原文連接: https://survivejs.com/webpack...
翻譯計劃: https://segmentfault.com/a/11...附言:由於發現書中一些內容單獨放出來會比較尷尬,因此會跳過部分章節,固然完整版會所有翻譯,已經正在研究原版的網站搭建工程了
javascript
Webpack 提供了多種配置模塊 loader 的方法。 Webpack 2 開始經過引入 use
字段,簡化了 loader 使用。在這裏使用絕對路徑是一個好主意,由於它們容許你在不影響構建的狀況下移動配置。css
另外一種方法是設置 context
字段,由於這會產生相似的效果並影響 entry 和 loader 的路徑解析。可是它對輸出沒有影響,你仍然須要使用絕對路徑或 /
。java
即便你設置了 include
或 exclude
規則,從 node_modules 加載的包仍然能夠正常工做,由於它們已經被編譯爲開箱即用的代碼。若是它們沒這麼作,那麼你必須應用 Consuming Packages 章節中涵蓋的技術。node
T> include
/exclude
在處理 node_modules 問題時很是方便,由於當你將 JavaScript 文件導入項目時,webpack 會默認處理並遍歷已安裝的包。爲了讓 webpack 不處理 node_modules,你須要使用 exclude
。其餘文件類型不會遇到此問題。webpack
Webpack 經過 loader 支持多種格式的文件。此外,它支持一些開箱即用的 JavaScript 模塊規範。文件格式不一樣,但思路都是一致的,你必須設置一個或多個 loader,並將它們與你的目錄結構鏈接起來。git
{pagebreak}github
下例中 webpack 經過 Babel 處理 JavaScript:web
webpack.config.jsnpm
module.exports = { ... module: { rules: [ { // **Conditions** to match files using RegExp, function. test: /\.js$/, // **Restrictions** // Restrict matching to a directory. This // also accepts an array of paths or a function. // The same applies to `exclude`. include: path.join(__dirname, "app"), exclude(path) { // You can perform more complicated checks as well. return path.match(/node_modules/); }, // **Actions** to apply loaders to the matched files. use: "babel-loader", }, ], }, };
T> 若是你對 RegExp 的匹配不熟悉,可使用在線工具,例如 regex101,RegExr 或 Regexper。segmentfault
必定要記住 loader 老是從右到左,從下到上(拆開寫的時候)進行運算的。把它當作函數比較容易理解所謂「從右到左運行」。你能夠把 use: ["style-loader", "css-loader"]
看做 style(css(input))
。
要查看規則,請看如下示例:
{ test: /\.css$/, use: ["style-loader", "css-loader"], },
根據從右到左的規則,能夠等效拆分爲:
{ test: /\.css$/, use: "style-loader", }, { test: /\.css$/, use: "css-loader", },
儘管可使用上述規則配置,可是也能夠強制在常規規則以前或以後應用特定規則。enforce
字段在這裏能夠派上用場。把他設置爲 pre
or post
以在其餘 loader 以前或以後進行處理。
Lint 是一個很好的例子,由於 Lint 必須先於任何其餘行爲。enforce: "post"
卻是不多用到,這可能是你想對構建結果進行檢查時使用的。
{pagebreak}
基本語法以下:
{ // Conditions test: /\.js$/, enforce: "pre", // "post" too // Actions use: "eslint-loader", },
若是你能夠保證 test
中的 loader 順序無誤,那麼能夠不使用 enforce
。不過使用 enforce
方便你把不一樣步驟的 loader 分離開來,更容易組織。
可經過 query 把參數傳到 loader:
{ // Conditions test: /\.js$/, include: PATHS.app, // Actions use: "babel-loader?presets[]=env", },
這種配置風格也適用於 entry 和 import,webpack 會處理他們。在某些個別狀況下,這個寫法能派上用場,但一般狀況下最好使用如下更具可讀性的方案。
{pagebreak}
傳入對象到 use
:
{ // Conditions test: /\.js$/, include: PATHS.app, // Actions use: { loader: "babel-loader", options: { presets: ["env"], }, }, },
若是你想使用多個 loader,你能夠將一個對象數組傳遞給 use
:
{ test: /\.js$/, include: PATHS.app, use: [ { loader: "babel-loader", options: { presets: ["env"], }, }, // Add more loaders here ], },
{pagebreak}
use
字段添加分支本書中,你在更高級別上進行環境配置。實現相似結果的另外一個選擇是在 use
處使用分支,由於 webpack 的 loader 定義接受函數做爲參數,你能夠經過此函數區分環境:
{ test: /\.css$/, // `resource` refers to the resource path matched. // `resourceQuery` contains possible query passed to it // `issuer` tells about match context path use: ({ resource, resourceQuery, issuer }) => { // You have to return something falsy, object, or a // string (i.e., "style-loader") from here. // // Returning an array fails! Nest rules instead. if (env === "development") { return { use: { loader: "css-loader", // css-loader first rules: [ "style-loader", // style-loader after ], }, }; } }, },
用心感覺,這是組合配置的另外一種手段。
儘管配置級 loader 定義更可取,但能夠內聯編寫 loader 定義:
// Process foo.png through url-loader and other // possible matches. import "url-loader!./foo.png"; // Override possible higher level match completely import "!!url-loader!./bar.png";
這種方法的問題在你的源代碼會與 webpack 耦合。相同的機制還適用於 entry:
{ entry: { app: "babel-loader!./app", }, },
test
結合 include
或 exclude
是匹配文件的最經常使用方法。這些字段接受如下數據類型:
test
——匹配 RegExp,字符串,函數,對象或數組。include
——同上。exclude
——同上,輸出與 include
相反。resource: /inline/
——匹配包含查詢內容的資源路徑。示例:/path/foo.inline.js
, /path/bar.png?inline
。issuer: /bar.js/
——匹配從某處請求的資源。示例:若是 /path/foo.png
從 /path/bar.js
請求,那麼 /path/foo.png
將匹配。resourcePath: /inline/
——匹配包含查詢內容的資源路徑(不包括 query)。示例:/path/foo.inline.png
。resourceQuery: /inline/
——匹配包含查詢內容的 query(不包括 query)。示例:/path/foo.png?inline
。基於布爾值的字段可用於進一步進行約束:
Boolean based fields can be used to constrain these matchers further:
not
——不匹配給定條件(參見test
表示接受的值)。and
——同時匹配一系列條件。or
——與數組中其中一個條件匹配。resourceQuery
加載oneOf
字段能夠根據資源相關匹配將 webpack 路由到特定的 loader:
{ test: /\.png$/, oneOf: [ { resourceQuery: /inline/, use: "url-loader", }, { resourceQuery: /external/, use: "file-loader", }, ], },
若是你須要在文件名中查詢,應該使用 resourcePath
而不是 resourceQuery
。
{pagebreak}
issuer
加載issuer
基於資源的導入位置進行操做。如下示例改編自 css-loader issue 287,style-loader 將應用於 JavaScript 導入的 CSS 文件:
{ test: /\.css$/, rules: [ { issuer: /\.js$/, use: "style-loader", }, { use: "css-loader", }, ], },
另外一種方法結合了 issuer
和 not
:
{ test: /\.css$/, rules: [ // CSS imported from other modules is added to the DOM { issuer: { not: /\.css$/ }, use: "style-loader", }, // Apply css-loader against CSS imports to return CSS { use: "css-loader", }, ], }
經過觀察 loader 行爲能夠更深刻地理解它們。 loader-runner 容許你在沒有 webpack 的狀況下單獨運行它們。Webpack 在底層也是使用此軟件包,Extending with Loaders 章節將會詳細介紹它。
inspect-loader 能夠監視 loader 之間傳遞的內容。將此 loader 添加到你的配置便可檢查其中的數據流,而沒必要在 node_modules 中插入 console.log
。
Webpack 提供了多種設置 loader 的方法,但在 webpack 4 中用好 use
就足夠了。注意 loader 的處理順序,這是不少常見的問題來源。
回顧一下:
use
字段。它將之前的 loader
和 loaders
字段結合到了一塊兒。在下一章中,你將學習使用 webpack 加載圖片。