国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

webpack配置

Doyle / 1192人閱讀

摘要:配置無入口的在輸出時的文件名稱。配置發(fā)布到線上資源的前綴,為類型。則是用于配置這個異步插入的標(biāo)簽的值。配置以何種方式導(dǎo)出庫。是字符串的枚舉類型,支持以下配置。在為時,配置將沒有意義。是可選配置項,類型需要是其中一個。

webpack配置
查看所有文檔頁面:全棧開發(fā),獲取更多信息。

原文鏈接:第2章 配置,原文廣告模態(tài)框遮擋,閱讀體驗不好,所以整理成本文,方便查找。

配置 Webpack 的方式有兩種:

通過一個 JavaScript 文件描述配置,例如使用 webpack.config.js 文件里的配置;

執(zhí)行 Webpack 可執(zhí)行文件時通過命令行參數(shù)傳入,例如 webpack --devtool source-map

這兩種方式可以相互搭配,例如執(zhí)行 Webpack 時通過命令 webpack --config webpack-dev.config.js 指定配置文件,再去 webpack-dev.config.js 文件里描述部分配置。

按照配置所影響的功能來劃分,可分為:

Entry 配置模塊的入口;

Output 配置如何輸出最終想要的代碼;

Module 配置處理模塊的規(guī)則;

Resolve 配置尋找模塊的規(guī)則;

Plugins 配置擴展插件;

DevServer 配置 DevServer;

其它配置項 其它零散的配置項;

整體配置結(jié)構(gòu) 整體地描述各配置項的結(jié)構(gòu);

多種配置類型 配置文件不止可以返回一個 Object,還有其他返回形式;

配置總結(jié) 尋找配置 Webpack 的規(guī)律,減少思維負(fù)擔(dān)。

Entry

Webpack 在尋找相對路徑的文件時會以 context 為根目錄,context 默認(rèn)為執(zhí)行啟動 Webpack 時所在的當(dāng)前工作目錄。

如果想改變 context 的默認(rèn)配置,可以在配置文件里設(shè)置:

module.exports = {
  context: path.resolve(__dirname, "app")
}

注意, context 必須是一個絕對路徑的字符串。 除此之外,還可以通過在啟動 Webpack 時帶上參數(shù) webpack --context 來設(shè)置 context。

Chunk 名稱

Webpack 會為每個生成的 Chunk 取一個名稱,Chunk 的名稱和 Entry 的配置有關(guān):

如果 entry 是一個 stringarray,就只會生成一個 Chunk,這時 Chunk 的名稱是 main

如果 entry 是一個 object,就可能會出現(xiàn)多個 Chunk,這時 Chunk 的名稱是 object 鍵值對里鍵的名稱。

配置動態(tài) Entry

假如項目里有多個頁面需要為每個頁面的入口配置一個 Entry ,但這些頁面的數(shù)量可能會不斷增長,則這時 Entry 的配置會受到到其他因素的影響導(dǎo)致不能寫成靜態(tài)的值。其解決方法是把 Entry 設(shè)置成一個函數(shù)去動態(tài)返回上面所說的配置,代碼如下:

// 同步函數(shù)
entry: () => {
  return {
    a:"./pages/a",
    b:"./pages/b",
  }
};
// 異步函數(shù)
entry: () => {
  return new Promise((resolve)=>{
    resolve({
       a:"./pages/a",
       b:"./pages/b",
    });
  });
};
Output

output 配置如何輸出最終想要的代碼。output 是一個 object,里面包含一系列配置項:

filename

output.filename 配置輸出文件的名稱,為 string 類型。 如果只有一個輸出文件,則可以把它寫成靜態(tài)不變的:

filename: "bundle.js"

但是在有多個 Chunk 要輸出時,就需要借助模版和變量了。前面說到 Webpack 會為每個 Chunk取一個名稱,可以根據(jù) Chunk 的名稱來區(qū)分輸出的文件名:

filename: "[name].js"

代碼里的 [name] 代表用內(nèi)置的 name 變量去替換[name],這時你可以把它看作一個字符串模塊函數(shù), 每個要輸出的 Chunk 都會通過這個函數(shù)去拼接出輸出的文件名稱。

變量名 含義
id Chunk 的唯一標(biāo)識,從0開始
name Chunk 的名稱
hash Chunk 的唯一標(biāo)識的 Hash 值
chunkhash Chunk 內(nèi)容的 Hash 值

其中 hashchunkhash 的長度是可指定的,[hash:8] 代表取8位 Hash 值,默認(rèn)是20位。

注意 ExtractTextWebpackPlugin 插件是使用 contenthash 來代表哈希值而不是 chunkhash, 原因在于 ExtractTextWebpackPlugin 提取出來的內(nèi)容是代碼內(nèi)容本身而不是由一組模塊組成的 Chunk。
chunkFilename

output.chunkFilename 配置無入口的 Chunk 在輸出時的文件名稱。 chunkFilename 和上面的 filename 非常類似,但 chunkFilename 只用于指定在運行過程中生成的 Chunk 在輸出時的文件名稱。 常見的會在運行時生成 Chunk 場景有在使用 CommonChunkPlugin、使用 import("path/to/module") 動態(tài)加載等時。 chunkFilename 支持和 filename 一致的內(nèi)置變量。

path

output.path 配置輸出文件存放在本地的目錄,必須是 string 類型的絕對路徑。通常通過 Node.js 的 path 模塊去獲取絕對路徑:

path: path.resolve(__dirname, "dist_[hash]")
publicPath

在復(fù)雜的項目里可能會有一些構(gòu)建出的資源需要異步加載,加載這些異步資源需要對應(yīng)的 URL 地址。

output.publicPath 配置發(fā)布到線上資源的 URL 前綴,為string 類型。 默認(rèn)值是空字符串 "",即使用相對路徑。

把構(gòu)建出的資源文件上傳到 CDN 服務(wù)上,以利于加快頁面的打開速度。配置代碼如下:

filename:"[name]_[chunkhash:8].js"
publicPath: "https://cdn.example.com/assets/"

這時發(fā)布到線上的 HTML 在引入 JavaScript 文件時就需要:


使用該配置項時要小心,稍有不慎將導(dǎo)致資源加載404錯誤。

output.pathoutput.publicPath 都支持字符串模版,內(nèi)置變量只有一個:hash 代表一次編譯操作的 Hash 值。

crossOriginLoading

Webpack 輸出的部分代碼塊可能需要異步加載,而異步加載是通過 JSONP 方式實現(xiàn)的。 JSONP 的原理是動態(tài)地向 HTML 中插入一個 標(biāo)簽去加載異步資源。

output.crossOriginLoading 則是用于配置這個異步插入的標(biāo)簽的 crossorigin 值。

script 標(biāo)簽的 crossorigin 屬性可以取以下值:

false(默認(rèn)) 在加載此腳本資源時不會帶上用戶的 Cookies;

use-credentials 在加載此腳本資源時會帶上用戶的 Cookies。

通常用設(shè)置 crossorigin 來獲取異步加載的腳本執(zhí)行時的詳細(xì)錯誤信息。

libraryTarget 和 library

當(dāng)用 Webpack 去構(gòu)建一個可以被其他模塊導(dǎo)入使用的庫時需要用到它們。

output.libraryTarget 配置以何種方式導(dǎo)出庫。

output.library 配置導(dǎo)出庫的名稱。

假如配置了 output.library="LibraryName",則輸出和使用的代碼如下:

// Webpack 輸出的代碼
var LibraryName = lib_code;

// 使用庫的方法
LibraryName.doSomething();

假如 output.library 為空,則將直接輸出:lib_code

其中 lib_code 代指導(dǎo)出庫的代碼內(nèi)容,是有返回值的一個自執(zhí)行函數(shù)。

它們通常搭配在一起使用。

output.libraryTarget 是字符串的枚舉類型,支持以下配置。

var (默認(rèn))

編寫的庫將通過 var 被賦值給通過 library 指定名稱的變量。

commonjs

編寫的庫將通過 CommonJS2 規(guī)范導(dǎo)出,輸出和使用的代碼如下:

// Webpack 輸出的代碼
module.exports = lib_code;

// 使用庫的方法
require("library-name-in-npm").doSomething();
CommonJS2 和 CommonJS 規(guī)范很相似,差別在于 CommonJS 只能用 exports 導(dǎo)出,而 CommonJS2 在 CommonJS 的基礎(chǔ)上增加了 module.exports 的導(dǎo)出方式。

output.libraryTarget 為 commonjs2 時,配置 output.library 將沒有意義。

this

編寫的庫將通過 this 被賦值給通過 library 指定的名稱,輸出和使用的代碼如下:

// Webpack 輸出的代碼
this["LibraryName"] = lib_code;

// 使用庫的方法
this.LibraryName.doSomething();

window

編寫的庫將通過 window 被賦值給通過 library 指定的名稱,即把庫掛載到 window 上,輸出和使用的代碼如下:

// Webpack 輸出的代碼
window["LibraryName"] = lib_code;

// 使用庫的方法
window.LibraryName.doSomething();
global

編寫的庫將通過 global 被賦值給通過 library 指定的名稱,即把庫掛載到 global 上,輸出和使用的代碼如下:

// Webpack 輸出的代碼
global["LibraryName"] = lib_code;

// 使用庫的方法
global.LibraryName.doSomething();
libraryExport

output.libraryExport 配置要導(dǎo)出的模塊中哪些子模塊需要被導(dǎo)出。 它只有在 output.libraryTarget 被設(shè)置成 commonjs 或者 commonjs2 時使用才有意義。

假如要導(dǎo)出的模塊源代碼是:

export const a=1;
export default b=2;

現(xiàn)在想讓構(gòu)建輸出的代碼只導(dǎo)出其中的 a,可以把 output.libraryExport 設(shè)置成 a,那么構(gòu)建輸出的代碼和使用方法將變成如下:

// Webpack 輸出的代碼
module.exports = lib_code["a"];

// 使用庫的方法
require("library-name-in-npm")===1;
Module 配置 Loader

rules 配置模塊的讀取和解析規(guī)則,通常用來配置 Loader。其類型是一個數(shù)組,數(shù)組里每一項都描述了如何去處理部分文件。 配置一項 rules 時大致通過以下方式:

條件匹配:通過 testincludeexclude 三個配置項來命中 Loader 要應(yīng)用規(guī)則的文件。

應(yīng)用規(guī)則:對選中后的文件通過 use 配置項來應(yīng)用 Loader,可以只應(yīng)用一個 Loader 或者按照從后往前的順序應(yīng)用一組 Loader,同時還可以分別給 Loader 傳入?yún)?shù)。

重置順序:一組 Loader 的執(zhí)行順序默認(rèn)是從右到左執(zhí)行,通過 enforce 選項可以讓其中一個 Loader 的執(zhí)行順序放到最前或者最后。

module: {
  rules: [
    {
      // 命中 JavaScript 文件
      test: /.js$/,
      // 用 babel-loader 轉(zhuǎn)換 JavaScript 文件
      // ?cacheDirectory 表示傳給 babel-loader 的參數(shù),用于緩存 babel 編譯結(jié)果加快重新編譯速度
      use: ["babel-loader?cacheDirectory"],
      // 只命中src目錄里的js文件,加快 Webpack 搜索速度
      include: path.resolve(__dirname, "src")
    },
    {
      // 命中 SCSS 文件
      test: /.scss$/,
      // 使用一組 Loader 去處理 SCSS 文件。
      // 處理順序為從后到前,即先交給 sass-loader 處理,再把結(jié)果交給 css-loader 最后再給 style-loader。
      use: ["style-loader", "css-loader", "sass-loader"],
      // 排除 node_modules 目錄下的文件
      exclude: path.resolve(__dirname, "node_modules"),
    },
    {
      // 對非文本文件采用 file-loader 加載
      test: /.(gif|png|jpe?g|eot|woff|ttf|svg|pdf)$/,
      use: ["file-loader"],
    },
  ]
}

在 Loader 需要傳入很多參數(shù)時,你還可以通過一個 Object 來描述,例如在上面的 babel-loader 配置中有如下代碼:

use: [
  {
    loader:"babel-loader",
    options:{
      cacheDirectory:true,
    },
    // enforce:"post" 的含義是把該 Loader 的執(zhí)行順序放到最后
    // enforce 的值還可以是 pre,代表把 Loader 的執(zhí)行順序放到最前面
    enforce:"post"
  },
  // 省略其它 Loader
]

上面的例子中 test include exclude 這三個命中文件的配置項只傳入了一個字符串或正則,其實它們還都支持?jǐn)?shù)組類型,使用如下:

{
  test:[
    /.jsx?$/,
    /.tsx?$/
  ],
  include:[
    path.resolve(__dirname, "src"),
    path.resolve(__dirname, "tests"),
  ],
  exclude:[
    path.resolve(__dirname, "node_modules"),
    path.resolve(__dirname, "bower_modules"),
  ]
}

數(shù)組里的每項之間是的關(guān)系,即文件路徑符合數(shù)組中的任何一個條件就會被命中。

noParse

noParse 配置項可以讓 Webpack 忽略對部分沒采用模塊化的文件的遞歸解析和處理,這樣做的好處是能提高構(gòu)建性能。 原因是一些庫例如 jQuery 、ChartJS 它們龐大又沒有采用模塊化標(biāo)準(zhǔn),讓 Webpack 去解析這些文件耗時又沒有意義。

noParse 是可選配置項,類型需要是 RegExp[RegExp]function 其中一個。

例如想要忽略掉 jQuery 、ChartJS,可以使用如下代碼:

// 使用正則表達式
noParse: /jquery|chartjs/

// 使用函數(shù),從 Webpack 3.0.0 開始支持
noParse: (content)=> {
  // content 代表一個模塊的文件路徑
  // 返回 true or false
  return /jquery|chartjs/.test(content);
}
注意被忽略掉的文件里不應(yīng)該包含 importrequiredefine 等模塊化語句,不然會導(dǎo)致構(gòu)建出的代碼中包含無法在瀏覽器環(huán)境下執(zhí)行的模塊化語句。
parser

因為 Webpack 是以模塊化的 JavaScript 文件為入口,所以內(nèi)置了對模塊化 JavaScript 的解析功能,支持 AMDCommonJSSystemJSES6

parser 屬性可以更細(xì)粒度的配置哪些模塊語法要解析哪些不解析,和 noParse 配置項的區(qū)別在于 parser 可以精確到語法層面, 而 noParse 只能控制哪些文件不被解析。 parser 使用如下:

module: {
  rules: [
    {
      test: /.js$/,
      use: ["babel-loader"],
      parser: {
      amd: false, // 禁用 AMD
      commonjs: false, // 禁用 CommonJS
      system: false, // 禁用 SystemJS
      harmony: false, // 禁用 ES6 import/export
      requireInclude: false, // 禁用 require.include
      requireEnsure: false, // 禁用 require.ensure
      requireContext: false, // 禁用 require.context
      browserify: false, // 禁用 browserify
      requireJs: false, // 禁用 requirejs
      }
    },
  ]
}
Resolve

Webpack 在啟動后會從配置的入口模塊出發(fā)找出所有依賴的模塊,Resolve 配置 Webpack 如何尋找模塊所對應(yīng)的文件。 Webpack 內(nèi)置 JavaScript 模塊化語法解析功能,默認(rèn)會采用模塊化標(biāo)準(zhǔn)里約定好的規(guī)則去尋找,但你也可以根據(jù)自己的需要修改默認(rèn)的規(guī)則。

alias

resolve.alias 配置項通過別名來把原導(dǎo)入路徑映射成一個新的導(dǎo)入路徑。例如使用以下配置:

// Webpack alias 配置
resolve:{
  alias:{
    components: "./src/components/"
  }
}

當(dāng)你通過 import Button from "components/button" 導(dǎo)入時,實際上被 alias 等價替換成了 import Button from "./src/components/button"

以上 alias 配置的含義是把導(dǎo)入語句里的 components 關(guān)鍵字替換成 ./src/components/

這樣做可能會命中太多的導(dǎo)入語句,alias 還支持 $ 符號來縮小范圍到只命中以關(guān)鍵字結(jié)尾的導(dǎo)入語句:

resolve:{
  alias:{
    "react$": "/path/to/react.min.js"
  }
}

react$ 只會命中以 react 結(jié)尾的導(dǎo)入語句,即只會把 import "react" 關(guān)鍵字替換成 import "/path/to/react.min.js"

mainFields

有一些第三方模塊會針對不同環(huán)境提供幾分代碼。 例如分別提供采用 ES5 和 ES6 的2份代碼,這2份代碼的位置寫在 package.json 文件里,如下:

{
  "jsnext:main": "es/index.js",// 采用 ES6 語法的代碼入口文件
  "main": "lib/index.js" // 采用 ES5 語法的代碼入口文件
}

Webpack 會根據(jù) mainFields 的配置去決定優(yōu)先采用哪份代碼,mainFields 默認(rèn)如下:

mainFields: ["browser", "main"]

Webpack 會按照數(shù)組里的順序去 package.json 文件里尋找,只會使用找到的第一個。

假如你想優(yōu)先采用 ES6 的那份代碼,可以這樣配置:

mainFields: ["jsnext:main", "browser", "main"]
extensions

在導(dǎo)入語句沒帶文件后綴時,Webpack 會自動帶上后綴后去嘗試訪問文件是否存在。 resolve.extensions 用于配置在嘗試過程中用到的后綴列表,默認(rèn)是:

extensions: [".js", ".json"]
modules

resolve.modules 配置 Webpack 去哪些目錄下尋找第三方模塊,默認(rèn)是只會去 node_modules 目錄下尋找。

有時你的項目里會有一些模塊會大量被其它模塊依賴和導(dǎo)入,由于其它模塊的位置分布不定,針對不同的文件都要去計算被導(dǎo)入模塊文件的相對路徑, 這個路徑有時候會很長,就像這樣 import "../../../components/button" 這時你可以利用 modules 配置項優(yōu)化,假如那些被大量導(dǎo)入的模塊都在 ./src/components 目錄下,把 modules 配置成:

modules:["./src/components","node_modules"]

后,你可以簡單通過 import "button" 導(dǎo)入。

descriptionFiles

resolve.descriptionFiles 配置描述第三方模塊的文件名稱,也就是 package.json 文件。默認(rèn)如下:

descriptionFiles: ["package.json"]
enforceExtension

resolve.enforceExtension 如果配置為 true 所有導(dǎo)入語句都必須要帶文件后綴, 例如開啟前 import "./foo" 能正常工作,開啟后就必須寫成 import "./foo.js"

enforceModuleExtension

enforceModuleExtensionenforceExtension 作用類似,但 enforceModuleExtension 只對 node_modules 下的模塊生效。

enforceModuleExtension 通常搭配 enforceExtension 使用,在 enforceExtension:true 時,因為安裝的第三方模塊中大多數(shù)導(dǎo)入語句沒帶文件后綴, 所以這時通過配置 enforceModuleExtension:false 來兼容第三方模塊。

Plugins

Plugin 用于擴展 Webpack 功能,各種各樣的 Plugin 幾乎讓 Webpack 可以做任何構(gòu)建相關(guān)的事情。

配置 Plugin

Plugin 的配置很簡單,plugins 配置項接受一個數(shù)組,數(shù)組里每一項都是一個要使用的 Plugin 的實例,Plugin 需要的參數(shù)通過構(gòu)造函數(shù)傳入。

const CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");

module.exports = {
  plugins: [
    // 所有頁面都會用到的公共代碼提取到 common 代碼塊中
    new CommonsChunkPlugin({
      name: "common",
      chunks: ["a", "b"]
    }),
  ]
};

使用 Plugin 的難點在于掌握 Plugin 本身提供的配置項,而不是如何在 Webpack 中接入 Plugin。

DevServer

要配置 DevServer ,除了在配置文件里通過 devServer 傳入?yún)?shù)外,還可以通過命令行參數(shù)傳入。 注意只有在通過 DevServer 去啟動 Webpack 時配置文件里 devServer 才會生效,因為這些參數(shù)所對應(yīng)的功能都是 DevServer 提供的,Webpack 本身并不認(rèn)識 devServer 配置項。

hot

devServer.hot 配置是否啟用模塊熱替換功能。

DevServer 默認(rèn)的行為是在發(fā)現(xiàn)源代碼被更新后會通過自動刷新整個頁面來做到實時預(yù)覽,開啟模塊熱替換功能后將在不刷新整個頁面的情況下通過用新模塊替換老模塊來做到實時預(yù)覽。

inline

DevServer 的實時預(yù)覽功能依賴一個注入到頁面里的代理客戶端去接受來自 DevServer 的命令和負(fù)責(zé)刷新網(wǎng)頁的工作。

devServer.inline 用于配置是否自動注入這個代理客戶端到將運行在頁面里的 Chunk 里去,默認(rèn)是會自動注入。 DevServer 會根據(jù)你是否開啟 inline 來調(diào)整它的自動刷新策略:

如果開啟 inline,DevServer 會在構(gòu)建完變化后的代碼時通過代理客戶端控制網(wǎng)頁刷新。

如果關(guān)閉 inline,DevServer 將無法直接控制要開發(fā)的網(wǎng)頁。這時它會通過 iframe 的方式去運行要開發(fā)的網(wǎng)頁,當(dāng)構(gòu)建完變化后的代碼時通過刷新 iframe 來實現(xiàn)實時預(yù)覽。

如果你想使用 DevServer 去自動刷新網(wǎng)頁實現(xiàn)實時預(yù)覽,最方便的方法是直接開啟 inline

historyApiFallback

devServer.historyApiFallback 用于方便的開發(fā)使用了 HTML5 History API 的單頁應(yīng)用。

這類單頁應(yīng)用要求服務(wù)器在針對任何命中的路由時都返回一個對應(yīng)的 HTML 文件,例如在訪問 http://localhost/userhttp://localhost/home 時都返回 index.html 文件, 瀏覽器端的 JavaScript 代碼會從 URL 里解析出當(dāng)前頁面的狀態(tài),顯示出對應(yīng)的界面。

配置 historyApiFallback 最簡單的做法是:

historyApiFallback: true

這會導(dǎo)致任何請求都會返回 index.html 文件,這只能用于只有一個 HTML 文件的應(yīng)用。

如果你的應(yīng)用由多個單頁應(yīng)用組成,這就需要 DevServer 根據(jù)不同的請求來返回不同的 HTML 文件,配置如下:

historyApiFallback: {
  // 使用正則匹配命中路由
  rewrites: [
    // /user 開頭的都返回 user.html
    { from: /^/user/, to: "/user.html" },
    { from: /^/game/, to: "/game.html" },
    // 其它的都返回 index.html
    { from: /./, to: "/index.html" },
  ]
}
contentBase

devServer.contentBase 配置 DevServer HTTP 服務(wù)器的文件根目錄。 默認(rèn)情況下為當(dāng)前執(zhí)行目錄,通常是項目根目錄,所有一般情況下你不必設(shè)置它,除非你有額外的文件需要被 DevServer 服務(wù)。 例如你想把項目根目錄下的 public 目錄設(shè)置成 DevServer 服務(wù)器的文件根目錄,你可以這樣配置:

devServer:{
  contentBase: path.join(__dirname, "public")
}

這里需要指出可能會讓你疑惑的地方,DevServer 服務(wù)器通過 HTTP 服務(wù)暴露出的文件分為兩類:

暴露本地文件。

暴露 Webpack 構(gòu)建出的結(jié)果,由于構(gòu)建出的結(jié)果交給了 DevServer,所以你在使用了 DevServer 時在本地找不到構(gòu)建出的文件。

contentBase 只能用來配置暴露本地文件的規(guī)則,你可以通過 contentBase:false 來關(guān)閉暴露本地文件。

headers

devServer.headers 配置項可以在 HTTP 響應(yīng)中注入一些 HTTP 響應(yīng)頭,使用如下:

devServer:{
  headers: {
    "X-foo":"bar"
  }
}
host

devServer.host 配置項用于配置 DevServer 服務(wù)監(jiān)聽的地址。

例如你想要局域網(wǎng)中的其它設(shè)備訪問你本地的服務(wù),可以在啟動 DevServer 時帶上 --host 0.0.0.0host 的默認(rèn)值是 127.0.0.1 即只有本地可以訪問 DevServer 的 HTTP 服務(wù)。

port

devServer.port 配置項用于配置 DevServer 服務(wù)監(jiān)聽的端口,默認(rèn)使用 8080 端口。 如果 8080 端口已經(jīng)被其它程序占有就使用 8081,如果 8081 還是被占用就使用 8082,以此類推。

allowedHosts

devServer.allowedHosts 配置一個白名單列表,只有 HTTP 請求的 HOST 在列表里才正常返回,使用如下:

allowedHosts: [
  // 匹配單個域名
  "host.com",
  "sub.host.com",
  // host2.com 和所有的子域名 *.host2.com 都將匹配
  ".host2.com"
]
disableHostCheck

devServer.disableHostCheck 配置項用于配置是否關(guān)閉用于 DNS 重綁定的 HTTP 請求的 HOST 檢查。

DevServer 默認(rèn)只接受來自本地的請求,關(guān)閉后可以接受來自任何 HOST 的請求。 它通常用于搭配 --host 0.0.0.0 使用,因為你想要其它設(shè)備訪問你本地的服務(wù),但訪問時是直接通過 IP 地址訪問而不是 HOST 訪問,所以需要關(guān)閉 HOST 檢查。

https

DevServer 默認(rèn)使用 HTTP 協(xié)議服務(wù),它也能通過 HTTPS 協(xié)議服務(wù)。 有些情況下你必須使用 HTTPS,例如 HTTP2 和 Service Worker 就必須運行在 HTTPS 之上。 要切換成 HTTPS 服務(wù),最簡單的方式是:

devServer:{
  https: true
}

DevServer 會自動的為你生成一份 HTTPS 證書。

如果你想用自己的證書可以這樣配置:

devServer:{
  https: {
    key: fs.readFileSync("path/to/server.key"),
    cert: fs.readFileSync("path/to/server.crt"),
    ca: fs.readFileSync("path/to/ca.pem")
  }
}
clientLogLevel

devServer.clientLogLevel 配置在客戶端的日志等級,這會影響到你在瀏覽器開發(fā)者工具控制臺里看到的日志內(nèi)容。

clientLogLevel枚舉類型,可取如下之一的值 none | error | warning | info。 默認(rèn)為 info 級別,即輸出所有類型的日志,設(shè)置成 none 可以不輸出任何日志。

compress

devServer.compress 配置是否啟用 gzip 壓縮。boolean 為類型,默認(rèn)為 false

open

devServer.open 用于在 DevServer 啟動且第一次構(gòu)建完時自動用你系統(tǒng)上默認(rèn)的瀏覽器去打開要開發(fā)的網(wǎng)頁。 同時還提供 devServer.openPage 配置項用于打開指定 URL 的網(wǎng)頁。

其它配置項 Target

target 配置項可以讓 Webpack 構(gòu)建出針對不同運行環(huán)境的代碼。 target 可以是以下之一:

target值 描述
web 針對瀏覽器 (默認(rèn)),所有代碼都集中在一個文件里
node 針對 Node.js,使用 require 語句加載 Chunk 代碼
async-node 針對 Node.js,異步加載 Chunk 代碼
webworker 針對 WebWorker
electron-main 針對 Electron 主線程
electron-renderer 針對 Electron 渲染線程

例如當(dāng)你設(shè)置 target:"node" 時,源代碼中導(dǎo)入 Node.js 原生模塊的語句 require("fs") 將會被保留,fs 模塊的內(nèi)容不會打包進 Chunk 里。

Devtool

devtool 配置 Webpack 如何生成 Source Map,默認(rèn)值是 false 即不生成 Source Map,想為構(gòu)建出的代碼生成 Source Map 以方便調(diào)試,可以這樣配置:

module.export = {
  devtool: "source-map"
}
Watch 和 WatchOptions

前面介紹過 Webpack 的監(jiān)聽模式,它支持監(jiān)聽文件更新,在文件發(fā)生變化時重新編譯。在使用 Webpack 時監(jiān)聽模式默認(rèn)是關(guān)閉的,想打開需要如下配置:

module.export = {
  watch: true
}

在使用 DevServer 時,監(jiān)聽模式默認(rèn)是開啟的。

除此之外,Webpack 還提供了 watchOptions 配置項去更靈活的控制監(jiān)聽模式,使用如下:

module.export = {
  // 只有在開啟監(jiān)聽模式時,watchOptions 才有意義
  // 默認(rèn)為 false,也就是不開啟
  watch: true,
  // 監(jiān)聽模式運行時的參數(shù)
  // 在開啟監(jiān)聽模式時,才有意義
  watchOptions: {
    // 不監(jiān)聽的文件或文件夾,支持正則匹配
    // 默認(rèn)為空
    ignored: /node_modules/,
    // 監(jiān)聽到變化發(fā)生后會等300ms再去執(zhí)行動作,防止文件更新太快導(dǎo)致重新編譯頻率太高
    // 默認(rèn)為 300ms  
    aggregateTimeout: 300,
    // 判斷文件是否發(fā)生變化是通過不停的去詢問系統(tǒng)指定文件有沒有變化實現(xiàn)的
    // 默認(rèn)每1000豪秒去問1次
    poll: 1000
  }
}
Externals

Externals 用來告訴 Webpack 要構(gòu)建的代碼中使用了哪些不用被打包的模塊,也就是說這些模版是外部環(huán)境提供的,Webpack 在打包時可以忽略它們。

有些 JavaScript 運行環(huán)境可能內(nèi)置了一些全局變量或者模塊,例如在你的 HTML HEAD 標(biāo)簽里通過以下代碼:


引入 jQuery 后,全局變量 jQuery 就會被注入到網(wǎng)頁的 JavaScript 運行環(huán)境里。

如果想在使用模塊化的源代碼里導(dǎo)入和使用 jQuery,可能需要這樣:

import $ from "jquery";
$(".my-element");

構(gòu)建后你會發(fā)現(xiàn)輸出的 Chunk 里包含的 jQuery 庫的內(nèi)容,這導(dǎo)致 jQuery 庫出現(xiàn)了2次,浪費加載流量,最好是 Chunk 里不會包含 jQuery 庫的內(nèi)容。

Externals 配置項就是為了解決這個問題。

通過 externals 可以告訴 Webpack JavaScript 運行環(huán)境已經(jīng)內(nèi)置了那些全局變量,針對這些全局變量不用打包進代碼中而是直接使用全局變量。 要解決以上問題,可以這樣配置 externals

module.export = {
  externals: {
    // 把導(dǎo)入語句里的 jquery 替換成運行環(huán)境里的全局變量 jQuery
    jquery: "jQuery"
  }
}
ResolveLoader

ResolveLoader 用來告訴 Webpack 如何去尋找 Loader,因為在使用 Loader 時是通過其包名稱去引用的, Webpack 需要根據(jù)配置的 Loader 包名去找到 Loader 的實際代碼,以調(diào)用 Loader 去處理源文件。

ResolveLoader 的默認(rèn)配置如下:

module.exports = {
  resolveLoader:{
    // 去哪個目錄下尋找 Loader
    modules: ["node_modules"],
    // 入口文件的后綴
    extensions: [".js", ".json"],
    // 指明入口文件位置的字段
    mainFields: ["loader", "main"]
  }
}

該配置項常用于加載本地的 Loader。

整體配置結(jié)構(gòu)

之前的章節(jié)分別講述了每個配置項的具體含義,但沒有描述它們所處的位置和數(shù)據(jù)結(jié)構(gòu),下面通過一份代碼來描述清楚:

const path = require("path");

module.exports = {
    // entry 表示 入口,Webpack 執(zhí)行構(gòu)建的第一步將從 Entry 開始,可抽象成輸入。
    // 類型可以是 string | object | array
    entry: "./app/entry", // 只有1個入口,入口只有1個文件
    entry: ["./app/entry1", "./app/entry2"], // 只有1個入口,入口有2個文件
    entry: { // 有2個入口
        a: "./app/entry-a",
        b: ["./app/entry-b1", "./app/entry-b2"]
    },

    // 如何輸出結(jié)果:在 Webpack 經(jīng)過一系列處理后,如何輸出最終想要的代碼。
    output: {
        // 輸出文件存放的目錄,必須是 string 類型的絕對路徑。
        path: path.resolve(__dirname, "dist"),

        // 輸出文件的名稱
        filename: "bundle.js", // 完整的名稱
        filename: "[name].js", // 當(dāng)配置了多個 entry 時,通過名稱模版為不同的 entry 生成不同的文件名稱
        filename: "[chunkhash].js", // 根據(jù)文件內(nèi)容 hash 值生成文件名稱,用于瀏覽器長時間緩存文件

        // 發(fā)布到線上的所有資源的 URL 前綴,string 類型
        publicPath: "/assets/", // 放到指定目錄下
        publicPath: "", // 放到根目錄下
        publicPath: "https://cdn.example.com/", // 放到 CDN 上去

        // 導(dǎo)出庫的名稱,string 類型
        // 不填它時,默認(rèn)輸出格式是匿名的立即執(zhí)行函數(shù)
        library: "MyLibrary",

        // 導(dǎo)出庫的類型,枚舉類型,默認(rèn)是 var
        // 可以是 umd | umd2 | commonjs2 | commonjs | amd | this | var | assign | window | global | jsonp ,
        libraryTarget: "umd",

        // 是否包含有用的文件路徑信息到生成的代碼里去,boolean 類型
        pathinfo: true,

        // 附加 Chunk 的文件名稱
        chunkFilename: "[id].js",
        chunkFilename: "[chunkhash].js",

        // JSONP 異步加載資源時的回調(diào)函數(shù)名稱,需要和服務(wù)端搭配使用
        jsonpFunction: "myWebpackJsonp",

        // 生成的 Source Map 文件名稱
        sourceMapFilename: "[file].map",

        // 瀏覽器開發(fā)者工具里顯示的源碼模塊名稱
        devtoolModuleFilenameTemplate: "webpack:///[resource-path]",

        // 異步加載跨域的資源時使用的方式
        crossOriginLoading: "use-credentials",
        crossOriginLoading: "anonymous",
        crossOriginLoading: false,
    },

    // 配置模塊相關(guān)
    module: {
        rules: [ // 配置 Loader
            {
                test: /.jsx?$/, // 正則匹配命中要使用 Loader 的文件
                include: [ // 只會命中這里面的文件
                    path.resolve(__dirname, "app")
                ],
                exclude: [ // 忽略這里面的文件
                    path.resolve(__dirname, "app/demo-files")
                ],
                use: [ // 使用那些 Loader,有先后次序,從后往前執(zhí)行
                    "style-loader", // 直接使用 Loader 的名稱
                    {
                        loader: "css-loader",
                        options: { // 給 html-loader 傳一些參數(shù)
                        }
                    }
                ]
            },
        ],
        noParse: [ // 不用解析和處理的模塊
            /special-library.js$/  // 用正則匹配
        ],
    },

    // 配置插件
    plugins: [],

    // 配置尋找模塊的規(guī)則
    resolve: {
        modules: [ // 尋找模塊的根目錄,array 類型,默認(rèn)以 node_modules 為根目錄
            "node_modules",
            path.resolve(__dirname, "app")
        ],
        extensions: [".js", ".json", ".jsx", ".css"], // 模塊的后綴名
        alias: { // 模塊別名配置,用于映射模塊
            // 把 "module" 映射 "new-module",同樣的 "module/path/file" 也會被映射成 "new-module/path/file"
            "module": "new-module",
            // 使用結(jié)尾符號 $ 后,把 "only-module" 映射成 "new-module",
            // 但是不像上面的,"module/path/file" 不會被映射成 "new-module/path/file"
            "only-module$": "new-module",
        },
        alias: [ // alias 還支持使用數(shù)組來更詳細(xì)的配置
            {
                name: "module", // 老的模塊
                alias: "new-module", // 新的模塊
                // 是否是只映射模塊,如果是 true 只有 "module" 會被映射,如果是 false "module/inner/path" 也會被映射
                onlyModule: true,
            }
        ],
        symlinks: true, // 是否跟隨文件軟鏈接去搜尋模塊的路徑
        descriptionFiles: ["package.json"], // 模塊的描述文件
        mainFields: ["main"], // 模塊的描述文件里的描述入口的文件的字段名稱
        enforceExtension: false, // 是否強制導(dǎo)入語句必須要寫明文件后綴
    },

    // 輸出文件性能檢查配置
    performance: {
        hints: "warning", // 有性能問題時輸出警告
        hints: "error", // 有性能問題時輸出錯誤
        hints: false, // 關(guān)閉性能檢查
        maxAssetSize: 200000, // 最大文件大小 (單位 bytes)
        maxEntrypointSize: 400000, // 最大入口文件大小 (單位 bytes)
        assetFilter: function (assetFilename) { // 過濾要檢查的文件
            return assetFilename.endsWith(".css") || assetFilename.endsWith(".js");
        }
    },

    devtool: "source-map", // 配置 source-map 類型

    context: __dirname, // Webpack 使用的根目錄,string 類型必須是絕對路徑

    // 配置輸出代碼的運行環(huán)境
    target: "web", // 瀏覽器,默認(rèn)
    target: "webworker", // WebWorker
    target: "node", // Node.js,使用 `require` 語句加載 Chunk 代碼
    target: "async-node", // Node.js,異步加載 Chunk 代碼
    target: "node-webkit", // nw.js
    target: "electron-main", // electron, 主線程
    target: "electron-renderer", // electron, 渲染線程

    externals: { // 使用來自 JavaScript 運行環(huán)境提供的全局變量
        jquery: "jQuery"
    },

    stats: { // 控制臺輸出日志控制
        assets: true,
        colors: true,
        errors: true,
        errorDetails: true,
        hash: true,
    },

    devServer: { // DevServer 相關(guān)的配置
        proxy: { // 代理到后端服務(wù)接口
            "/api": "http://localhost:3000"
        },
        contentBase: path.join(__dirname, "public"), // 配置 DevServer HTTP 服務(wù)器的文件根目錄
        compress: true, // 是否開啟 gzip 壓縮
        historyApiFallback: true, // 是否開發(fā) HTML5 History API 網(wǎng)頁
        hot: true, // 是否開啟模塊熱替換功能
        https: false, // 是否開啟 HTTPS 模式
    },

    profile: true, // 是否捕捉 Webpack 構(gòu)建的性能信息,用于分析什么原因?qū)е聵?gòu)建性能不佳

    cache: false, // 是否啟用緩存提升構(gòu)建速度

    watch: true, // 是否開始
    watchOptions: { // 監(jiān)聽模式選項
        // 不監(jiān)聽的文件或文件夾,支持正則匹配。默認(rèn)為空
        ignored: /node_modules/,
        // 監(jiān)聽到變化發(fā)生后會等300ms再去執(zhí)行動作,防止文件更新太快導(dǎo)致重新編譯頻率太高
        // 默認(rèn)為300ms
        aggregateTimeout: 300,
        // 判斷文件是否發(fā)生變化是不停的去詢問系統(tǒng)指定文件有沒有變化,默認(rèn)每秒問 1000 次
        poll: 1000
    },
};
多種配置類型

除了通過導(dǎo)出一個 Object 來描述 Webpack 所需的配置外,還有其它更靈活的方式,以簡化不同場景的配置。

導(dǎo)出一個 Function

在大多數(shù)時候你需要從同一份源代碼中構(gòu)建出多份代碼,例如一份用于開發(fā)時,一份用于發(fā)布到線上。

如果采用導(dǎo)出一個 Object 來描述 Webpack 所需的配置的方法,需要寫兩個文件。 一個用于開發(fā)環(huán)境,一個用于線上環(huán)境。再在啟動時通過 webpack --config webpack.config.js 指定使用哪個配置文件。

采用導(dǎo)出一個 Function 的方式,能通過 JavaScript 靈活的控制配置,做到只寫一個配置文件就能完成以上要求。

導(dǎo)出一個 Function 的使用方式如下:

const path = require("path");
const UglifyJsPlugin = require("webpack/lib/optimize/UglifyJsPlugin");

module.exports = function (env = {}, argv) {
    const plugins = [];

    const isProduction = env["production"];

    // 在生成環(huán)境才壓縮
    if (isProduction) {
        plugins.push(
            // 壓縮輸出的 JS 代碼
            new UglifyJsPlugin()
        )
    }

    return {
        plugins: plugins,
        // 在生成環(huán)境不輸出 Source Map
        devtool: isProduction ? undefined : "source-map",
    };
};

在運行 Webpack 時,會給這個函數(shù)傳入2個參數(shù),分別是:

env:當(dāng)前運行時的 Webpack 專屬環(huán)境變量,env 是一個 Object。讀取時直接訪問 Object 的屬性,設(shè)置它需要在啟動 Webpack 時帶上參數(shù)。例如啟動命令是 webpack --env.production --env.bao=foo 時,則 env 的值是 {"production":"true","bao":"foo"}

argv:代表在啟動 Webpack 時所有通過命令行傳入的參數(shù),例如 --config、--env、--devtool,可以通過 webpack -h 列出所有 Webpack 支持的命令行參數(shù)。

就以上配置文件而言,在開發(fā)時執(zhí)行命令 webpack 構(gòu)建出方便調(diào)試的代碼,在需要構(gòu)建出發(fā)布到線上的代碼時執(zhí)行 webpack --env.production 構(gòu)建出壓縮的代碼。

導(dǎo)出一個返回 Promise 的函數(shù)

在有些情況下你不能以同步的方式返回一個描述配置的 Object,Webpack 還支持導(dǎo)出一個返回 Promise 的函數(shù),使用如下:

module.exports = function(env = {}, argv) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({
        // ...
      })
    }, 5000)
  })
}
導(dǎo)出多份配置

除了只導(dǎo)出一份配置外,Webpack 還支持導(dǎo)出一個數(shù)組,數(shù)組中可以包含每份配置,并且每份配置都會執(zhí)行一遍構(gòu)建。

使用如下:

module.exports = [
  // 采用 Object 描述的一份配置
  {
    // ...
  },
  // 采用函數(shù)描述的一份配置
  function() {
    return {
      // ...
    }
  },
  // 采用異步函數(shù)描述的一份配置
  function() {
    return Promise();
  }
]

以上配置會導(dǎo)致 Webpack 針對這三份配置執(zhí)行三次不同的構(gòu)建。

這特別適合于用 Webpack 構(gòu)建一個要上傳到 Npm 倉庫的庫,因為庫中可能需要包含多種模塊化格式的代碼,例如 CommonJS、UMD。

配置總結(jié)

從前面的配置看來選項很多,Webpack 內(nèi)置了很多功能。

你不必都記住它們,只需要大概明白 Webpack 原理和核心概念去判斷選項大致屬于哪個大模塊下,再去查詳細(xì)的使用文檔。

通常你可用如下經(jīng)驗去判斷如何配置 Webpack:

想讓源文件加入到構(gòu)建流程中去被 Webpack 控制,配置 entry

想自定義輸出文件的位置和名稱,配置 output

想自定義尋找依賴模塊時的策略,配置 resolve

想自定義解析和轉(zhuǎn)換文件的策略,配置 module,通常是配置 module.rules 里的 Loader。

其它的大部分需求可能要通過 Plugin 去實現(xiàn),配置 plugin

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/95190.html

相關(guān)文章

  • TCM的webpack配置與常用插件

    摘要:中的配置熱加載插件安裝中的配置優(yōu)化插件為組件分配,通過這個插件可以分析和優(yōu)先考慮使用最多的模塊,并為它們分配最小的壓縮代碼分離和文件 0 前言 本文是針對TCM項目所做的WebPack配置文件總結(jié),主要概述了一些常用配置選項和插件使用,對以后的項目有指導(dǎo)意義。TCM的webpack配置文件包括webapck.config.base.js、webapck.config.dev.js、we...

    羅志環(huán) 評論0 收藏0
  • TCM的webpack配置與常用插件

    摘要:中的配置熱加載插件安裝中的配置優(yōu)化插件為組件分配,通過這個插件可以分析和優(yōu)先考慮使用最多的模塊,并為它們分配最小的壓縮代碼分離和文件 0 前言 本文是針對TCM項目所做的WebPack配置文件總結(jié),主要概述了一些常用配置選項和插件使用,對以后的項目有指導(dǎo)意義。TCM的webpack配置文件包括webapck.config.base.js、webapck.config.dev.js、we...

    張憲坤 評論0 收藏0
  • Webpack入門到精通(1)

    前言 什么是webpack 本質(zhì)上,webpack 是一個現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)。當(dāng) webpack 處理應(yīng)用程序時,它會遞歸地構(gòu)建一個依賴關(guān)系圖(dependency graph),其中包含應(yīng)用程序需要的每個模塊,然后將所有這些模塊打包成一個或多個 bundle。 webpack 有哪些功能(代碼轉(zhuǎn)換 文件優(yōu)化 代碼分割 模塊合并 ...

    SunZhaopeng 評論0 收藏0
  • Webpack入門到精通(1)

    前言 什么是webpack 本質(zhì)上,webpack 是一個現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)。當(dāng) webpack 處理應(yīng)用程序時,它會遞歸地構(gòu)建一個依賴關(guān)系圖(dependency graph),其中包含應(yīng)用程序需要的每個模塊,然后將所有這些模塊打包成一個或多個 bundle。webpack 有哪些功能(代碼轉(zhuǎn)換 文件優(yōu)化 代碼分割 模塊合并 自...

    wangbinke 評論0 收藏0
  • 基于webpack構(gòu)建的angular 1.x 工程(一)webpack

    摘要:基于構(gòu)建的工程一篇現(xiàn)在都已經(jīng)出到的版本了,可我對它的認(rèn)識還是停留在的版本。然后是寫啟動的命令行,也就是上面的這樣寫的意思是,當(dāng)你輸入你的命令名字就會讓執(zhí)行你對應(yīng)命令的語句。我們首先把基本的配置引進來。 基于webpack構(gòu)建的angular 1.x 工程(一)webpack篇 ??現(xiàn)在AngularJS都已經(jīng)出到4.x的版本了,可我對它的認(rèn)識還是停留在1.x的版本。 ??之前用它是為...

    Anleb 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<