前言在深入阅读下面的内容之前,希望大家已经阅读了我之前的文章日常工作webpack必备姿势(一)。这篇文章的目的是进一步探索webpack的日常使用。而不是入门教学。打包多页应用webpack通常配合VUE等框架来打包单页应用。如果要用它来打包多页应用,我们如何实现这个操作呢?思路是这样的:打包页面,在页面中动态插入js。必须依赖的插件是HtmlWebpackPlugin,指定动态插入页面的js入口文件。入口文件从一个入口变成了多个,指定入口文件的方式也从字符串变成了对象。出口文件已从一个出口更改为多个出口。基于以上思路,我们来看看webpack配置文件的最终配置:letpath=require('path');//webpack是node写的,path是node的语法letHtmlWebpackPlugin=require('html-webpack-plugin');//HTML编译插件module.exports={mode:'development',//编译环境改为development(开发模式)entry:{aaa:'./src/aaa.js',//第一个入口文件bbb:'./src/bbb.js'//第二个入口文件},output:{//编译目录filename:'[name].js',//编译文件名,name由入口js动态生成filepath:path.resolve(__dirname,'dist'),//编译路径必须是绝对路径},plugins:[newHtmlWebpackPlugin({template:'./src/index.html',//html源文件需要编译的,一个就够了,因为内容是入口jsRenderedfilename:'aaa.html',//编译后的文件名chunks:['aaa']//入口js文件}),newHtmlWebpackPlugin({template:'./src/index.html',//需要编译的html源文件filename:'bbb.html',//编译后的文件名chunks:['aaa','bbb']//可以参考设置多个入口js文件}),],}在我们项目中新建入口文件aaa.js和bbb.js文件,测试最终编译效果如图:source-map的作用在开始使用webpack运行的时候有没有遇到过代码错误,但是又没有办法追查到源码错误的地方?这个时候source-map就派上用场了。source-map的意思是“源代码映射”。顾名思义,它的作用就是帮助我们查找源代码错误。//在webpack配置文件中添加这样一行devtool:'eval-cheap-source-map'。在实际项目使用中,一般的开发环境都会配置这个选项,但是在部署的时候一定要把它去掉。因为source-map文件比较大,严重影响了网页传输的效率。与source-map相比,source-map对应的eval-source-map并不会单独生成一个source-map相关的文件,但是它也可以发现错误点。很少使用其他可配置项,例如cheap-source-map和eval-cheap-source-map。webpack常用的clean-webpack-plugin插件:配置设置为每次生成新文件(避免缓存),手动删除之前编译好的文件太麻烦。有了它,就可以自动删除之前编译目录下的文件。copy-webpack-plugin:如果我们有文件要在每次更新后编译到输出目录,为我们制作一个副本,使用这个。BannerPlugin是webpack的一个内置功能:我们在看别人的文章的时候,总会加上一个来源说明。使用BannerPlugin可以自动帮我们在每个打包文件的开头添加描述性字符。一、安装依赖包//BannerPlugin是webpack自带的功能,不需要安装npminstall--save-devclean-webpack-pluginnpminstallcopy-webpack-plugin--save-devwebpack配置文件(相关3个插件的配置)letpath=require('path');//webpack是node写的,path是node的语法letHtmlWebpackPlugin=require('html-webpack-plugin');//HTML编译插件const{CleanWebpackPlugin}=require('clean-webpack-plugin');constCopyPlugin=require('copy-webpack-plugin');letwebpack=require('webpack');module.exports={mode:'development',//将编译环境改为development(开发模式)entry:'./src/index.js',//需要编译源文件目录output:{//编译目录filename:'bundle.[hash].js',//编译文件名path:path.resolve(__dirname,'dist'),//编译后的路径必须是绝对路径},devtool:'eval-cheap-source-map',plugins:[newHtmlWebpackPlugin({template:'./src/index.html',//The需要编译的html源文件filefilename:'index.html',//编译后的文件名}),newCleanWebpackPlugin(),newCopyPlugin([{from:'doc',to:''}]),newwebpack.BannerPlugin('Descriptioncharacter')],}最终效果:跨域解决webpack即可通过代理解决跨域,只需要配置如下://以'/api'开头的请求将重新代理到新域下的devServer:{proxy:{'/api':'http://***'}},//如果后端路径不包含'/api',可以通过pathRewrite更改(此处替换)devServer:{proxy:{'/api':{target:'http://***',pathRewrite:{'/api':''}}}},以上方案(包括使用webpack在网上模拟后端数据等)需要后端解决跨域问题下面是Java语言中的跨域解决方案:跨域解决方案response.addHeader("Access-Control-Allow-Origin","*");response.addHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE,OPTIONS,HEAD");response.addHeader("Access-Control-Allow-Headers","Content-Type,Authorization");response.addHeader("Access-Control-Max-Age","3600");}returntrue;}}定义环境变量,区分环境webpack中的定义插件可以帮助我们定义一些全局变量来区分当前环境是在线还是离线,用法如下:newwebpack.DefinePlugin({'env':JSON.stringify('development')})//错误的用法如下:newwebpack.DefinePlugin({'env':'development'})//使用直接env而没有引用实际获取变量env的地方;//上面的错误是获取env得到的变量development不是字符串;//development改成字符串也能正常运行(如下),但是感觉很奇怪实践如果要区分线上环境和线下环境,需要用到webpack-merge。一般在实际开发中区分线上环境和开发环境的方式是定义三个文件:webpack.base.js。这个文件的作用是定义上网环境。开发环境通用的配置项内容webpack.prod.js这个文件的作用是定义线上特定的属性比如:定义mode为'production',定义一些针对压缩代码的优化项等webpack。dev.js应该文件的作用是定义开发环境的属性,比如source-map属性,devServer等等。文件内容如下://webpack.base.jsfileletpath=require('path');//webpack是node写的,path是node的语法letHtmlWebpackPlugin=require('html-webpack-plugin');//HTML编译插件letwebpack=require('webpack');module.exports={entry:'./src/index.js',//要编译的源文件目录output:{//编译目录filename:'bundle.[hash].js',//编译文件名path:path.resolve(__dirname,'dist'),//编译路径必须是绝对路径},plugins:[newHtmlWebpackPlugin({template:'./src/index.html',//待编译的html源文件filename:'index.html',//编译后的文件名}),newwebpack.DefinePlugin({'env':"'development'"})],}//webpack.prod.js文件varbase=require('./webpack.base.js');varmerge=require('webpack-merge');module.exports=merge(base,{mode:'production'//其他优化项})//webpack.dev.js文件varbase=require('./webpack.base.js');varmerge=require('webpack-merge');module.出口=合并(基地,{mode:'development',//其他开发配置项内容})package.json文件中调用不同的配置文件来区分线上和开发环境脚本:{"build":"webpack--configwebpack.prod.js","dev":"webpack--configwebpack.dev.js"},webpack自带的优化webpack会自动帮我们在开发环境做很多代码优化。需要注意的是,优化必须是在生产环境下的效果。我们来看下面两个例子:tree-shakingtree-shaking就是说只要摇一摇树,那些没用的或者枯萎的树叶就会离开,也就是说我们代码中无效的代码会被自动优化。我们来看一下案例://在一个文件中创建以下两个函数//bb.jsletsum=function(a,b){returna+b+"ssssssssss";//ssssssssss是测试时搜索验证效果}letminus=function(a,b){returna-b+"mmmmmmmm";//同样mmmmmmmm是在测试时搜索验证效果}exportdefault{sum,mi??nus}//在另一个文件中引用上面的内容,打包importcalcfrom'./bb.js'console.log(calc.sum(12,23))在生产环境中;打包结果只有bb.js文件中的sum函数,没有minus函数。原因是我们的代码中只用到了sum函数,而minus函数因为没有用到,所以自动帮我们去掉了。scopepromotionwebpack可以自动做一些计算优化处理,比如下面这种情况:leta=1;letb=2;letc=3;console.log(a+b+c+"scopepromotion")//"Scopepromotion”就是在测试的时候搜索和验证效果。编译后最终代码效果为:console.log("6scopepromotion")。favicon.ico图标在vue项目目录build文件夹webpack.dev中分别在.conf.js和webpack.prod.conf.js文件中的html-webpack-plugin中添加一个favicon:'favicon文件的相对路径'例如:newHtmlWebpackPlugin({filename:'index.html',template:'index.html',favicon:'./favicon.ico',inject:true})注意:1.favicon填写的路径必须是一个相对路径。2、对于修改后的文件,dev是开发环境,prod是生产环境。只有全部修改,才能保证本地和通过服务器访问都有小图标。结语webpack的常用知识暂时介绍到这里,后续会根据webpack版本的更新进行更新!!
