以前,当须要打包多个而文件时,我是这么写的: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的脚手架的配置。