以前,當須要打包多個而文件時,我是這麼寫的:javascript
module.exports={ entry:{ "page/main/main":'./src/js/index.js', "page/car/car":"./src/js/car.js", "page/goods/goods":"./src/js/goods.js", }, output:{ filename:"[name].[hash].js", path:path.resolve(__dirname,'dist') }, plugins:[ new webpack.HotModuleReplacementPlugin(), new htmlWebpackPlugin({ title:"首頁", template:'./src/index.html', filename:"index.html", chunks:["page/main/main"] }), new htmlWebpackPlugin({ title:"購物車", template:'./src/index.html', filename:"car.html", chunks:["page/car/car"] }), new htmlWebpackPlugin({ title:"商品", template:'./src/index.html', filename:"goods.html", chunks:["page/goods/goods"] }) ]
能夠發現,咱們在entry中手動引入了多個文件; 在plugins中,咱們又手動的屢次new htmlWebpackPlugin()。css
雖然可以正常的運行,然而存在不少限制。html
首先:存在大量重複的代碼。如今只有3個頁面,假如現有10個頁面,那麼你就得手動的new10次,在enrty中輸入10個入口。vue
其次:當增長新的頁面時,又得過來webpack的配置裏面手動的再加入到入口文件中。java
明顯的,對於這些重複的並且長得很像的,若是能自動獲取到須要配置的文件,而且在一個循環裏面調用,那就方便多了。node
使用node.js的golb模塊來獲取文件
//引入glob var glob= require('glob'); //同步讀取src目錄下全部的html文件 var files = glob.sync('./src/*.html'); var entry={}; var plugins=[]; //循環將文件 files.forEach(function(item,i){ //item相似:./src/index.html var htmlName=item.slice(item.lastIndexOf("/")+1); //最後生成的文件名只須要最後面的名字index.html var name=htmlName.split(".")[0]; //添加到entry入口,並制定生成文件的目錄 entry["page/"+name+"/"+name]='./src/js/'+name+'.js' //生成htmlWebpackPlugin實例 plugins.push( new htmlWebpackPlugin({ template:item, filename:htmlName, chunks:["page/"+name+"/"+name] }) ) }); module.exports={ entry:entry, output:{ filename:"[name].[chunkhash].js", path:path.resolve(__dirname,'dist'), }, module:{ rules:[ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, ] }, plugins:plugins }
能夠發現,使用glob.sync來讀取文件並進行循環操做,本來須要手動操做的部分,循環已經幫咱們處理好了。本來須要不少new new htmlWebpackPlugin()已經再也不存在,並且即便後續須要添加新的頁面,也不須要咱們手動去添加,glob.sync會本身去讀取全部的*.html文件,接着循環會幫咱們處理。jquery
這裏須要注意的地方就是,index.html對應的js文件必須爲index.js,ceshi.html文件對應的文件必須爲ceshi.js。至於js裏面須要引入其餘庫,或者本身寫的工具函數,哪一個頁面須要,只需引入便可,webpack會本身處理好。webpack
當頁面存在引用相同的庫時,最好仍是將這些庫文件提取到單獨的文件,頁面只保留業務邏輯的js代碼。ios
entry.vendor=[ //舉例以下: "vue","vuex","axios","jquery","vue-router","moment","lodash" ]; plugins=[ new webpack.optimize.CommonsChunkPlugin({ name:["vendor","manifest"] }) ] //修改循環中的chunks, 增長vendor以及manifest: files.forEach(function(item,i){ plugins.push( new htmlWebpackPlugin({ template:item, filename:htmlName, chunks:["page/"+name+"/"+name,"vendor","mainfest"] }) ) });
再執行webpack,能夠發現公共的庫已經被提取到單獨的vendor文件。web
對於CommonsChunkPlugin
,webpack 每次打包實際仍是須要去處理這些第三方庫,只是打包完以後,能把第三方庫和咱們本身的代碼分開。
而DLLPlugin
則是能把第三方代碼徹底分離開,即每次只打包項目自身的代碼。
//安裝模塊 npm install --save-dev autodll-webpack-plugin //引入模塊 var AutoDllPlugin = require('autodll-webpack-plugin'); 在plugins中添加插件:(須要放在循環以前,防止數組被從新賦值) var plugins=[ new AutoDllPlugin({ //文件名 filename: '[name].[hash].js', //打包後的文件路徑 path: './page/common/', //是否將生成的Js文件注入到html文件中 inject:true, //須要分離的庫 entry: { vendor: [ "vue","vuex","axios","jquery","vue-router","moment","lodash","vue-touch","vue-lazyload" ] }, //壓縮代碼(注意這裏是壓縮分離出來的庫文件代碼,跟外面的要區分開來,若是外面的須要壓縮,外面的plugins中也須要new一個壓縮實例) plugins: [ new webpack.optimize.UglifyJsPlugin() ] }) ]
執行webpack命令,能夠發現公共的庫文件也被打包到單獨的文件了。
autodll-webpack-plugin
在內存中緩存了文件,因此當你第二此執行webpack命令進行打包時,能夠明顯發現打包時間少了不少。
而CommonsChunkPlugin
每次都所有從新打包再進行分離,因此當須要屢次修改文件時,autodll-webpack-plugin能夠明顯下降打包的時間,尤爲是依賴不少外部庫的時候。
不少時候,咱們都須要針對不一樣的環境進行不用的操做。
好比在生成環境下分離css到單獨文件:
var extractSass = new ExtractTextPlugin({ filename: "[name].[contenthash].css", disable: process.env.NODE_ENV === "development" });
在生成環境下要壓縮代碼: new UglifyJSPlugin();
在開發環境下使用代理
devServer:{ proxy: { 'api': { target: 'http://api.douban.com/v2/movie/', secure: false, changeOrigin: true } }
一般會用process.env.NODE_ENV === "development",而且在package.json中設置環境變量來進行判斷,不過當文件大了或者頁面須要判斷的地方多了以後,配置文件就會充斥着大量三元表達式
。
能夠考慮用webpack-merge將配置文件拆分爲3個文件,一個是webpack.common.js
,即不論是生產環境仍是開發環境都會用到的部分,以及webpack.product.j
s和webpack.dev.js
, 而且使用webpack-merge來合併對象。
//webpack.common.js var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { app: './src/index.js' }, output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules:[ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, ] }, plugins: [ new HtmlWebpackPlugin({ title: 'test' }) ], }
//開發環境webpack.dev.js var merge = require('webpack-merge'); var common = require('./webpack.common.js'); module.exports = merge(common, { module:{ rules:[ { test: /\.css$/, use:["style-loader","css-loader"] } ] }, devtool: 'inline-source-map', devServer:{ open:true, hot: true, proxy: { '/api/': { target: 'http://baidu.com', secure: false, changeOrigin: true } } }, })
//生產環境webpack.product.js var merge = require('webpack-merge'); var UglifyJSPlugin = require('uglifyjs-webpack-plugin'); var common = require('./webpack.common.js'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); var cleanPlugin = require("clean-webpack-plugin"); var extractSass = new ExtractTextPlugin({ filename: "[name].[contenthash].css", }); module.exports = merge(common, { module: { rules: [{ test: /\.css$/, use: extractSass.extract({ use: [{ loader: "css-loader" }, ], fallback: "style-loader" }) }] }, devtool: 'source-map', plugins: [ new cleanPlugin(["dist"]), new UglifyJSPlugin(), extractSass, ] });
在packjson中修改webpack默認配置文件
"scripts": { "dev": "webpack-dev-server --config webpack.dev.js", "build": "webpack --config webpack.product.js" }
經過npm run dev以及npm run build來執行對應的操做。
以上只是一個簡單的示例,並非必定須要拆分紅3個文件,若是你的配置足夠簡單,寫成一個webpack.config.js足以。可是,假如你的項目足夠龐大,最好仍是拆開來寫,能夠參考vue-cli的腳手架的配置。