閱讀目錄css
1.webpack配置瞭解html
webpack的配置文件是一個nodejs的module,使用CommonJS風格來編寫的,好比以下:node
module.exports = { entry: './index', output: { path: __dirname + '/dist', filename: 'bundle.js' } }
webpack的配置文件能夠隨便命名,默認爲 webpack.config.js,所以在項目的根目錄下,直接運行 webpack就能夠進行打包,可是也能夠對webpack命名爲其餘的名字,好比把它放入 build/webpack.dev.js ,代碼目錄結構以下:jquery
### 目錄結構以下: demo # 工程名 | |--- dist # 打包後生成的目錄文件 | |--- node_modules # 全部的依賴包 | |--- src # 項目的文件包 | | |--- pages # 存放全部頁面的文件 | | | |--- page1 | | | | |--- index.html # 第一個頁面的html文件 | | | | |--- index.styl # 第一個頁面的css文件 | | | | |--- index.js # 第一個頁面的js文件 | | | |--- page2 | | | | |--- index.html # 第二個頁面的html文件 | | | | |--- index.styl # 第二個頁面的css文件 | | | | |--- index.js # 第二個頁面的js文件 | |--- build | | |--- webpack.base.js # webpack 基本配置文件 | | |--- webpack.dev.js # 開發文件 | | |--- webpack.build.js # 打包線上文件 | |--- .gitignore | |--- README.md | |--- package.json
所以咱們在package.json 配置文件以下:webpack
"scripts": { "dev": "node build/webpack.dev.js", "build": "node build/webpack.build.js" }
進入項目的根目錄後,運行 npm run dev 便可進行打包。git
1.1) 入口文件配置 entry參數github
entry入口文件能夠是字符串的單入口文件,也能夠是數組的多入口文件,可是咱們最多見的是一個對象的方式來組織入口文件。所以object中的key在webpack裏至關於入口的name,能夠用來生成文件的路徑,也可使用來爲此入口惟一的標識。
好比以下:web
entry: { 'page1': path.resolve(__dirname, '../src/pages/page1'), 'page2': path.resolve(__dirname, '../src/pages/page2') }
假如頁面上有多個入口的話,這樣一個個寫比較麻煩,所以能夠寫一個函數以下:正則表達式
/* 獲取項目中多個入口文件 */ function getEntries(paths) { // node 中同步獲取文件列表 var files = glob.sync(paths), entries = {}; files.forEach(function(filepath) { var toArray = filepath.split('/'); var filename = toArray[toArray.length - 2]; entries[filename] = filepath; }); return entries; } var entries = getEntries('./src/pages/*/index.js'); Object.keys(entries).forEach(function(name) { entry[name] = entries[name] });
1.2) 輸出文件:out參數npm
output參數是告訴webpack以什麼方式來生成/輸出文件,output有幾個經常使用的參數如:path, publicPath, filename, chunkFilename, 以下代碼:
output: { path: path.resolve(__dirname, '../dist'), publicPath: '/assets/', // 供插件在生產模式下更新內嵌到css、html文件裏的相對路徑url值 filename: 'static/js/[name].js', chunkFilename: '[id].bundle.js', }
1.3) path參數
path參數表示生成文件的根目錄,須要傳入一個絕對路徑,如:path.resolve(__dirname, '../dist'),會解析成 /項目的根目錄下/dist文件, path參數和filename參數會共同組成入口文件的完整路徑。
1.4) publicPath
該參數表示的是一個URL路徑(指向生成文件的根目錄),能夠用於css/js/images/font文件等資源的路徑,能夠確保網頁正確的加載到這些資源文件。
1.5) publicPath參數 和 path參數的區別:
path參數是針對本地文件系統的,可是publicPath則針對的是瀏覽器,它既能夠是一個相對路徑,好比 '../../dist', 也能夠是一個絕對路徑,好比:'http://www.xxx.com/', 那麼何時使用相對路徑呢?何時使用絕對路徑呢?若是是引用本項目下的文件,最好使用相對路徑,若是是引用跨項目的文件,須要使用絕對路徑。
1.6) filename
filename屬性表示的是如何命名生成的入口文件,能夠有以下規則:
1. [name], 指代入口文件的name,也就是上面的entry中的key。
2. [hash] 指代本次編譯的一個hash版本,可是請注意,只要在同一次編譯過程當中生成的文件,這個[hash]值就是同樣的,每一次編譯,hash值都是同樣,也就是說不存在緩存文件,只要一編譯全部的hash
都會改變。
3. [chunkhash] 指代當前chunk的一個hash版本,也就是說,在每次編譯過程當中,每個chunk的hash都是不同的,若是某個chunk沒有發生變化,那麼該chunk的hash也不會發生變化,也就是能夠理解若是頁面的文件沒有發生改變,那麼chunk的hash也不會發生改變,所以未改變的文件會在緩存中讀取。
1.7) chunkFilename
chunkFilename 參數 與 filename參數相似,都是用來定義生成的命名方式的,只不過,chunkFilename參數指定的是除了入口文件外的chunk。
1.8) module參數中的 rules 配置(其實rules就至關於以前的loaders):
module: { rules: [ { test: /\.js$/, include: [ path.resolve(__dirname, 'src/pages/**/*.js') ], exclude: /(node_modules)/, // 排除node_modules 文件 use: { loader: 'babel-loader', options: { presets: ['es2015'], plugins: ['transform-runtime'] } } } ] }
下面對一些子參數進行說明:
test: test實際上是一個使用正則表達式匹配文件的一種方式,好比上面的是,匹配以 .js結尾的文件。
include: 用來表示本rules 配置是針對那些目錄/文件,好比上面的代碼配置是針對 src/pages/ 下的全部js文件的。
exclude: 是用來排除掉那些文件的,好比上面的是 /(node_modules)/ 的意思是 排除掉 node_modules下的js文件的。
use: 使用到的loader的配置
use 下的 loader: 使用加載器名稱。
options: 該參數是爲當前loader設置的參數,對於babel也能夠單獨放在 .babelrc文件中,也就是說該參數能夠在項目的根目錄不包含.babelrc文件,把.babelrc文件移到該配置項來便可。
2.webpack CommonsChunkPlugin公共代碼剝離
與單頁應用相比,多頁應用存在多個入口(每一個頁面即一個入口),每一個入口意味着一套完整的js代碼(包括業務邏輯和加載第三方庫、框架)。而後在每一個頁面中分別加載該文件便可,
CommonsChunkPlugin: 該插件是一個可選用於創建一個獨立文件(chunk), 這個文件包括多個入口的chunk的公共模塊,經過將公共模塊拆出來,最終合成的文件可以在最開始的時候加載一次,便存到緩存中,供後續使用,優勢是:會帶來速度的提高,由於瀏覽器會迅速將公共的代碼從緩存中提取出來
,而不是每次訪問一個新頁面時候,再去加載一個更大的文件。
CommonsChunkPlugin 初始化有哪些參數?
name: 給這個包含公共代碼的chunk命名。
filename: 命名打包後生成的js文件。
minChunks 公共代碼的判斷標準:某個js模塊被多少個chunk(入口文件)加載了纔算是公共代碼。
chunks,表示須要在哪些chunk(配置中entry的每一項)裏尋找公共代碼進行打包,默認不設置,那麼它的提取範圍爲全部的chunk。
下面是一個簡單的CommonsChunkPlugin的實列含義:
var commonsChunkPlugin = new webpack.optimize.CommonsChunkPlugin = ({ name: 'vender', // 這公共代碼的chunk命名爲 'vender' filename: '[name].bundle.js', // 生成的文件名爲 vender.bundle.js minChunks: 2, // 設定要有2個chunk(即2個頁面)加載的js模塊纔會被歸入公共代碼。 chunks: ['pageA', 'pageB'], // 只使用這些入口的 chunk }) var commonsChunkPlugin = new webpack.optimize.CommonsChunkPlugin = ({ name: 'vender', // 這公共代碼的chunk命名爲 'vender' // filename: '[name].bundle.js', // 生成的文件名爲 vender.bundle.js minChunks: Infinity, // 隨着入口chunk愈來愈多,這個配置保證沒其餘的模塊會打包進 公共的chunk })
下面是使用對 webpack CommonsChunkPlugin 詳解的demo:
### 目錄結構以下: demo # 工程名 | |--- dist # 打包後生成的目錄文件 | |--- node_modules # 全部的依賴包 | |--- src # 項目的文件包 | | |--- common | | | |---css # 公用頁面的css文件 | | | |---js # 公用頁面的js文件 | | |--- libs | | | |--- jquery.js # 第三方庫文件 | | |--- main.js # 入口文件 | |--- .gitignore | |--- README.md | |--- index.html # 首頁文件 | |--- package.json | |--- webpack.config.js # 配置文件 | |--- webpack.production.config.js # 上線打包配置文件
1.1) 未使用 CommonsChunkPlugin 打包狀況下
webpack.config.js 代碼以下:
// 導入路徑包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { //開啓sourceMap便於調試 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js' }, output: { // 輸出文件到當前目錄下的 build文件夾內 path: path.resolve(__dirname, 'build'), publicPath: '/assets/', //指定資源文件引用的目錄 filename: 'bundle.js' // 文件名爲 bundle.js //filename: '[name].js' // 能夠打包爲多個文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模塊 module: { /* * 在webpack2.0版本已經將 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同時鏈式loader(用!鏈接)只適用於module.loader,同時-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 設置css模塊化,詳情參考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 參考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //須要排除的目錄 } ] }, // 配置devServer各類參數 devServer: { // contentBase: "./", // 本地服務器所加載的頁面所在的目錄 hot: true, // 配置HMR以後能夠選擇開啓 historyApiFallback: true, // 不跳轉 inline: true // 實時刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 熱加載插件 ] }
main.js代碼以下:
require('./common/css/style.css'); import './common/css/stylus.styl'; require('./libs/jquery.js');
運行命令 npm run start 能夠看到打包後的文件 bundle.js 代碼內 包含第三方jquery框架的源碼。
1.2)使用CommonsChunkPlugin
單一入口文件,分文件輸出
webpack.config.js 代碼以下:
// 導入路徑包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //開啓sourceMap便於調試 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js' }, output: { // 輸出文件到當前目錄下的 build文件夾內 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能夠打包爲多個文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模塊 module: { /* * 在webpack2.0版本已經將 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同時鏈式loader(用!鏈接)只適用於module.loader,同時-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 設置css模塊化,詳情參考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 參考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //須要排除的目錄 } ] }, // 配置devServer各類參數 devServer: { // contentBase: "./", // 本地服務器所加載的頁面所在的目錄 hot: true, // 配置HMR以後能夠選擇開啓 historyApiFallback: true, // 不跳轉 inline: true // 實時刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 熱加載插件 new CommonsChunkPlugin({ name: 'chunk', filename: 'chunk.js' // 把公用的 webpackJsonp 打包到chunk.js 裏面去 }) ] }
main.js 代碼以下:
require('./common/css/style.css'); import './common/css/stylus.styl'; require('./common/js/test.js'); require('./common/js/test2.js'); require('./libs/jquery.js');
輸出文件 chunk.js 和 main.js , chunk.js 是把公用的webpackJsonp打包到 chunk.js 代碼裏面去了。
可是 test.js 和 test2.js 及 jquery.js 被打包到 main.js 裏面去了。
如今咱們能夠將 test.js 和 test2.js 打包到chunk.js , 以下webpack配置代碼以下:
// 導入路徑包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //開啓sourceMap便於調試 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js', chunk: ['./src/common/js/test.js', './src/common/js/test2.js'] }, output: { // 輸出文件到當前目錄下的 build文件夾內 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能夠打包爲多個文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模塊 module: { /* * 在webpack2.0版本已經將 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同時鏈式loader(用!鏈接)只適用於module.loader,同時-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 設置css模塊化,詳情參考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 參考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //須要排除的目錄 } ] }, // 配置devServer各類參數 devServer: { // contentBase: "./", // 本地服務器所加載的頁面所在的目錄 hot: true, // 配置HMR以後能夠選擇開啓 historyApiFallback: true, // 不跳轉 inline: true // 實時刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 熱加載插件 new CommonsChunkPlugin({ name: 'chunk', filename: 'chunk.js' // 把公用的 webpackJsonp 打包到chunk.js 裏面去 }) ] }
1.3) 單一入口,模塊重複引用,最終把相同的模塊打包到 入口文件內。
webpack.config.js 配置以下:
// 導入路徑包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //開啓sourceMap便於調試 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js' }, output: { // 輸出文件到當前目錄下的 build文件夾內 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能夠打包爲多個文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模塊 module: { /* * 在webpack2.0版本已經將 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同時鏈式loader(用!鏈接)只適用於module.loader,同時-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 設置css模塊化,詳情參考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 參考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //須要排除的目錄 } ] }, // 配置devServer各類參數 devServer: { // contentBase: "./", // 本地服務器所加載的頁面所在的目錄 hot: true, // 配置HMR以後能夠選擇開啓 historyApiFallback: true, // 不跳轉 inline: true // 實時刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 熱加載插件 new CommonsChunkPlugin({ name: 'chunk', minChunks: 2 }) ] }
main.js 代碼以下:
require('./common/css/style.css'); import './common/css/stylus.styl'; require('./common/js/test'); require('./common/js/test2'); test.js代碼以下: require('./test2'); var test1 = 11; exports.test1 = test1;
test2模塊被引用了兩次打包,可是最終模塊被打包到main.js裏面去了,minChunks: 2 的含義是 至少入口文件引用2個相同的模塊會被打包到main.js 裏面去。
1.4) 多入口,模塊重複引用,將多個引用的模塊被打包到公共模塊。以下webpack.config.js代碼:
// 導入路徑包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //開啓sourceMap便於調試 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js', main2: './src/main2.js', }, output: { // 輸出文件到當前目錄下的 build文件夾內 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能夠打包爲多個文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模塊 module: { /* * 在webpack2.0版本已經將 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同時鏈式loader(用!鏈接)只適用於module.loader,同時-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 設置css模塊化,詳情參考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 參考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //須要排除的目錄 } ] }, // 配置devServer各類參數 devServer: { // contentBase: "./", // 本地服務器所加載的頁面所在的目錄 hot: true, // 配置HMR以後能夠選擇開啓 historyApiFallback: true, // 不跳轉 inline: true // 實時刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 熱加載插件 new CommonsChunkPlugin({ name: 'chunk', minChunks: 2 }) ] }
main.js代碼以下:
require('./common/css/style.css'); import './common/css/stylus.styl'; require('./common/js/test'); require('./common/js/test2'); main2.js代碼以下: var test1 = require('./common/js/test'); var test2 = require('./common/js/test2'); console.log(test1); console.log(test2);
如上代碼: main.js 和 main2.js 都引用了 test.js 和 test2.js,打包後,test.js和 test2.js 被打包到 chunk.js內。 minChunks的含義是:至少引用了
2個相同的模塊纔會被打包到 chunk.js裏面去。默認爲2.
1.5)將第三方業務框架分開打包。
webpack.config.js 代碼以下:
// 導入路徑包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //開啓sourceMap便於調試 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js', main2: './src/main2.js', jquery: ['./src/libs/jquery.js'] }, output: { // 輸出文件到當前目錄下的 build文件夾內 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能夠打包爲多個文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模塊 module: { /* * 在webpack2.0版本已經將 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同時鏈式loader(用!鏈接)只適用於module.loader,同時-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 設置css模塊化,詳情參考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 參考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //須要排除的目錄 } ] }, // 配置devServer各類參數 devServer: { // contentBase: "./", // 本地服務器所加載的頁面所在的目錄 hot: true, // 配置HMR以後能夠選擇開啓 historyApiFallback: true, // 不跳轉 inline: true // 實時刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 熱加載插件 new CommonsChunkPlugin({ name: ['chunk', 'jquery'], minChunks: 2 }) ] }
上面打包後 在頁面上 會先加載 jquery.js,該模塊包含了全部的模塊文件,包括webpackJSon依賴代碼,而後就是加載chunk.js,最後就是 main.js 和 main2.js了。
注意:webpack使用插件 CommonsChunkPlugin進行打包的時候,將符合引用次數的(minChunks)的模塊打包到name參數的數組的第一個塊內(chunk), 而後數組裏面的依次打包,(查找entry裏面的key), CommonsChunkPlugin中的最後一個塊包含webpack生成的在瀏覽器上使用各個塊的加載代碼,
因此頁面上使用的時候最後一個塊必須先加載。
因此咱們在頁面上會先看到先 加載 jquery.js ,查看該代碼就會看到包含全部的代碼,而後加載chunk.js代碼,最後就是main.js和main2.js代碼了。
1.6)minChunks: infinity
webpack.config.js代碼以下:
// 導入路徑包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //開啓sourceMap便於調試 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js', main2: './src/main2.js', jquery: ['./src/libs/jquery.js'], }, output: { // 輸出文件到當前目錄下的 build文件夾內 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能夠打包爲多個文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模塊 module: { /* * 在webpack2.0版本已經將 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同時鏈式loader(用!鏈接)只適用於module.loader,同時-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 設置css模塊化,詳情參考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 參考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //須要排除的目錄 } ] }, // 配置devServer各類參數 devServer: { // contentBase: "./", // 本地服務器所加載的頁面所在的目錄 hot: true, // 配置HMR以後能夠選擇開啓 historyApiFallback: true, // 不跳轉 inline: true // 實時刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 熱加載插件 new CommonsChunkPlugin({ name: 'jquery', minChunks: 2 }) ] }
main.js 代碼以下:
require('./common/css/style.css'); import './common/css/stylus.styl'; require('./common/js/test'); require('./common/js/test2');
main2.js代碼以下:
var test1 = require('./common/js/test'); var test2 = require('./common/js/test2'); console.log(test1); console.log(test2);
運行代碼後 發現main.js和 main2.js共同也能用的代碼 test.js和 test2.js 代碼被打包到jquery.js裏面去了。
當把 上面的 webpack.config.js的代碼 minChunks 修改成 minChunks: Infinity 後, test.js 和 test2.js代碼都被打包到 main.js和main2.js代碼內了。
1.7)參數chunks
webpack.config.js 代碼以下:
// 導入路徑包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //開啓sourceMap便於調試 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js', main2: './src/main2.js', jquery: ['./src/libs/jquery.js'], }, output: { // 輸出文件到當前目錄下的 build文件夾內 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能夠打包爲多個文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模塊 module: { /* * 在webpack2.0版本已經將 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同時鏈式loader(用!鏈接)只適用於module.loader,同時-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 設置css模塊化,詳情參考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 參考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //須要排除的目錄 } ] }, // 配置devServer各類參數 devServer: { // contentBase: "./", // 本地服務器所加載的頁面所在的目錄 hot: true, // 配置HMR以後能夠選擇開啓 historyApiFallback: true, // 不跳轉 inline: true // 實時刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 熱加載插件 new CommonsChunkPlugin({ name: 'jquery', minChunks: 2, chunks: ['main', 'main2'] }) ] }
chunks 代碼 包含['main', 'main2'],的含義是 都引用的模塊纔會打包到公用的模塊 (jquery)內。
3.瞭解ProvidePlugin的用途
該插件的做用是 自動加載模塊,典型的列子:好比自動加載jquery,首先須要使用 npm install --save jquery 後,在webpack.config.js 加以下配置:
config.plugins.push( new Webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }));
這樣配置完成後,咱們在index.js 能夠直接使用 $ 和 jQuery了,如:console.log(jQuery('body'));
3.2) 添加hash
每次打完包後,咱們看到 都會生成三個文件,分別是manifest.js, vendor.js. 和 頁面上的業務js,manifest 是業務模塊全部須要依賴的js,好比:webpackJsonp,而vendor.js 咱們這邊打包成第三方框架或庫,咱們這邊是
jquery,每次打包後都會生成這三個文件,可是文件名都是同樣的,瀏覽器可能緩存上一次的結果而沒法加載最新的數據。所以咱們須要添加 hash。
爲了解決上述問題,咱們須要爲打包後的文件名添加hash值,這樣每次修改後打包的hash文件值將會發生改變,瀏覽器會從服務器端下載最新的文件。
基本配置以下:
module.exports = { output: { path: path.resolve(__dirname, '../dist'), publicPath: '', filename: isLine ? 'static/js/[name].[chunkhash:5].js' : 'static/js/[name].js' } }
上面的代碼 首先判斷是不是在線上環境仍是平常環境,若是是在線上打包的話,添加 [chunkHash:5]變量,表示打包後的文件中加入5位的hash值。
3.3) 修改 vendor配置
上面解決瀏覽器緩存問題後,每次打包生成一個新的5位的hash編碼值,可是問題又來了,當我修改某一個js文件的時候,vendor.js的hash值也跟着改變了,咱們明白 vendor是咱們打包第三方庫jquery的,jquery我並無改動,
爲了解決上面的問題,咱們須要使用 CommonsChunkPlugin 插件來配置;以下:
module.exports = { new Webpack.optimize.CommonsChunkPlugin({ name: ['vendor','manifest'], minChunks: 2 }) };
vendor.js 是打包庫文件,而manifest.js 是打包模塊中依賴的文件,當某個js文件發生改變的話,manifest是頁面加載時啓動文件,因此hash值會發生改變。而vendor代碼被抽取出來後做爲一個單獨文件,源碼沒有改動的話,所以hash值就不會發生改變了。
webpack 多頁應用架構系列實戰git代碼