1. 新建一個文件夾,命名爲 webpack-cli , webpack-cli 就是你的項目名,項目名建議使用小寫字母,而且不帶空格,不能含有大寫字母.javascript
2. 安裝 Webpack,Webpack 可使用 npm 安裝.
使用終端在該文件夾中執行下述指令就能夠完成安裝,因爲網絡緣由安裝過程可能須要一些時間。css
//全局安裝 npm install -g webpack //安裝到你的項目目錄 npm install --save-dev webpack 注:建議用淘寶鏡像的cnpm依賴包能下載的快一些
Webpack 能夠全局安裝,也能夠安裝到你的項目目錄.剛開始學習 Webpack 爲了方便,建議同時全局安裝和安裝到你的項目目錄.html
3. 在 webpack-cli 文件夾中建立一個 package.json 文件,這是一個標準的 npm 說明文件,裏面蘊含了豐富的信息,包括當前項目的依賴模塊,自定義的腳本任務等等。在終端中使用 npm init 命令能夠自動建立這個 package.json 文件.前端
npm init
輸入這個命令後,終端會問你一系列諸如項目名稱,項目版本,項目描述,入口文件,做者等信息,不過不用擔憂,若是你不許備在 npm 中發佈你的模塊,這些問題的答案都不重要,傻瓜式操做一路回車默認便可.這些信息從此均可以更改 package.json 來修改,因此不用擔憂.java
4. 在 webpack-cli 文件夾中建立兩個文件夾 src文件夾和 dist文件夾, src文件夾用來存放原始數據,例如: SASS 文件、LESS 文件、JavaScript 模塊等,dist 文件夾用來存放通過 Webpack 處理過的 src文件夾數據,這也是準備給瀏覽器讀取的數據,其中包括使用 Webpack 打包後的 js 文件等。在這裏還須要在 dist 文件夾中建立 index.html 文件.在 src文件夾中建立 name.js 和 main.js 文件,node
5.在 dist文件夾中的 index.html 文件只有最基礎的 html 代碼,它惟一的目的就是加載打包後的 js 文件 bundle.js.react
// index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>webpack-cli</title> </head> <body> <div id="root"></div> <script src="bundle.js"></script> </body> </html>
6. 在 src文件夾中的 name.js 只包括一個用來返回name信息的 html 元素的函數。webpack
// name.js module.exports = function(){ var name = document.createElement('h1'); name.textContent = "My name is MMhui"; return name; };
7. 在 src文件夾中的 main.js 用來把 name模塊(其實能夠簡單的把它看做 name.js)返回的節點插入頁面。git
// main.js var name = require('./name.js'); document.querySelector('#root').appendChild(name());
Webpack 配置文件
Webpack 配置文件其實也是一個簡單的 JavaScript 模塊,能夠把全部與項目構建相關的信息放在裏面。在 webpack-cli 文件夾根目錄下新建一個名爲 webpack.config.js 的文件,並在其中進行最簡單的配置.以下所示,它包含入口文件路徑和存放打包後文件的地方路徑。github
// webpack.config.js module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑 output: { path: __dirname + '/dist/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 } }; 注:__dirname 是 node.js 中的一個全局變量,它指向當前 js 文件所在的目錄.
如今只須要在終端裏運行 webpack 命令就能夠了,這條命令會自動參考 webpack.config.js 文件中的配置選項打包你的項目,輸出結果
此時項目的 dist 文件夾下也會出現打包好的 bundle.js 文件.:
利用 npm 更快捷的執行打包任務
經過 Webpack 配置文件和執行 webpack 命令實際上是比較煩人且容易出錯的,不過值得慶幸的是 npm 能夠引導任務執行,對其進行配置後可使用簡單的 npm start 命令來代替這些繁瑣的命令。在 package.json 中對 npm 的腳本部分進行相關設置,至關於把 npm 的 start 命令指向 webpack 命令,設置方法以下:
// package.json { "name": "webpack-cli", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack" }, "author": "", "license": "ISC", "devDependencies": { "webpack": "^3.8.1" } }
執行 npm start 後命令行的輸出顯示
如今只須要使用 npm start 就能夠打包文件了.打開 dist 目錄下的 index.html 文件,看到的最終效果是否是與以前的同樣.
利用 Webpack 生成 Source Maps
簡單說,Source Maps 就是一個信息文件,裏面儲存着位置信息。也就是說,轉換後的代碼的每個位置,所對應的轉換前的位置.有了它,出錯的時候,除錯工具將直接顯示原始代碼,而不是轉換後的代碼。這無疑給開發者帶來了很大方便.爲了方便調試能夠利用 Webpack 生成 Source Maps.
在 Webpack 的配置文件中配置 Source Maps,須要配置 devtool,它有如下四種不一樣的配置選項,各有優缺點,描述以下:
1.source-map 在一個單獨的文件中產生一個完整且功能徹底的文件。這個文件具備最方便調試的 Source Maps,可是這個文件會比較大,會減慢打包文件的構建速度.
2.cheap-module-source-map 在一個單獨的文件中生成一個不帶列映射的 Source Maps,不帶列映射可以提升項目構建速度,但這也使得瀏覽器開發者工具只能對應到具體的行,不能對應到具體的列,會對調試形成不便.
3.eval-source-map 在同一個文件中生成乾淨的完整的 Source Maps。這個選項能夠在不影響構建速度的前提下生成完整的 Source Maps,可是對打包後輸出的 js 文件的執行具備性能和安全的隱患。不過在開發階段這是一個很是好的選項,可是在生產階段必定不要用這個選項.
4.cheap-module-eval-source-map 這是在打包文件時最快的生成 Source Maps 的方法,生成的Source Map 會和打包後的 js 文件同行顯示,沒有列映射,和 eval-source-map 選項具備類似的缺點,文件的執行具備性能和安全的隱患.
上述選項由上到下打包速度愈來愈快,不過同時也具備愈來愈多的負面做用,較快的構建速度的後果就是對打包的文件執行有必定影響。在學習階段以及在小到中型的項目上,eval-source-map是一個很好的選項,不過記得只在開發階段使用它.
編輯 webpack-cli 文件夾下的 webpack.config.js 文件配置 devtool 選項,生成 Source Maps 文件.配置 devtool 後的 webpack.config.js 文件以下:
// webpack.config.js module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑 output: { path: __dirname + '/dist/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map' // 配置生成的source-map };
執行 npm start 命令後就能生成對應的 Source Maps,終端輸出信息
此時項目中 dist文件夾下也生成了名爲 bundle.js.map 的 Source Maps 文件.此時項目結構以下圖所示:
使用 Webpack 構建本地服務器
想不想讓你的瀏覽器監測你修改的代碼,並自動刷新修改後的結果.其實 Webpack 提供一個可選的本地開發服務器,這個本地服務器基於 node.js 構建,能夠實現你想要的這些功能,不過它是一個單獨的組件,在 Webpack 中進行配置以前須要單獨安裝它做爲項目依賴.在終端中輸入下面的指令安裝對應組件.建議同時全局安裝和安裝到你的項目目錄.
//全局安裝 npm install -g webpack-dev-server //安裝到你的項目目錄 npm install --save-dev webpack-dev-server
devserver 做爲 Webpack 配置選項中的一項,具備如下配置選項
contentBase: 默認 webpack-dev-server 會爲根文件夾提供本地服務器,若是想爲另一個目錄下的文件提供本地服務器,應該在這裏設置其所在目錄(本例設置到「dist"文件夾下).
port: 設置默認監聽端口,若是省略,默認爲"8080".
inline: 設置爲 true,當源文件改變時會自動刷新頁面.
historyApiFallback: 在開發單頁應用時很是有用,它依賴於 HTML5 history API,若是設置爲 true,全部的跳轉將指向 index.html.
open: 直接打開瀏覽器
編輯 webpack-cli 文件夾下的 webpack.config.js 文件配置以上選項.
// webpack.config.js module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/dist/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { contentBase: './dist', port: '9000', inline: true, historyApiFallback: true, open: true } };
在終端中輸入以下命令,構建本地服務器: webpack-dev-server
終端輸出信息,表示 Webpack 構建的本地服務器已啓動.
瀏覽器自動打開 http://localhost:9000/ 就能夠看到像以前同樣的頁面.
也可使用 npm 更快捷的執行任務,編輯 webpack-cli 文件夾下的 package.json 文件 scripts 選項.
// package.json { "name": "webpack-cli", "version": "1.0.0", "description": "", "scripts": { "start": "webpack", "dev": "webpack-dev-server --devtool eval --progress --content-base build" }, "author": "", "license": "ISC" }
在終端中執行 npm run dev 命令,輸出信息以下圖,同樣能夠啓動的本地服務器.
按 Ctrl + C 便可退出本地服務器.
一切皆模塊
Webpack 有一個不可不說的優勢,它把全部的文件均可以當作模塊處理,包括你的 JavaScript 代碼,也包括 CSS 和 fonts 以及圖片等等,只要經過合適的 Loaders,它們均可以被當作模塊被處理.
Loaders
webpack 可使用 loader 來預處理文件。這容許你打包除 JavaScript 以外的任何靜態資源.經過使用不一樣的 loader,Webpack 經過調用外部的腳本或工具能夠對任何靜態資源進行處理,好比說分析 JSON 文件並把它轉換爲 JavaScript 文件,或者說把 ES6 / ES7 的 JS 文件轉換爲現代瀏覽器能夠識別的 JS 文件.對 React 開發而言,合適的 Loaders 能夠把 React 的 JSX 文件轉換爲 JS 文件.
Loaders 須要單獨安裝而且須要 在webpack.config.js 下的 modules 關鍵字下進行配置,Loaders 的配置選項包括如下幾方面:
test:一個匹配 Loaders 所處理的文件的拓展名的正則表達式(必須)
use:use: [ { loader: ['style-loader']}, { loader: ['css-loader'], options: { modules: true } } ]
include/exclude: 手動添加必須處理的文件/文件夾,或屏蔽不須要處理的文件/文件夾(可選)
loader:loader 的名稱(必須)
query:爲 Loaders 提供額外的設置選項(可選)
繼續動手實踐,修改 src文件夾下的 name.js 文件,把問候消息放在一個單獨的 JSON 文件裏,經過 loader 的使 name.js 能夠讀取該 JSON 文件.
1. 在 src文件夾下建立 name.json 文件,並輸入以下代碼:
//name.json { "name": "My name is MMhui" }
2. 編輯 src文件夾下的 name.js 文件,修改後以下:
// name.js var text = require('./name.json'); module.exports = function(){ var name = document.createElement('h1'); name.textContent = text.name; return name; };
3. 安裝支持導入 JSON 文件的 json-loader .因爲 webpack 2.× 默認支持導入 JSON 文件.若是你使用自定義文件擴展名,可能仍然須要使用此 loader.在終端中運行以下命令,安裝 json-loader 到你的項目中.
//安裝到你的項目中 npm install --save-dev json-loader
由於 json-loader 安裝到你的項目目錄裏了,因此 webpack-cli項目下會新增一個 node_modules 文件夾用於存放安裝的 json-loader.此時的項目結構以下:
- 編輯 webpack.config.js 文件配置 modules 選項,添加 json-loader,編輯後的文件以下:
// webpack.config.js module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/dist/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { contentBase: './dist', port: '9000', inline: true, historyApiFallback: true, open: true }, module: { rules: [ { test: /\.json$/, loader: 'json-loader' } ] } };
在終端中輸入 npm start 從新編譯打包,再在瀏覽器中打開 dist 文件夾下的 index.html 文件,若是看到和下圖同樣的,就說明 json-loader 配置成功了.
Babel
Babel 實際上是一個編譯 JavaScript 的平臺,它的強大之處表如今能夠經過編譯幫你達到如下目的:
把 ES6 / ES7 標準的 JavaScript 轉化爲瀏覽器可以解析的 ES5 標準的 JavaScript.
使用基於 JavaScript 進行了拓展的語言,好比 React 的 JSX.
Babel的安裝與配置
Babel 實際上是幾個模塊化的包,其核心功能位於稱爲 babel-core 的 npm 包中,不過 Webpack 把它們整合在一塊兒使用,可是對於每個你須要的功能或拓展,你都須要安裝單獨的包.用得最多的是解析 ES6 的 babel-preset-es2015 包和解析 JSX 的 babel-preset-react 包.
先來安裝這些依賴包,輸入以下命令,把這些依賴包安裝到你的項目中.
// 利用 npm 一次性安裝多個依賴模塊,模塊之間用空格隔開 npm install --save-dev babel-core babel-loader babel-preset-es2015
編輯 webpack.config.js 文件配置 module 選項,添加 Babel 配置,編輯後的文件以下:
// webpack.config.js module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/dist/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { contentBase: './dist', port: '9000', inline: true, historyApiFallback: true, open: true }, module: { rules: [ { test: /\.json$/, loader: 'json-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/, // 編譯打包時排除node_modules文件夾 query: { presets: ['es2015'] } } ] } };
使用 ES6 的語法,更新 src 文件夾下的 name.js 文件,修改後的代碼以下:
// Greeter.js import text from './name.json'; let el = document.createElement('h1'); el.textContent = text.name + '改動了'; export default el;
使用 ES6 修改 src文件夾下的 main.js 文件,修改後的代碼以下:
// main.js import name from './name.js'; document.querySelector('#root').appendChild(name);
在終端中運行 npm start 命令從新編譯打包,終端輸出信息以下:
在瀏覽器中打開 dist文件夾下的 index.html 文件,若是看到和下圖同樣的,就說明已經成功配置了 Babel.
Babel的配置選項
Babel 其實能夠徹底在 webpack.config.js 文件中進行配置,可是考慮到 babel 具備很是多的配置選項,在單一的 webpack.config.js 文件中進行配置每每使得這個文件顯得太複雜,所以一些開發者支持把 babel 的配置選項放在一個單獨的名爲 ".babelrc" 的配置文件中。咱們如今的 babel 的配置並不算複雜,不過以後咱們會再加一些東西,所以如今咱們就提取出相關部分,分兩個配置文件進行配置, Webpack 會自動調用 .babelrc 裏的 babel 配置選項.
編輯 webpack.config.js 文件配置 modules 選項,添加 Babel 配置,編輯後的文件以下:
// webpack.config.js module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/dist/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { contentBase: './dist', port: '9000', inline: true, historyApiFallback: true, open: true }, module: { rules: [ { test: /\.json$/, loader: 'json-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ // 編譯打包時排除node_modules文件夾 } ] } };
webpack-cli 文件夾下新建 .babelrc 文件,添加以下代碼:
// .babelrc { presets: ['es2015'] }
在終端中運行 npm start 命令從新編譯打包,終端輸出信息以下:
在瀏覽器中打開 dist文件夾下的 index.html 文件,若是看到和上次打開的html頁面同樣的,就說明已經成功配置了 Babel.
CSS
Webpack 提供兩個工具處理樣式表,css-loader 和 style-loader.
css-loader 使你可以使用相似 @import 和 url(...) 的方法實現 require() 的功能
style-loader 將全部的計算後的樣式加入頁面中
兩者組合在一塊兒使你可以把樣式表嵌入 Webpack 打包後的 JS 文件中。
先來安裝 css-loader, style-loader,輸入以下命令,把這些依賴包安裝到你的項目中. npm install --save-dev style-loader css-loader
編輯 webpack.config.js 文件配置 module 選項,添加處理樣式表配置,編輯後的文件以下:
// webpack.config.js module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/dist/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { contentBase: './dist', port: '9000', inline: true, historyApiFallback: true, open: true }, module: { rules: [ { test: /\.json$/, loader: 'json-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ // 編譯打包時排除node_modules文件夾 }, { test: /\.css$/, use: [ { loader: 'style-loader'}, { loader: 'css-loader', options: { modules: true } } ] } ] } };
接下來,在 src文件夾裏建立一個名爲 main.css 的文件,在文件中添加以下代碼,對一些元素設置樣式.
// main.css html { box-sizing: border-box; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } html, body{ width: 100%; height: 100%; background: #ccc; }
Webpack 只有單一的入口,其它的模塊須要經過 import, require, url 等導入相關位置,爲了讓 Webpack 能找到 main.css 文件,咱們把它導入 src 文件夾下的 main.js 中.修改 src文件夾下的 main.js 文件,修改後的代碼以下:
// main.js import name from './name.js'; import './main.css'; // 導入css文件 document.querySelector('#root').appendChild(name);
在終端中運行 npm start 命令從新編譯打包,終端輸出信息以下:
在瀏覽器中打開 dist 文件夾下的 index.html 文件,若是看到和下圖同樣的,就說明已經配置成功了.
一般狀況下,css 會和 js 打包到同一個文件中,並不會打包爲一個單獨的 css 文件,不過經過合適的配置 Webpack 也能夠把 css 打包爲單獨的文件的。 不過這也只是 Webpack 把 css 當作模塊而已,繼續看一個真的 CSS 模塊的實踐.
CSS module
在過去的一些年裏,JavaScript 經過一些新的語言特性、更好的工具、更好的實踐方法(好比說模塊化)發展得很是迅速。模塊使得開發者把複雜的代碼轉化爲小的、乾淨的、依賴聲明明確的單元,且基於優化工具,依賴管理和加載管理能夠自動完成。
不過前端的另一部分,CSS 的發展就相對慢一些,大多的樣式表卻依舊是巨大且充滿了全局類名,這使得維護和修改都很是困難和複雜。
CSS modules 的技術就可以把 JS 的模塊化思想帶入 CSS 中來,經過 CSS 模塊,全部的類名,動畫名默認都只做用於當前模塊.
Webpack 從一開始就對 CSS 模塊化提供了支持,在 CSS loader 中進行配置後,你所須要作的一切就是把 modules 傳遞到須要的地方,而後就能夠直接把 CSS 的類名傳遞到組件的代碼中,且這樣作只對當前組件有效,沒必要擔憂在不一樣的模塊中具備相同的類名可能會形成的問題。
編輯 webpack.config.js 文件配置 modules 選項,添加處理樣式表配置,編輯後的文件以下:
// webpack.config.js module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/dist/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { contentBase: './dist', port: '9000', inline: true, historyApiFallback: true, open: true }, module: { rules: [ { test: /\.json$/, loader: 'json-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ // 編譯打包時排除node_modules文件夾 }, { test: /\.css$/, use: [ { loader: 'style-loader'}, { loader: 'css-loader?modules', // 此處多加了一個?modules options: { modules: true } } ] } ] } };
接下來,在 src文件夾裏建立一個名爲 name.css 的文件,在文件中添加以下代碼,對一些元素設置樣式.
// name.css
.root{
display: flex;
background: #fff;
padding: 10px;
border: 4px solid #f00;
}
導入 .root 到 name.js 中,修改 src文件夾下的 name.js 文件,修改後的代碼以下:
// name.js import text from './name.json'; import styles from './name.css'; // 導入.root到name.js中 let el = document.createElement('h1'); el.className = styles.root; // 導入.root到name.js中 el.textContent = text.name + '改動了'; export default el;
在終端中運行 npm start 命令從新編譯打包,終端輸出信息以下:
在瀏覽器中打開 dist文件夾下的 index.html 文件,若是看到和下圖同樣的,就說明已經配置成功了.
CSS modules 也是一個很大的主題,有興趣的話能夠去官方文檔查看更多消息.下面兩篇文章也能夠看看:
CSS 預處理器
CSS 預處理器能夠將 SASS、LESS 文件轉化爲瀏覽器可識別的 CSS 文件,如下是經常使用的CSS 預處理器 loaders.
Less Loader
Sass Loader
Stylus Loader
其實也存在一個 CSS 的處理平臺 PostCSS,它能夠幫助你的 CSS 實現更多的功能,能夠看看<<PostCSS 是個什麼鬼東西?>>.
舉例來講如何使用 PostCSS,咱們使用 PostCSS 來爲 CSS 代碼自動添加適應不一樣瀏覽器,不一樣版本的 CSS 前綴。
首先安裝 postcss-loader 和 autoprefixer(自動添加前綴的插件),安裝到你的項目中. npm install --save-dev postcss-loader autoprefixer
編輯 webpack.config.js 文件配置 module 選項,添加 postcss-loader 處理樣式表配置,編輯後的文件以下:
// webpack.config.js module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/dist/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { contentBase: './dist', port: '9000', inline: true, historyApiFallback: true, open: true }, module: { rules: [ { test: /\.json$/, loader: 'json-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ // 編譯打包時排除node_modules文件夾 }, { test: /\.css$/, // 此處結構須要作一下修改 use: [ 'style-loader', 'css-loader?modules&importLoaders=1', { loader: 'postcss-loader', options: { plugins: [ require('autoprefixer') ] } } ] } ] } };
在 webpack-cli 文件夾下新建 postcss.config.js 文件,添加以下代碼:
// postcss.config.js module.exports = { plugins: [ // 調用autoprefixer插件,還能夠配置選項添加須要兼容的瀏覽器版本. require("autoprefixer")[{ browsers: ['ie>=8', '>1% in CN'] }] ] }
如今你寫的樣式會自動根據 Can i use 裏的數據添加不一樣前綴了.在終端中運行 npm start 命令從新編譯打包,終端輸出信息以下:
在瀏覽器中打開 dist 文件夾下的 index.html 文件,若是看到和下圖同樣的,就說明已經成功配置了 PostCSS.
插件(Plugins)
插件(Plugins)是用來拓展 Webpack 功能的,它會在整個構建過程當中生效,執行相關的任務。 Loaders 和 Plugins 經常被弄混,可是他們實際上是徹底不一樣的東西,能夠這麼說,Loaders 是在打包構建過程當中用來處理源文件的(JSX,Scss,Less..),一次處理一個;插件並不直接操做單個文件,它直接對整個構建過程其做用。
Webpack 有不少內置插件,同時也有不少第三方插件,可讓咱們完成更加豐富的功能。
使用插件的方法)使用插件的方法
要使用某個插件,咱們須要經過 npm 安裝它,而後要作的就是在 Webpack 配置中的 Plugins 關鍵字部分添加該插件的一個實例.
編輯 webpack.config.js 文件配置 Plugins 選項,添加一個實現版權聲明的 BannerPlugin 插件,BannerPlugin 是內置插件不須要使用 npm 安裝.
編輯後的文件以下:
// webpack.config.js var webpack = require('webpack'); module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/dist/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { contentBase: './dist', port: '9000', inline: true, historyApiFallback: true, open: true }, module: { rules: [ { test: /\.json$/, loader: 'json-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ // 編譯打包時排除node_modules文件夾 }, { test: /\.css$/, // 此處結構須要作一下修改 use: [ 'style-loader', 'css-loader?modules&importLoaders=1', { loader: 'postcss-loader', options: { plugins: [ require('autoprefixer') ] } } ] } ] }, plugins: [ new webpack.BannerPlugin('版權全部,侵權必究!!!') ] };
在終端中運行 npm start 命令從新編譯打包,在瀏覽器中打開 dist文件夾下的 index.html 文件,若是看到和下圖同樣的,就說明已經成功配置了 BannerPlugin 插件.
經常使用插件
給你們推薦幾個經常使用的插件
HtmlWebpackPlugin
這個插件的做用是依據一個簡單的模板,幫你生成最終的 html 文件,這個文件中自動引用了你打包後的 JS 文件。每次編譯都在文件名中插入一個不一樣的哈希值。
安裝 HtmlWebpackPlugin 到你的項目中 npm install --save-dev html-webpack-plugin
在使用 HtmlWebpackPlugin 以前,須要對 webpack-cli 項目結構作一些改變.
1. 移除 dist文件夾.
2. 在 src目錄下,建立一個文件名爲 index.html 模板文件,在編譯過程當中,HtmlWebpackPlugin 插件會依據此模板生成最終的 html 頁面,會自動添加所依賴的 css、 js、favicon等文件.
index.html 模板文件代碼以下:
// index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>webpack-cli</title> </head> <body> <div id="root"></div> </body> </html>
3. 在 webpack-cli 文件夾下新建一個 build 文件夾用來存放最終的輸出文件.
4. 編輯 webpack.config.js 文件配置 Plugins 選項,添加 HtmlWebpackPlugin 插件,修改 output 選項.編輯後的文件以下:
// webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/build/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { contentBase: './build', port: '9000', inline: true, historyApiFallback: true, open: true }, module: { rules: [ { test: /\.json$/, loader: 'json-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ // 編譯打包時排除node_modules文件夾 }, { test: /\.css$/, // 此處結構須要作一下修改 use: [ 'style-loader', 'css-loader?modules&importLoaders=1', { loader: 'postcss-loader', options: { plugins: [ require('autoprefixer') ] } } ] } ] }, plugins: [//在這個數組中new一個實例就能夠了 new webpack.BannerPlugin('版權全部,侵權必究!!!'), new HtmlWebpackPlugin({ template: __dirname + '/src/index.html' // new一個插件的實例,並傳入相關的參數 }) ] };
此時項目結構以下圖所示:
在終端中運行 npm start 命令從新編譯打包,終端輸出信息以下:
此時項目結構已經發生改變,build 文件夾下存放了最終的輸出的文件,項目結構以下圖所示:
在瀏覽器中打開 build 文件夾下的 index.html 文件,若是看到和下圖同樣的,就說明已經成功配置了 HtmlWebpackPlugin 插件.
Hot Module Replacement
Hot Module Replacement(HMR)也是 Webpack 裏頗有用的一個插件,它容許你在修改組件代碼後,自動刷新實時預覽修改後的效果。 在 Webpack 中使用 HMR 也很簡單,只須要作兩項配置.
- 在 Webpack 配置文件中添加 HMR 插件
- 在 Webpack Dev Server 中添加 hot 參數
不過配置完這些後,JS 模塊其實仍是不能自動熱加載的,還須要在你的 JS 模塊中執行一個 Webpack 提供的 API 才能實現熱加載,雖然這個 API 不難使用,可是若是是 React 模塊,使用咱們已經熟悉的 Babel 能夠更方便的實現功能熱加載。
整理下思路,具體實現方法以下
- Babel 和 Webpack 是獨立的工具,兩者能夠一塊兒工做,兩者均可以經過插件拓展功能.
- HMR 是一個 Webpack 插件,它讓你能瀏覽器中實時觀察模塊修改後的效果,可是若是你想讓它工做,須要對模塊進行額外的配額.
- Babel 有一個叫作 react-transform-hrm 的插件,能夠在不一樣 React 模塊進行額外的配置下讓 HMR 正常工做.
編輯 webpack.config.js 文件配置 Plugins / devServer 選項,添加 Hot Module Replacement 插件.編輯後的文件以下:
// webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/build/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { port: '9000', inline: true, historyApiFallback: true, open: true, hot: true // 熱加載 }, module: { rules: [ { test: /\.json$/, loader: 'json-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ // 編譯打包時排除node_modules文件夾 }, { test: /\.css$/, // 此處結構須要作一下修改 use: [ 'style-loader', 'css-loader?modules&importLoaders=1', { loader: 'postcss-loader', options: { plugins: [ require('autoprefixer') ] } } ] } ] }, plugins: [//在這個數組中new一個實例就能夠了 new webpack.BannerPlugin('版權全部,侵權必究!!!'), new HtmlWebpackPlugin({ template: __dirname + '/src/index.html' // new一個插件的實例,並傳入相關的參數 }), new webpack.HotModuleReplacementPlugin() // 熱加載插件 ] };
編輯 webpack-cli 文件夾下的 package.json 文件 scripts 選項,添加 --hot 選項開啓代碼熱替換.
// package.json { "name": "webpack-cli", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack", "dev": "webpack-dev-server --devtool eval --progress --content-base build --hot" }, "author": "", "license": "ISC", "devDependencies": { "autoprefixer": "^7.1.6", "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-es2015": "^6.24.1", "css-loader": "^0.28.7", "html-webpack-plugin": "^2.30.1", "json-loader": "^0.5.7", "postcss-loader": "^2.0.8", "style-loader": "^0.19.0", "webpack": "^3.8.1", "webpack-dev-server": "^2.9.3" } }
在終端中執行 npm run dev 命令,輸出信息以下圖,同樣能夠啓動自動熱加載.瀏覽器打開界面以下圖:
產品階段的構建
咱們已經使用 Webpack 構建了一個完整的開發環境.可是在產品階段,可能還須要對打包的文件進行額外的處理,好比說優化、壓縮、緩存以及分離 CSS 和 JS.
對於複雜的項目來講,須要複雜的配置,這時候分解配置文件爲多個小的文件可使得事情層次分明,以 webpack-cli 項目來講,咱們在 webpack-cli 文件夾下建立一個名爲 webpack.prod.config.js 的文件,在裏面加上基本的配置代碼,以下:
// webpack.prod.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/build/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, module: { rules: [ { test: /\.json$/, loader: 'json-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ // 編譯打包時排除node_modules文件夾 }, { test: /\.css$/, // 此處結構須要作一下修改 use: [ 'style-loader', 'css-loader?modules&importLoaders=1', { loader: 'postcss-loader', options: { plugins: [ require('autoprefixer') ] } } ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: __dirname + '/src/index.html' // new一個插件的實例,並傳入相關的參數 }) ] };
編輯 webpack-cli 文件夾下的 package.json 文件 scripts 選項,添加 build 選項,編輯後的文件以下:
// package.json { "name": "webpack-cli", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack", "dev": "webpack-dev-server --devtool eval --progress --content-base build --hot", "build": "webpack --config ./webpack.prod.config.js --progress" }, "author": "", "license": "ISC", "devDependencies": { "autoprefixer": "^7.1.6", "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-es2015": "^6.24.1", "css-loader": "^0.28.7", "html-webpack-plugin": "^2.30.1", "json-loader": "^0.5.7", "postcss-loader": "^2.0.8", "style-loader": "^0.19.0", "webpack": "^3.8.1", "webpack-dev-server": "^2.9.3" } }
在終端中執行 npm run build 命令,輸出信息以下圖:
說明分解配置文件爲多個小的文件成功了.
優化插件
Webpack 提供了一些在發佈階段很是有用的優化插件,它們大多來自於 Webpack 社區,能夠經過 npm 安裝,經過如下插件能夠完成產品發佈階段所需的功能.
OccurrenceOrderPlugin: 爲組件分配 ID,經過這個插件 Webpack 能夠分析和優先考慮使用最多的模塊,併爲它們分配最小的 ID.
UglifyJsPlugin:壓縮JS代碼.
ExtractTextPlugin:分離 CSS 和 JS 文件.
咱們來看看如何使用它們,OccurrenceOrderPlugin 和 UglifyJS plugins 都是內置插件,咱們只須要安裝 ExtractTextPlugin 插件.
安裝 ExtractTextPlugin 插件 npm install --save-dev extract-text-webpack-plugin
編輯 webpack.config.js 文件配置 Plugins 選項,添加這三個插件,由於要分離 css 因此還要配置 module 下的 loaders 選項.編輯後的文件以下:
// webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/build/', // 存放打包後文件的路徑 filename: 'bundle.js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { port: '9000', inline: true, historyApiFallback: true, open: true, hot: true // 熱加載 }, module: { rules: [ { test: /\.json$/, loader: 'json-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ // 編譯打包時排除node_modules文件夾 }, { test: /\.css$/, // 此處結構須要作一下修改 use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader?modules!postcss-loader' }) } ] }, plugins: [//在這個數組中new一個實例就能夠了 new webpack.BannerPlugin('版權全部,侵權必究!!!'), new HtmlWebpackPlugin({ template: __dirname + '/src/index.html' // new一個插件的實例,並傳入相關的參數 }), new webpack.HotModuleReplacementPlugin(), // 熱加載插件 new webpack.optimize.OccurrenceOrderPlugin(), new webpack.optimize.UglifyJsPlugin(), new ExtractTextPlugin('style.css') ] };
在終端中執行 npm start 命令,
此時項目結構已經發生改變,build 文件夾下多出了抽離出來的 style.css 文件還有對應的 style.css.map 文件,
若是你打開 build 文件夾下的 bundle.js 文件,就能夠看到 bundle.js 文件內容已經被壓縮處理了.
說明這三個插件已經配置成功了.
緩存
爲了加快加載速度,合理的利用緩存是必不可少的.使用緩存的最好方法是保證文件名和文件內容是匹配的.內容改變,名稱也相應改變.
Webpack 能夠把一個哈希值添加到打包文件的文件名中,添加特殊的字符串混合體([name], [id] and [hash])到輸出文件名前,便於修改 BUG 之後,對應更新用戶本地的緩存文件.
編輯 webpack.config.js 文件修改 output / plugins 選項.編輯後的文件以下:
// webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: __dirname + '/src/main.js', // 入口文件路徑文件所在的目錄. output: { path: __dirname + '/build/', // 存放打包後文件的路徑 filename: '[name]-[hash].js' // 打包後文件名 }, devtool: 'source-map', // 配置生成的source-map devServer: { port: '9000', inline: true, historyApiFallback: true, open: true, hot: true // 熱加載 }, module: { loaders: [ { test: /\.json$/, loader: 'json-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ // 編譯打包時排除node_modules文件夾 }, { test: /\.css$/, // 此處結構須要作一下修改 use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader?modules!postcss-loader' }) } ] }, plugins: [//在這個數組中new一個實例就能夠了 new webpack.BannerPlugin('!!!!!!!'), new HtmlWebpackPlugin({ template: __dirname + '/src/index.html' // new一個插件的實例,並傳入相關的參數 }), new webpack.HotModuleReplacementPlugin(), // 熱加載插件 new webpack.optimize.OccurrenceOrderPlugin(), new webpack.optimize.UglifyJsPlugin(), new ExtractTextPlugin('[name]-[hash].css') ] };
在終端中執行 npm start 命令,輸出信息
此時項目 build 文件夾下的 main.css 和 main.js 文件都對應的加上了哈希值.
若是你打開 build 文件夾下的 index.html 文件,就能夠看到引用的 css、js 文件名也對應發生了改變,這樣修改 BUG 之後,也能對應更新用戶本地的緩存文件.