您的位置:首頁>遊戲>正文

webpack3中文版使用參考文檔——全面解析webpack.config.js

Webpack目前官方發佈的最新版本是3.1.0, 相對於2.0的怎麼本, 在語法上沒有變動, 只是新增了功能。 使用webpack, 需要事先安裝node.js, 並對node.js生態有一些基本的瞭解,比如(npm init 初始化專案, npm install 安裝一個包等等)。 使用webpack通常有兩種方式:1. 命令列方式(CLI) , 2 script方式(推薦)。 兩種方式都需要理解webpack概念。

概念

webpackis amodule bundlerfor modern JavaScript applications. When webpack processes your application, it recursively builds adependency graphthat includes every module your application needs, then packages all of those modules into a small number ofbundles- often only one - to be loaded by the browser.

webpack是時下很火的js模組化的打包工具。 當用webpack處理你的應用時, 它會遞迴的構建每個模組的依賴關係圖,然後把所有的這些依賴模組打包到一個由數個小塊組成的檔中--通常只有一個(將被流覽器載入)

It is incredibly configurable, but to get started you only need to understand Four Core Concepts: entry, output, loaders, and plugins.

雖然它是高度可配置的, 但是初步使用你只需要理解下面這四個核心概念:入口,

輸出, 載入器, 外掛程式。 預設情況下, 所有這些配置項, 都保存在專案根目錄下一個名為webpack.config.js的文件中。

一. 入口 (entry)

The entry pointtells webpackwhere to startand follows the graph of dependencies to knowwhat to bundle. You can think of your application'sentry pointas the contextual root or the first file to kick off your app.

所謂的入口, 就是告訴webpack從哪裡開始並通過依賴關係圖得知要哪些檔要打包。 你可以理解為應用程式最先讀取的檔。 讀取這個檔之後, 就會產生一個模組依賴關係圖, 那麼當前這個檔, 就是依賴關係的根。

webpack.config.js

module.exports = { entry: './path/to/my/entry/file.js' };

上例告訴webpack從./path/to/my/entry/file.js開始打包, 這是最簡單的一種入口形式, 實際上, 它是下面這種形式的簡寫

module.exports = { entry : { main : './path/to/my/entry/file.js' } }

entry 還可以是陣列的方式

module.exports = { entry: ['./path/to/my/entry/file.js'] };

這對於不想在js中引入css的情況非常有用, 比如:

module.exports = { entry: ['./path/to/my/entry/file.js','./path/to/my/entry/file.css'] };

如果是多頁應用或者想要提取公共代碼(CommonsChunkPlugin)的話, 就需要使用下面這種入口方式:

module.exports = { entry: { pageOne: './src/pageOne/index.js', pageTwo: './src/pageTwo/index.js', pageThree: './src/pageThree/index.js' } }

當然, 這裡也可以使用陣列的形式, 同時引入樣式或其它檔

module.exports = { entry: { pageOne: ['./src/pageOne/index.js','./src/pageOne/index.css'], pageTwo: ['./src/pageTwo/index.js'], pageThree: ['./src/pageThree/index.js'] } }

以上就是關於入口這個概念和配置的全部內容了, 更詳細的介紹請移步官方網站關於入口的擴展介紹。 除了要告訴webpack要從哪個檔開始打包之外, 還要告訴它打包生成的檔存放在哪個位置。 於是就有了輸出的配置。

二. 輸出 (output)

webpack的output屬性就是告訴webpack怎麼對待這些打包的代碼。

Configuring the outputconfiguration options tell webpack how to write the compiled files to disk. Note that, while there can be multipleentrypoints, only oneoutputconfiguration is specified.

配置output屬性就是告訴webpack把編譯後的檔寫在磁片的哪個地方。 注意一點, 雖然入口中可以配置成多個檔的形式, 但是輸出只能指定一個。

--- 打包之後資源, 並不總是寫在磁片上, 也可能是在記憶體中, 比如使用webpack-dev-server的時候。 (譯者注)

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有兩個屬性是必須的。

1. path 輸出路徑

An absolute pathto your preferred output directory. 通常是絕對路徑。

2. filename 檔案名

當入口是多個檔的時候, 可以用變數[name]代替固定的名字。 這裡的name變數, 對應entry中的key. ( 對於entry:配置成字串的時候,

輸出的檔案名就是main, 如果不明白, 查看前面入口是誰的簡寫形式)

module.exports = { entry: { app: './src/app.js', search: './src/search.js' }, output: { filename: '[name].js', path: __dirname + '/dist' } }

在filename屬性中, 除了[name]之外, 還可以用[hash],[contenthash]等內置變數, Tips ! [hash:8] 截取hash前8位

3. publicPath 虛擬路徑

如果你有一個功能變數名稱或打算用CDN, 可以使用這個配置, 如果你不知道, 或暫時不打算用, 可以先留空

output: { path: "/home/proj/cdn/assets/", publicPath: "http://cdn.example.com/assets/", filename:'[name].js' }

注意:如果配置了publicPath屬性, 那麼本地資源路徑, 都會被替換成publicPath所指定的位址 (譯者注)

三、載入器

Loaders are transformations that are applied on the source code of a module. They allow you to pre-process files as you importor “load” them. Thus, loaders are kind of like “tasks” in other build tools, and provide a powerful way to handle front-end build steps. Loaders can transform files from a different language (like TypeScript) to JavaScript, or inline images as data URLs. Loaders even allow you to do things likeimportCSS files directly from your JavaScript modules!

載入器用於將資原始程式碼轉換成模組。 它允許您在導入或“載入”它們時預處理檔。 因此, 載入器就像處理各種任務的小工具, 它提供一個強大的方法來處理前端構建步驟。 載入器可以把不同類型的檔(比如typescript)轉換成javascript 或者把圖片處理成內聯的資料位址(如base64), 載入器甚至可以像導入js模組一樣直接導入樣式檔。

載入器聽起來很曆害的樣子, 不過它不能算是webpack的功能, 如果要想在專案中導入樣式模組, 需要先安裝樣式的載入器(css-loader), 同樣的, 要導入圖片要安裝檔載入器(file-loader)

在命令列中輸入:
npm install --save-dev css-loader
即可安裝樣式載入器, 後面跟的參數--save-dev 表示將保存到package.json的開發環境依賴屬性中。 對應還有一個--save表示安裝到生產環境。 package.json檔可以通過手工創建, 也可用npm init(推薦)
創建。 更多關於package.json的介紹請移步這裡

webpack.config.js

module.exports = { module: { rules: [ { test: /.css$/, use: 'css-loader' } ] } };

載入器位於module屬性中(適用於webpack2.0+), rules 是一個陣列, 裡邊可以添加多個載入器(loader). 每一個載入器用物件的方式組織, 下面是一個更為複雜的配置

module: { rules: [ { test: /.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true } } ] } ] }

每一個載入器, 都有各自對應的配置內容, 比如css-loader的詳細配置請移步這裡, 但是不管怎麼說, 方法都是一樣的。

需要指出的事, 載入器, 除了在webpack.config.js中配置之外, 還可以直接在js代碼中用行內載入的方式使用, 比如

import Styles from 'style-loader!css-loader?modules!./styles.css'; //多個載入器之間用!進行分隔

不過這種方式寫起來很冗長, 不推薦。 還有一種方式, 也一併提一下, 在CLI方式中的使用

webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

同樣的冗長, 瞭解一下即可, 實際項目中, 大多是使用webpack.config.js進行集中配置。

一般來說, 一個載入器就可以完成一個任務, 比如file-loader 可以載入檔到js的模組中, 可是我們常常發現, 載入css到js模組中, 除了使用css-loader之外, 常常還有一個多個附加的伴侶, 比如這個style-loader。

這是為什麼呢? 這其實是因為樣式的使用有兩種方式, 一種是內聯的方式, 寫在html的style標籤中, 還有一種是外鏈, 通過link的方式引用。 而我們在開發環境中, css是作為js的模組打包進js檔中的。 而且js要使用樣式,必須在html中插入style標籤,然後把樣式以字串的形式插入標籤內。所以這裡需要用到兩個載入器,首先用css-loader把樣式讀取到js的模組中,然用style-loader寫入style標籤中。所以也就出現了css-loader和style-loader成對使用的情況。對於同時使用多個載入器的情況,它們的調用順序是從右向左的。也就是說最先使用的要寫在最右邊,對於新式這個例子來說,就是style-loader!css-loader這樣寫。關於style-loader這個載入器,其實它還有一個少被人提起,卻非常有用的功能--熱替換,這部分內容後面再細說

有人不禁要問,既然css可以直接用link的方式使用,為什麼不把css打包成獨立的css文件呢?這樣我就不需要用style-loader了,而且把樣式內聯在html中,看著不舒服。好吧,這就不得不引出webpack中的第四個概念了---外掛程式

四、 外掛程式 plugins

They also serve the purpose of doing anything else that a loadercannot do.

外掛程式用於完成一些載器所不能做的事情。

其實這樣解釋不並是很嚴謹,但是外掛程式,確實使的webpack更加強大了。回到前說的獨立樣式的問題,結合外掛程式來做。

先安裝extract-text-webpack-plugin 這個外掛程式

npm install --save-dev extract-text-webpack-plugin

var path = require('path'); var webpack = require('webpack'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var node_modules_dir = path.resolve(__dirname, '../node_modules'); module.exports = { entry: { home:'./src/home.es6' }, module: { rules:[{ test:/.css/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ["css-loader","postcss-loader"] }) } ] }, output: { path: path.resolve(__dirname,"../dist"), filename: 'js/[name][hash:7].js' }, plugins: [ new ExtractTextPlugin({ filename: "css/[name].[contenthash].css" }), new webpack.optimize.UglifyJsPlugin ], }

new webpack.optimize.UglifyJsPlugin //用來壓縮代碼,這個是webpack送的,不需要單獨安裝, new ExtractTextPlugin 用來提取css到一個獨立的樣式檔,這個外掛程式需要自己安裝,還要在loader中進行相應的改動,配合使用才能生效。值得注意的是,這樣一來,就牲犧了css的熱替換能力了。不過沒有關係,這個外掛程式一般用在生產環境。

Hot Module Replacement (HMR熱替換)

這應當屬於webpack中比較高級的內容了,但是在開發中,結合熱替換一起使用,會很方便。最簡單的使用方式是通過 webpack-dev-server --hot --inline

關於這一部分的內容,參考我以前寫的一篇文章。官方介紹移步這裡這裡需要指出的是,並不是加了--hot就可以實現熱替換,這需要對應的載入器支援“熱替換”才行的。

比如前面說的樣式,style-loader是可以支援熱替換的。而且對於js來說,雖然webpack不需要額外的載入器就可以進模組化,但是並不支援“熱替換", 如果使用react.js的話,可以用react-hot-loader,如果用Vue的話,可以用vue-loader。 如果該載入器不支援熱替,會降級為自動刷新。因此,熱替換,並不是自動刷新哦。

總結

webpack3還比較新,如果之前使用webpack2的專案,直接升級到webpack3的話,需要小心了,有些載入器和外掛程式可能不支持webpack3. 比如提取css為獨立檔的外掛程式,就不支持。webpack-dev-server也不支持 (至少在我寫這篇文章的時候還是不支持的),但是不能因噎廢食,新技術最終會取替舊技術,這是行業趨勢。安於現狀,只會被淘汰。webpack的學習最好是自己寫一個簡單項目,把文章提到的和自己學到的loader,plugin都試試。把基本的概念和用法型明白之後,可以安裝別人寫的比較優盤的項目拿來對照學習,比如Vue-cli。看看行業大牛們,是怎麼配置webpack的,他們都用了哪些外掛程式和載入器。最後,我也提供一下自己練習的項目,做為本篇的結尾。https://github.com/bjtqti/font-end-boilerplate.git

而且js要使用樣式,必須在html中插入style標籤,然後把樣式以字串的形式插入標籤內。所以這裡需要用到兩個載入器,首先用css-loader把樣式讀取到js的模組中,然用style-loader寫入style標籤中。所以也就出現了css-loader和style-loader成對使用的情況。對於同時使用多個載入器的情況,它們的調用順序是從右向左的。也就是說最先使用的要寫在最右邊,對於新式這個例子來說,就是style-loader!css-loader這樣寫。關於style-loader這個載入器,其實它還有一個少被人提起,卻非常有用的功能--熱替換,這部分內容後面再細說

有人不禁要問,既然css可以直接用link的方式使用,為什麼不把css打包成獨立的css文件呢?這樣我就不需要用style-loader了,而且把樣式內聯在html中,看著不舒服。好吧,這就不得不引出webpack中的第四個概念了---外掛程式

四、 外掛程式 plugins

They also serve the purpose of doing anything else that a loadercannot do.

外掛程式用於完成一些載器所不能做的事情。

其實這樣解釋不並是很嚴謹,但是外掛程式,確實使的webpack更加強大了。回到前說的獨立樣式的問題,結合外掛程式來做。

先安裝extract-text-webpack-plugin 這個外掛程式

npm install --save-dev extract-text-webpack-plugin

var path = require('path'); var webpack = require('webpack'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var node_modules_dir = path.resolve(__dirname, '../node_modules'); module.exports = { entry: { home:'./src/home.es6' }, module: { rules:[{ test:/.css/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ["css-loader","postcss-loader"] }) } ] }, output: { path: path.resolve(__dirname,"../dist"), filename: 'js/[name][hash:7].js' }, plugins: [ new ExtractTextPlugin({ filename: "css/[name].[contenthash].css" }), new webpack.optimize.UglifyJsPlugin ], }

new webpack.optimize.UglifyJsPlugin //用來壓縮代碼,這個是webpack送的,不需要單獨安裝, new ExtractTextPlugin 用來提取css到一個獨立的樣式檔,這個外掛程式需要自己安裝,還要在loader中進行相應的改動,配合使用才能生效。值得注意的是,這樣一來,就牲犧了css的熱替換能力了。不過沒有關係,這個外掛程式一般用在生產環境。

Hot Module Replacement (HMR熱替換)

這應當屬於webpack中比較高級的內容了,但是在開發中,結合熱替換一起使用,會很方便。最簡單的使用方式是通過 webpack-dev-server --hot --inline

關於這一部分的內容,參考我以前寫的一篇文章。官方介紹移步這裡這裡需要指出的是,並不是加了--hot就可以實現熱替換,這需要對應的載入器支援“熱替換”才行的。

比如前面說的樣式,style-loader是可以支援熱替換的。而且對於js來說,雖然webpack不需要額外的載入器就可以進模組化,但是並不支援“熱替換", 如果使用react.js的話,可以用react-hot-loader,如果用Vue的話,可以用vue-loader。 如果該載入器不支援熱替,會降級為自動刷新。因此,熱替換,並不是自動刷新哦。

總結

webpack3還比較新,如果之前使用webpack2的專案,直接升級到webpack3的話,需要小心了,有些載入器和外掛程式可能不支持webpack3. 比如提取css為獨立檔的外掛程式,就不支持。webpack-dev-server也不支持 (至少在我寫這篇文章的時候還是不支持的),但是不能因噎廢食,新技術最終會取替舊技術,這是行業趨勢。安於現狀,只會被淘汰。webpack的學習最好是自己寫一個簡單項目,把文章提到的和自己學到的loader,plugin都試試。把基本的概念和用法型明白之後,可以安裝別人寫的比較優盤的項目拿來對照學習,比如Vue-cli。看看行業大牛們,是怎麼配置webpack的,他們都用了哪些外掛程式和載入器。最後,我也提供一下自己練習的項目,做為本篇的結尾。https://github.com/bjtqti/font-end-boilerplate.git

Next Article
喜欢就按个赞吧!!!
点击关闭提示