一、多個入口文件
之前我們配置的都是 一個入口
var webpack = require('webpack'); var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js'); module.exports = { //頁面入口文件配置 entry: { index: './src/index.js' }, //入口文件輸出配置 output: { path: path.join(__dirname, "dist/"), filename: "bundle.js" } };
但是有的 時候我們需要多個入口文件,這個時候該如何配置?
entry 參數支持設置對象,可以設置多個入口文件,這個時候output的filename就不能是固定名字 了,因為入口是多個文件,所以 同時也要修改 output參數:
var webpack = require('webpack'); var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js'); module.exports = { //頁面入口文件配置 entry: { app: ['./src/index.js'], login: ['./src/login.js'] }, //入口文件輸出配置 output: { path: path.join(__dirname, "dist/"), filename: "bundle_[name].js" } };
這里的filename: "bundle_[name].js" 中的[name]是一個 正則表達式匹配的,這里的[name]名字指的是鍵值對的鍵,上面的實例中第一個入口文件是app: ['./src/index.js'],[name]名字對應的是app而不是index。運行一下webapck命令就會在dist生成bundle_app.js和bundle_login.js兩個文件
二、plugins插件
常用Plugins介紹
-
代碼熱替換, HotModuleReplacementPlugin
-
生成html文件,HtmlWebpackPlugin
-
將css成生文件,而非內聯,ExtractTextPlugin
-
報錯但不退出webpack進程,NoErrorsPlugin
-
代碼丑化,UglifyJsPlugin,開發過程中不建議打開
-
多個 html共用一個js文件(chunk),可用CommonsChunkPlugin
-
清理文件夾,Clean
-
調用模塊的別名ProvidePlugin,例如想在js中用$,如果通過webpack加載,需要將$與jQuery對應起來
1、CommonsChunkPlugin抽取公共資源
CommonsChunkPlugin 常用參數:
name:與 entry 中的鍵對應 filename:公共文件的輸出名字 minChunks :公共模塊被使用的最小次數。比如配置為3,也就是同一個模塊只有被3個以外的頁面同時引用時才會被提取出來作為common chunks。 minSize:作用類似於minChunks,只不過這里控制的文件大小。
項目中可能會使用很多的第三方插件,如果把所有的插件和自己的js文件,打包成一個js文件,這樣網頁加載會很慢,並且在優化方面完全可以把第三方插件進行單獨的緩存。這個時候就需要把所有的第三方插件單獨 打包 為一個js包。CommonsChunkPlugin插件就可以幫助我們實現這個功能。
CommonsChunkPlugin是一個對象,所以使用的時候要 進行實例化
new webpack.optimize.CommonsChunkPlugin('common.js')
CommonsChunkPlugin的參數支持字符串和json
下面我們在webpackDemo中實現CommonsChunkPlugin功能,首先我們通過npm安裝 jquery和moment第三方插件:
npm install jquery --save npm install moment --save
接下來在webpack.config.js文件配置CommonsChunkPlugin
var webpack = require('webpack'); var WebpackDevServer = require("webpack-dev-server"); var path = require('path'); var CURRENT_PATH = path.resolve(__dirname); // 獲取到當前目錄 var ROOT_PATH = path.join(__dirname, '../'); // 項目根目錄 var MODULES_PATH = path.join(ROOT_PATH, './node_modules'); // node包目錄 var BUILD_PATH = path.join(ROOT_PATH, './dist'); // 最后輸出放置公共資源的目錄 module.exports = { //項目的文件夾 可以直接用文件夾名稱 默認會找index.js ,也可以確定是哪個文件名字 entry: { app: ['./src/index.js'], login: ['./src/login.js'], vendors: ['jquery', 'moment'] //需要打包的第三方插件 }, //輸出的文件名,合並以后的js會命名為bundle.js output: { path: path.join(__dirname, "dist/"), publicPath: "http://localhost:8088/dist/", filename: "bundle_[name].js" }, devServer: { historyApiFallback: true, contentBase: "./", quiet: false, //控制台中不輸出打包的信息 noInfo: false, hot: true, //開啟熱點 inline: true, //開啟頁面自動刷新 lazy: false, //不啟動懶加載 progress: true, //顯示打包的進度 watchOptions: { aggregateTimeout: 300 }, port: '8088' //設置端口號 }, plugins: [ //new webpack.HotModuleReplacementPlugin() //提取公共部分資源 new webpack.optimize.CommonsChunkPlugin({ // 與 entry 中的 vendors 對應 name: 'vendors', // 輸出的公共資源名稱 filename: 'common.bundle.js', // 對所有entry實行這個規則 minChunks: Infinity }), ], devtool: 'source-map' };
index.html
由於進行了公共資源的提取,所以頁面上 要引入公共部分js文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <h1 id="welcome">welcome to 68kejian.com</h1> <script src="dist/common.bundle.js"></script> <script src="dist/bundle_app.js"></script> </body> </html>
index.js
var login=require('./login'); var $=require('jquery');//引用jquery模塊 $("#welcome").html(login.sayName());
login.js
var userName="68kejian"; module.exports.userName=userName; module.exports.sayName=function(){ return userName; };
這個時候運行webpack執行命令在dist目錄下面就會生成如下js文件:
2、ProvidePlugin全局掛載插件
ProvidePlugin插件主要是進行設置全局模塊,比如jquery插件幾乎所有的頁面都用到,使用require('jquery')引用寫起來比較多,這個時候就可以使用ProvidePlugin 把jquery設置為全局的, 每個頁面就可以 直接使用了。
plugins: [ //new webpack.HotModuleReplacementPlugin() //提取公共部分資源 new webpack.optimize.CommonsChunkPlugin({ // 與 entry 中的 vendors 對應 name: 'vendors', // 輸出的公共資源名稱 filename: 'common.bundle.js', // 對所有entry實行這個規則 minChunks: Infinity }), // 把jquery作為全局變量插入到所有的代碼中 // 然后就可以直接在頁面中使用jQuery了 new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery' }), ],
index.js
var login=require('./login'); var data = require('data'); $("#welcome").html(data);
3、自動生成html插件html-webpack-plugin
html-webpack-plugin不是webpack的內置插件所以需要單獨安裝
npm install html-webpack-plugin --save-dev
html-webpack-plugin插件默認會在打包根目錄生成一個index.html頁面, 通過相關參數 可以定義輸出名字以及其它的相關配置,下面我們看一下相關的參數:
new HtmlWebpackPlugin({ title: 'My App',//設置title的名字 filename: 'admin.html',//設置這個html的文件名 template:'header.html',//要使用的模塊的路徑 inject: 'body',//把模板注入到哪個標簽后 'body' favicon:'./images/favico.ico',//給html添加一個favicon './images/favico.ico' minify:true,//是否壓縮 true false hash:true,//是否hash化 true false , cache:false,//是否緩存, showErrors:false,//是否顯示錯誤, xhtml:false //是否自動關閉標簽 默認false })
下面我們在webpackDemo項目中加入 這個插件:
var webpack = require('webpack'); var WebpackDevServer = require("webpack-dev-server"); var path = require('path'); var CURRENT_PATH = path.resolve(__dirname); // 獲取到當前目錄 var ROOT_PATH = path.join(__dirname, '../'); // 項目根目錄 var MODULES_PATH = path.join(ROOT_PATH, './node_modules'); // node包目錄 var BUILD_PATH = path.join(ROOT_PATH, './dist'); // 最后輸出放置公共資源的目錄 var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { //項目的文件夾 可以直接用文件夾名稱 默認會找index.js ,也可以確定是哪個文件名字 entry: { app: ['./src/js/index.js'], vendors: ['jquery', 'moment'] //需要打包的第三方插件 }, //輸出的文件名,合並以后的js會命名為bundle.js output: { path: path.join(__dirname, "dist/"), publicPath: "http://localhost:8088/dist/", filename: "bundle_[name].js" }, devServer: { historyApiFallback: true, contentBase: "./", quiet: false, //控制台中不輸出打包的信息 noInfo: false, hot: true, //開啟熱點 inline: true, //開啟頁面自動刷新 lazy: false, //不啟動懶加載 progress: true, //顯示打包的進度 watchOptions: { aggregateTimeout: 300 }, port: '8088' //設置端口號 }, plugins: [ new webpack.HotModuleReplacementPlugin() //提取公共部分資源 new webpack.optimize.CommonsChunkPlugin({ // 與 entry 中的 vendors 對應 name: 'vendors', // // 輸出的公共資源名稱 filename: 'common.bundle.js', // 對所有entry實行這個規則 minChunks: Infinity }), // 把jquery作為全局變量插入到所有的代碼中 // 然后就可以直接在頁面中使用jQuery了 new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery' }), //生成index.html頁面 new HtmlWebpackPlugin({ title: '68kejian.com', filename: 'index.html', template: 'header.html', inject: 'body', favicon: './images/favico.ico', minify: false, hash: true, cache: false, showErrors: false }) ], externals: { // require('data') is external and available // on the global var data // 'data': 'data' }, devtool: 'source-map' };
header.html
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> </body> </html>
可以看到htmlWebpackPlugin里面的對象通過<%= htmlWebpackPlugin.options.title %>可以打印到頁面里面。
運行webpack命令,就會在dist 目錄生成了index.html頁面
通過截圖可以看到html-webpack-plugin會把生成的js文件自動插入到頁面中去。
4、提取樣式插件extract-text-webpack-plugin
我們 知道webpack使用require()方法可以引用css文件和圖片,但是由於它們不像js文件准尋CMD格式, 所有在使用的時候需要通過加載器進行處理。 需要用到兩個基本的加載器:css-loader、style.lader,所謂加載器就是一個處理器,它們會把 相關的文件處理為webpack可以使用的規范。加載器不是webpack內置,所有需要npm進行安裝,同時,extract-text-webpack-plugin也需要單獨安裝。
npm install extract-text-webpack-plugin --save-dev
npm install css-loader style-loader less-loader
下面是相關配置:
var webpack = require('webpack'); var WebpackDevServer = require("webpack-dev-server"); var path = require('path'); var CURRENT_PATH = path.resolve(__dirname); // 獲取到當前目錄 var ROOT_PATH = path.join(__dirname, '../'); // 項目根目錄 var MODULES_PATH = path.join(ROOT_PATH, './node_modules'); // node包目錄 var BUILD_PATH = path.join(ROOT_PATH, './dist'); // 最后輸出放置公共資源的目錄 var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { //項目的文件夾 可以直接用文件夾名稱 默認會找index.js ,也可以確定是哪個文件名字 entry: { app: ['./src/js/index.js'], vendors: ['jquery', 'moment'] //需要打包的第三方插件 }, //輸出的文件名,合並以后的js會命名為bundle.js output: { path: path.join(__dirname, "dist/"), publicPath: "http://localhost:8088/dist/", filename: "bundle_[name].js" }, devServer: { historyApiFallback: true, contentBase: "./", quiet: false, //控制台中不輸出打包的信息 noInfo: false, hot: true, //開啟熱點 inline: true, //開啟頁面自動刷新 lazy: false, //不啟動懶加載 progress: true, //顯示打包的進度 watchOptions: { aggregateTimeout: 300 }, port: '8088' //設置端口號 }, module: { loaders: [ // 把之前的style&css&less loader改為 { test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader'), exclude: /node_modules/ }, { test: /\.less$/, loader: ExtractTextPlugin.extract('style', 'css!less'), exclude: /node_modules/ }, ] }, plugins: [ new webpack.HotModuleReplacementPlugin() //提取公共部分資源 new webpack.optimize.CommonsChunkPlugin({ // 與 entry 中的 vendors 對應 name: 'vendors', // 輸出的公共資源名稱 filename: 'common.bundle.js', // 對所有entry實行這個規則 minChunks: Infinity }), // 把jquery作為全局變量插入到所有的代碼中 // 然后就可以直接在頁面中使用jQuery了 new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery' }), //生成index.html頁面 new HtmlWebpackPlugin({ title: '68kejian', filename: 'index.html', template: 'header.html', inject: 'body', favicon: './images/favico.ico', minify: false, hash: true, cache: false, showErrors: false }), // 分離css new ExtractTextPlugin('[name].bundle.css', { allChunks: true }), ], externals: { // require('data') is external and available // on the global var data // 'data': 'data' }, devtool: 'source-map' };
代碼詳解:
module: { loaders: [ // 把之前的style&css&less loader改為 { test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader'), exclude: /node_modules/ }, { test: /\.less$/, loader: ExtractTextPlugin.extract('style', 'css!less'), exclude: /node_modules/ }, ] }
module對象用來設置加載器的相關配置, loader就是所有加載器的數組。設置加載器的參數如下:
test: /\.css$/,//文件類型,在整個項目 目錄 loader: ExtractTextPlugin.extract('style-loader', 'css-loader'),//使用的加載器 exclude: /node_modules/ //排除的目錄
ExtractTextPlugin插件的使用和其他的一樣,引用、實例化然后在plugins配置。執行webpack命令就會把所有的 js里面引用的css文件抽取到一個css文件里面。
5、拷貝資源插件copy-webpack-plugin
官方這樣解釋 Copy files and directories in webpack ,在webpack中拷貝文件和文件夾。
需要安裝
npm install --save-dev copy-webpack-plugin
相關參數:
from : 定義要拷貝的源目錄 __dirname + ‘/src/public’ to : 定義要拷貝的目標目錄 __dirname + ‘/dist’ toType : file 或者 dir , 可選,默認是文件 force : 強制覆蓋先前的插件 , 可選 默認false context : 不知道作用 , 可選 默認 base context 可用 specific context flatten :只拷貝文件不管文件夾 , 默認是false ignore : 忽略拷貝指定的文件 ,可以用模糊匹配
下面我們對webpackDemo增加一個復制 圖片的配置
var webpack = require('webpack'); var WebpackDevServer = require("webpack-dev-server"); var path = require('path'); var CURRENT_PATH = path.resolve(__dirname); // 獲取到當前目錄 var ROOT_PATH = path.join(__dirname, '../'); // 項目根目錄 var MODULES_PATH = path.join(ROOT_PATH, './node_modules'); // node包目錄 var BUILD_PATH = path.join(ROOT_PATH, './dist'); // 最后輸出放置公共資源的目錄 var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); var CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = { //項目的文件夾 可以直接用文件夾名稱 默認會找index.js ,也可以確定是哪個文件名字 entry: { app: ['./src/js/index.js'], vendors: ['jquery', 'moment'] //需要打包的第三方插件 }, //輸出的文件名,合並以后的js會命名為bundle.js output: { path: path.join(__dirname, "dist/"), publicPath: "http://localhost:8088/dist/", filename: "bundle_[name].js" }, devServer: { historyApiFallback: true, contentBase: "./", quiet: false, //控制台中不輸出打包的信息 noInfo: false, hot: true, //開啟熱點 inline: true, //開啟頁面自動刷新 lazy: false, //不啟動懶加載 progress: true, //顯示打包的進度 watchOptions: { aggregateTimeout: 300 }, port: '8088' //設置端口號 }, module: { loaders: [ // 把之前的style&css&less loader改為 { test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader'), exclude: /node_modules/ }, { test: /\.less$/, loader: ExtractTextPlugin.extract('style', 'css!less'), exclude: /node_modules/ }, ] }, plugins: [ new webpack.HotModuleReplacementPlugin() //提取公共部分資源 new webpack.optimize.CommonsChunkPlugin({ // 與 entry 中的 vendors 對應 name: 'vendors', // 輸出的公共資源名稱 filename: 'common.bundle.js', // 對所有entry實行這個規則 minChunks: Infinity }), // 把jquery作為全局變量插入到所有的代碼中 // 然后就可以直接在頁面中使用jQuery了 new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery' }), //生成index.html頁面 new HtmlWebpackPlugin({ title: '68kejian', filename: 'index.html', template: 'header.html', inject: 'body', favicon: './images/favico.ico', minify: false, hash: true, cache: false, showErrors: false }), // 分離css new ExtractTextPlugin('[name].bundle.css', { allChunks: true }), new CopyWebpackPlugin([ { from: './src/images' } ]) ], externals: { // require('data') is external and available // on the global var data 'data': 'data' }, devtool: 'source-map' };
執行webpack命令就可以拷貝了