<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      webpack的五個核心概念(入口、輸出、loader、插件、模式)

      1、入口(Entry)

      entry 對象是用于 webpack 查找啟動并構(gòu)建 bundle。entry 是應(yīng)用程序的起點入口,從這個起點開始,應(yīng)用程序啟動執(zhí)行。如果傳遞一個數(shù)組,那么數(shù)組的每一項都會執(zhí)行。入口起點(entry point) 指示 webpack 應(yīng)該使用哪個模塊,來作為構(gòu)建其內(nèi)部依賴圖(dependency graph) 的開始。進(jìn)入入口起點后,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的。

      簡單規(guī)則:每個 HTML 頁面都有一個入口起點。單頁應(yīng)用(SPA):一個入口起點,多頁應(yīng)用(MPA):多個入口起點。

      默認(rèn)值是 ./src/index.js,但你可以通過在 webpack configuration 中配置 entry 屬性,來指定一個(或多個)不同的入口起點。例如:

      //單入口--字符串
      module.exports = {
        entry: './path/to/my/entry/file.js',
      };
      
      //多入口--數(shù)組
      module.exports = {
        entry: ['./src/index.js', './src/add.js']
      };
      
      //多入口--對象
      module.exports = {
        entry: {
          home: './home.js',
          about: './about.js',
          contact: './contact.js'
        }
      };

      entry的值類型:

      • 字符串:單入口,打包形成一個chunk,最終只會輸出一個bundle文件,chunk 的名稱默認(rèn)是 main
      • 數(shù)組:多入口,所有的入口文件最終也只會形成一個chunk,最終輸出一個 bundle 文件,chunk 的名稱默認(rèn)為 main。一般只用在 HMR 功能中讓html熱更新生效
      • 對象:多入口,有多少個 key 就會形成多少個chunk,也就輸出多少個 bundle 文件,每個鍵(key)會是 chunk 的名稱。在對象類型中,每個key的值還可以是一個數(shù)組,不僅僅是一個字符串。

       

      2、輸出(output)

      output 指示 webpack 如何去輸出、以及在哪里輸出你的bundle、asset 和其他你所打包或使用 webpack 載入的任何內(nèi)容。輸出的 bundle 的默認(rèn)值是 ./dist/main.js,其他生成文件默認(rèn)放置在 ./dist 文件夾中。

      你可以通過在配置中指定一個 output 字段,來配置這些處理過程:

      //webpack.config.js
      const path = require('path');
      
      module.exports = {
        entry: './path/to/my/entry/file.js',
        output: {
          path: path.resolve(__dirname, 'dist'),
          filename: 'my-first-webpack.bundle.js',
        },
      };

      我們可以通過 output.filename 和 output.path 屬性,來告訴 webpack bundle 的名稱,以及 bundle 生成到哪里。

       

      2.1、output.filename(文件名和目錄)

      此選項決定了每個輸出 bundle 的目錄和名稱。這些 bundle 將寫入到 output.path 選項指定的目錄下。

      對于單個入口起點,filename 會是一個靜態(tài)名稱。然而,當(dāng)通過多個入口起點(entry point)、代碼拆分(code splitting)或各種插件(plugin)創(chuàng)建多個 bundle,應(yīng)該使用其他方法來讓每個 bundle 都有一個唯一的名稱。

      //單入口時:
      module.exports = {
        //...
        output: {
          filename: 'js/bundle.js'
        }
      };
      
      //多入口--使用入口名稱:
      module.exports = {
        //...
        output: {
          filename: '[name].bundle.js'
        }
      };
      
      //多入口--使用每次構(gòu)建過程中,唯一的 hash 生成
      module.exports = {
        //...
        output: {
          filename: '[name].[hash].bundle.js'
        }
      };
      
      ...

       

      2.2、output.path(文件目錄)

      output.path 指定所有輸出文件的目錄,即將來所有資源輸出的公共目錄。path 必須是絕對路徑。

      module.exports = {
        //...
        output: {
          path: path.resolve(__dirname, 'dist/assets')
        }
      };

       

      2.3、output.publicPath(引用資源的路徑前綴)

      publicPath 指定的是 html 文件中的所有資源引入的公共路徑前綴。它并不會對生成文件的路徑造成影響,而是在 html 文件引入各種資源時,將 publicPath 作為前綴加到引入資源的路徑前面。

      實例:

      在 vue-cli 生成的 webpack 配置中,生產(chǎn)環(huán)境下 publicPath 的值默認(rèn)是 '/',即當(dāng)前目錄的根目錄。

       

      打包過后,我們打開 html 文件,可以看到 html 文件中引入的資源路徑為:

       可以看到,都在路徑前面加了 / 符號。當(dāng)我們打開瀏覽器訪問生成的 html 文件時,會發(fā)現(xiàn)報錯,資源訪問不到,報404,此時資源的訪問類似如下:

      在服務(wù)器上可能會是如下,但訪問一樣可能會有問題。

      我們可以將 publicPath 修改為相對路徑,或者直接把它注釋掉也行。 

       

      2.3.1、path和publicPath的區(qū)別

      • path 指定的是打包后文件在硬盤中的存儲位置,是webpack所有文件的輸出的路徑,必須是絕對路徑。比如:輸出的js、圖片,HtmlWebpackPlugin生成的html文件等,都會存放在以path為基礎(chǔ)的目錄下。
      • publicPath 并不會對生成文件的路徑造成影響,主要是對你的頁面里面引入的資源的路徑做對應(yīng)的補全。

       

      2.4、output.chunkFilename(非入口chunk的名稱)

      output.chunkFilename 決定了非入口(non-entry) chunk 文件的名稱。也就是除了入口文件生成的chunk外,其他文件生成的chunk文件命名。

      module.exports = {
        //...
        output: {
          chunkFilename: 'js/[name]_chunk.js'   //非入口chunk的名稱
        }
      };

       

      3、loader

      webpack 本身只能打包 JavaScript 和 JSON 文件(webpack3+和webpack2+內(nèi)置可處理JSON文件,但webpack1+并不支持,需要引入json-loader),這是 webpack 開箱可用的自帶能力。webpack 本身不支持打包其他類型文件,比如 css、vue 等,但我們可以通過各種 loader 來讓 webpack 去處理這些類型的文件。loader 可以將文件從不同的語言(如 TypeScript)轉(zhuǎn)換為 JavaScript 或?qū)?nèi)聯(lián)圖像轉(zhuǎn)換為 data URL,loader 甚至允許你直接在 JavaScript 模塊中 import CSS文件!

      通過使用不同的loaderwebpack有能力調(diào)用外部的腳本或工具,實現(xiàn)對不同格式的文件的處理,比如說分析轉(zhuǎn)換 scss為css,或者把下一代的JS文件(ES6,ES7)轉(zhuǎn)換為現(xiàn)代瀏覽器兼容的JS文件。對React的開發(fā)而言,合適的Loaders可以把React的中用到的JSX文件轉(zhuǎn)換為JS文件。

      在 webpack 的配置中,loader 有兩個屬性:

      1. test 屬性,識別出哪些文件會被轉(zhuǎn)換。
      2. use 屬性,定義出在進(jìn)行轉(zhuǎn)換時,應(yīng)該使用哪個 loader。
      3. include/exclude(可選):手動添加必須處理的文件(文件夾)或屏蔽不需要處理的文件(文件夾)
      4. query(可選):為loaders提供額外的設(shè)置選項
      //示例:webpack.config.js
      const path = require('path');
      
      module.exports = {
        output: {
          filename: 'my-first-webpack.bundle.js',
        },
        module: {
          rules: [
              { test: /\.txt$/, loader: 'raw-loader' },
              { test: /\.css$/, use: ['style-loader', 'css-loader'] }   //使用多個loader的話應(yīng)該用 use
          ], 
        },
      };

      以上配置中,對一個單獨的 module 對象定義了 rules 屬性,里面包含兩個必須屬性:test 和 use。這相當(dāng)于告訴 webpack 編譯器在碰到 require()/import 語句中被解析為 '.txt' 的路徑時,在對它打包之前,先使用raw-loader 轉(zhuǎn)換一下。

      使用多個loader的話應(yīng)該用 use,use 數(shù)組中的 loader 執(zhí)行順序:從右到左,依次執(zhí)行。比如上面的 css 文件,首先 css-loader 會將 css 文件編譯成 JS 加載到 JS文件中,然后再由 style-loader 創(chuàng)建 style 標(biāo)簽,將 JS 中的樣式資源插入到 head 標(biāo)簽中。

       

      3.1、CSS-loader

      webpack提供兩個工具處理樣式表,css-loader 和 style-loader,二者處理的任務(wù)不同。css-loader使你能夠使用類似import的方法來引入 css 文件,style-loader將所有的計算后的樣式加入頁面中,二者組合在一起使你能夠把樣式表嵌入webpack打包后的JS文件中,由此就可以在JS文件中引入css文件了。

      //安裝
      npm install --save-dev style-loader css-loader  //css-loader版本太高編譯可能會出錯,建議降低版本比如 css-loader@1.0.1 可用
      //使用
      module.exports = {
         ...
          module: {
              rules: [
                  {
                      test: /(\.jsx|\.js)$/,
                      use: {
                          loader: "babel-loader"
                      },
                      exclude: /node_modules/
                  },
                  {
                      test: /\.css$/,  //對同一個文件引入多個loader的方法。loader的作用順序是后面的loader先開始作用
                      use: [
                          {
                              loader: "style-loader"
                          }, {
                              loader: "css-loader"
                          }
                      ]
                  }
              ]
          }
      };

       

      假設(shè)有一個 main.css 文件:

      body {
        backgroud: green;
      }

      為了讓webpack能找到”main.css“文件,我們把它導(dǎo)入”main.js “中,如下:

      //main.js
      import React from 'react';
      import {render} from 'react-dom';
      import Greeter from './Greeter';
      import './main.css';//使用require導(dǎo)入css文件
      
      render(<Greeter />, document.getElementById('root'));

      通常情況下,css會和js打包到同一個文件中,并不會打包為一個單獨的css文件。不過通過合適的配置webpack也可以把css打包為單獨的文件的。

       

      4、插件(plugin)

      loader 用于轉(zhuǎn)換某些類型的模塊,而插件則可以用于執(zhí)行范圍更廣的任務(wù),包括:打包優(yōu)化、壓縮、資源管理、注入環(huán)境變量等。插件目的在于解決 loader 無法實現(xiàn)的其他事。

      要使用某個插件,我們需要通過npm安裝它,然后在 plugins 屬性下添加該插件的一個實例。由于插件可以攜帶參數(shù)/選項,你必須在 webpack 配置中,向 plugins 屬性傳入 new 實例。多數(shù)插件可以通過選項自定義,你也可以在一個配置文件中因為不同目的而多次使用同一個插件。

      //webpack.config.js
      const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通過 npm 安裝
      const webpack = require('webpack'); // 用于訪問內(nèi)置插件
      
      module.exports = {
        module: {
          rules: [{ test: /\.txt$/, use: 'raw-loader' }],
        },
        plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
      };

      在上面的示例中,html-webpack-plugin 為應(yīng)用程序生成一個 HTML 文件,并自動注入所有生成的 bundle。

       

      4.1、BannerPlugin插件(添加版權(quán)說明)

      下面我們添加了一個給打包后代碼添加版權(quán)聲明的插件。該插件是webpack中的內(nèi)置插件不用安裝。

      const webpack = require('webpack');
      
      module.exports = {
      ...
          module: {
              rules: [
                  {
                      test: /(\.jsx|\.js)$/,
                      use: {
                          loader: "babel-loader"
                      },
                      exclude: /node_modules/
                  },
                  {
                      test: /\.css$/,
                      use: [
                          {
                              loader: "style-loader"
                          }, {
                              loader: "css-loader",
                              options: {
                                  modules: true
                              }
                          }, {
                              loader: "postcss-loader"
                          }
                      ]
                  }
              ]
          },
          plugins: [
              new webpack.BannerPlugin('wenxuehai版權(quán)所有,翻版必究')
          ],
      };

       

      4.2、Hot Module Replacement 插件(熱加載)

      Hot Module Replacement(HMR)是webpack里很有用的一個插件,它允許你在修改組件代碼后,自動刷新實時預(yù)覽修改后的效果。熱加載和webpack-dev-server不同,熱替換在應(yīng)用運行時,無需刷新頁面,便能查看代碼更新后的效果 ,就跟直接在瀏覽器上修改dom樣式一樣,而webpack-dev-server是要刷新頁面的。

      (1)在webpack配置文件中添加HMR插件;

      (2)在Webpack Dev Server中添加“hot”參數(shù);

       

      4.2.1、react實現(xiàn)熱加載

      React模塊可以使用Babel實現(xiàn)功能熱加載。Babel有一個叫做react-transform-hrm的插件,可以在不對React模塊進(jìn)行額外的配置的前提下讓HMR正常工作;

      安裝react-transform-hmr

      npm install --save-dev babel-plugin-react-transform react-transform-hmr
      const webpack = require('webpack');
      
      module.exports = {
          entry: __dirname + "/app/main.js",//已多次提及的唯一入口文件
          output: {
              path: __dirname + "/public",
              filename: "bundle.js"
          },
          devtool: 'eval-source-map',
          devServer: {
              contentBase: "./public",//本地服務(wù)器所加載的頁面所在的目錄
              historyApiFallback: true,//不跳轉(zhuǎn)
              inline: true,
              hot: true
          },
          module: {
              rules: [
                  {
                      test: /(\.jsx|\.js)$/,
                      use: {
                          loader: "babel-loader"
                      },
                      exclude: /node_modules/
                  },
                  {
                      test: /\.css$/,
                      use: [
                          {
                              loader: "style-loader"
                          }, {
                              loader: "css-loader",
                              options: {
                                  modules: true
                              }
                          }, {
                              loader: "postcss-loader"
                          }
                      ]
                  }
              ]
          },
          plugins: [
              new webpack.BannerPlugin('版權(quán)所有,翻版必究'),
           new webpack.HotModuleReplacementPlugin()  //熱加載插件
          ],
      };

      配置Babel

      // .babelrc
      {
        "presets": ["react", "env"],
        "env": {
          "development": {
          "plugins": [["react-transform", {
             "transforms": [{
               "transform": "react-transform-hmr",         
               "imports": ["react"],       
               "locals": ["module"]
             }]
           }]]
          }
        }
      }
      //Greeter,js
      import React, {
        Component
      } from 'react'
      import styles from './main.css'
      
      class Greeter extends Component {
        render() {
          return ( 
              < div>
                <h1>
                  aaaf
                </h1>
              </div>
          );
        }
      }
      export default Greeter
      //main.js
      import React from 'react';
      import {
        render
      } from 'react-dom';
      import Greeter from './greeter.js';
      
      render( < Greeter / > , document.getElementById('root'));

      現(xiàn)在如果我們就可以實現(xiàn)熱加載模塊了,每次保存就能在瀏覽器上直接看到更新內(nèi)容,瀏覽器不必刷新也不會自動刷新。

      (有時候沒有效果可能是版本問題)

       

      4.3、ExtractTextWebpackPlugin插件(抽離css)

      在默認(rèn)情況下,webpack 不會將 css 樣式作為一個獨立文件,而是會將 css 也打包到 js 文件中,打包生成的 js 文件在渲染時會通過 js 語法來將樣式通過 style 標(biāo)簽的形式來插入到頁面中。但是這樣的話,打包出來的 bundle 文件可能會過大,此時我們可以通過 ExtractTextWebpackPlugin 插件來將 css  樣式獨立成 css 文件。

      ExtractTextWebpackPlugin 插件會將入口 chunk 中引用到的 *.css(包括引入的css文件和vue文件中style所寫的樣式),移動到一個獨立分離的 CSS 文件中。ExtractTextPlugin 對每個入口 chunk 都會生成一個對應(yīng)的 css文件,也就是說一個入口對應(yīng)著一個 css 文件,多個入口的話就會分別生成多個對應(yīng)的 css 文件。

      通過 ExtractTextWebpackPlugin 插件,你的樣式將不再內(nèi)嵌到 JS bundle 中,而是會放到一個單獨的 CSS 文件(即 styles.css)當(dāng)中。 如果你的樣式文件大小較大,這會做更快提前加載,因為 CSS bundle 會跟 JS bundle 并行加載。

      const ExtractTextPlugin = require("extract-text-webpack-plugin");
      
      module.exports = {
        module: {
          rules: [
            {
              test: /\.css$/,
              use: ExtractTextPlugin.extract({
                fallback: "style-loader",
                use: "css-loader"
              })
            }
          ]
        },
        plugins: [
          new ExtractTextPlugin({
            filename: utils.assetsPath('css/[name].[contenthash].css'),   //ExtractTextPlugin 對每個入口 chunk 都生成一個對應(yīng)的文件,所以當(dāng)你配置多個入口 chunk 的時候,必須使用 [name], [id] 或 [contenthash]
            // allChunks: true,   //當(dāng)使用 `CommonsChunkPlugin` 并且在公共 chunk 中有提取的 chunk(來自`ExtractTextPlugin.extract`)時,`allChunks` **必須設(shè)置為 `true`。
          }),
        ]
      }

       

      4.3.1、allChunks選項(是否也將異步加載的樣式一起提取出來)

      ExtractTextWebpackPlugin 插件的 allChunks 選項的默認(rèn)值為 false。

      allChunks 選項的意思是是否需要將異步加載的樣式一起提取出來。因為在默認(rèn)情況下,就算使用了 ExtractTextWebpackPlugin 插件,如果該樣式或者樣式文件是異步加載的話,那么這些樣式是不會被提取到獨立的 css 文件中的,而是仍然會打包到 js 文件中。

      所以allChunks:false為默認(rèn)值,默認(rèn)是從 entry 的入口提取代碼,但是不會提取異步加載的代碼;allChunks:true則是提取所有模塊的代碼(包括異步加載的模塊)到一個文件里面。如果使用了異步加載樣式,但是 allChunks 又設(shè)為了 false,那么我們就需要設(shè)置 ExtractTextPlugin.extract 的 fallback, fallback是在異步代碼加載的 css 代碼沒有被提取的情況下, 以style-loader的情況去加載異步組件的樣式。

      可參考:https://github.com/sevenCon/blog-github/blob/master/articles/webpack%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0(2)-ExtractTextWebpackPlugin%E7%9A%84%E4%BD%BF%E7%94%A8.md

      https://blog.csdn.net/weixin_41134409/article/details/88416356

       

      5、模式(mode)

      通過選擇 developmentproduction 或 none 之中的一個,來設(shè)置 mode 參數(shù),你可以啟用 webpack 內(nèi)置在相應(yīng)環(huán)境下的優(yōu)化。其默認(rèn)值為 production

      module.exports = {
        mode: 'production',
      };

      在配置文件中直接配置 mode 選項將告知 webpack 使用相應(yīng)模式的內(nèi)置優(yōu)化,mode選項有development、production、none。

      development : 開發(fā)模式,打包的代碼不會被壓縮,開啟代碼調(diào)試,
      production : 生產(chǎn)模式,則正好反之。

      將 mode 設(shè)為development或者production,webpack會自動同時也設(shè)置 process.env.NODE_ENV 的值,我們可以在任何文件夾中直接拿到該值。但如果只設(shè)置 NODE_ENV,則不會自動設(shè)置 mode。(在node中,全局變量 process 表示的是當(dāng)前的node進(jìn)程。process.env 屬性包含著用戶環(huán)境的信息。process.env 本身并不存在NODE_ENV這個屬性,我們一般會自己去定義 NODE_ENV 屬性,用它來判斷是生產(chǎn)環(huán)境還是開發(fā)環(huán)境)

      (請注意:mode選項是webpack4新增的,在4之前都是用DefinePlugin插件設(shè)置,webpack4把DefinePlugin刪除了)

       

      5.1、vue-cli項目mode配置詳解

      在 webpack 中,一般都會在配置文件中配置 NODE_ENV 的值。在使用 vue-cli 默認(rèn)生成的 vue 項目中,NODE_ENV 配置情況如下:

      //webpack.dev.conf.js 文件下,引入了 dev.env.js 文件
      new webpack.DefinePlugin({
            'process.env': require('../config/dev.env')
      }), 
      //dev.env.js 文件中
      module.exports = merge(prodEnv, {
        NODE_ENV: '"development"'
      })
      //webpack.prod.conf.js 文件下,引入了 prod.env.js 文件
      const env = require('../config/prod.env')
      new webpack.DefinePlugin({
            'process.env': env
      }),
      //prod.env.js 文件中
      module.exports = {
        NODE_ENV: '"production"'
      }

      從上面可以知道,在開發(fā)環(huán)境下,配置文件將 NODE_ENV 配置成了 'development';在生產(chǎn)環(huán)境下,配置文件將 NODE_ENV 配置成了 'production'。

      我們在運行項目時,會執(zhí)行 npm run dev 或者 npm run build,這兩個命令時使用了開發(fā)環(huán)境或者生產(chǎn)環(huán)境的配置文件來生成運行項目,由此也對應(yīng)著配置了對應(yīng)的 NODE_ENV 的值,我們也就能夠在項目的任一文件中(配置文件不一定,因為要看配置了 NODE_ENV 的值的配置文件有沒有生效了才行)獲取到對應(yīng)的 NODE_ENV 的值。

       

      5.2、process.env.NODE_ENV配置

      process 是 node 的全局變量,并且 process 有 env 這個屬性,但是沒有 NODE_ENV 這個屬性。NODE_ENV 變量并不是 process.env 直接就有的,而是通過設(shè)置得到的,但是 NODE_ENV 變量通常約定用于定義環(huán)境類型。這個變量的作用是:我們可以通過判斷這個變量區(qū)分開發(fā)環(huán)境或生產(chǎn)環(huán)境。

      (1)可以通過webpack的內(nèi)置插件 DefinePlugin 來設(shè)置全局變量值:

      new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production')
      }),

       設(shè)置完后在執(zhí)行腳本上可以取到該值,比如:

      // main.js
      console.log(process.env.NODE_ENV);    //production

      但是在webpack的配置文件 webpack.config.js 中取不到該值。

      (2)通過 cross-env 包設(shè)置

      先下載 cross-env 包:

      cnpm i cross-env -D

      設(shè)置 package.json 文件:

      "build": "cross-env NODE_ENV=test webpack --config webpack.config.js"

      此時在配置文件中可以取到該值(process.env.NODE_ENV),但是在可執(zhí)行腳本中取不到,需要配合DefinePlugin 插件使用

       

      posted @ 2021-03-17 17:10  wenxuehai  閱讀(1279)  評論(0)    收藏  舉報
      //右下角添加目錄
      主站蜘蛛池模板: 97精品伊人久久久大香线蕉| 99久久精品久久久久久婷婷| 国产午夜精品一区二区三区漫画| 精品黄色av一区二区三区| 亚洲视频免费一区二区三区| 无极县| 亚洲人成电影网站 久久影视 | av在线播放无码线| 91国产自拍一区二区三区| 另类 专区 欧美 制服| 国产精品午夜福利精品| 亚洲精品www久久久久久| 精品国精品自拍自在线| 久久婷婷五月综合色欧美| 91老熟女老人国产老太| 日韩丝袜欧美人妻制服| 沽源县| 亚洲最大激情中文字幕| 亚洲日韩性欧美中文字幕| 少妇人妻互换不带套| 精品亚洲欧美高清不卡高清 | 国产精品人妻中文字幕| 精品国产一区二区三区av色诱| 丰满少妇被猛烈进入av久久| 无套内射视频囯产| 蜜桃臀av一区二区三区| 无卡无码无免费毛片| 国产一区日韩二区三区| 人妻无码久久久久久久久久久 | 天天爽天天摸天天碰| 国产精品久久久久久无毒不卡 | 久久91精品牛牛| 日韩精品一卡二卡三卡在线| 国产亚洲av夜间福利香蕉149| 色综合视频一区二区三区| 国产精品久久中文字幕网| 欧美三级不卡在线观线看高清| 欧洲中文字幕一区二区| 久久精品国产亚洲av久| 亚洲成av人片色午夜乱码| 精品无码国产污污污免费|