当前位置: 首页 > 科技观察

使用webpack管理多页面应用技巧总结

时间:2023-03-13 02:55:44 科技观察

随着前端功能的不断丰富,前端代码也越来越复杂,难以管理。为了简化开发的复杂度,出现了很多新的处理技术:模块化、组件化、css预处理器(less、scss)等,提高了我们的开发效率,但是很多模块文件的处理和打包还是会很麻烦的。Webpack是一个nodejs工具,它的工作方式是:把你的项目当成一个整体,通过给定的主文件(如:index.js),Webpack会从这个文件开始寻找你项目的所有依赖文件,使用加载器来处理它们,并最终将它们打包成浏览器可读的JavaScript文件。webpack{entryfile/入口文件}{destinationforbundledfile/bundle.js所在的地方}写入其默认配置文件webpack.config.js,并添加简单的配置以简化上述命令到webpack(非需要node_modules/.bin)globalinstallation/webpack):module.exports={entry:__dirname+"/development/main.js",//唯一提到多次的入口文件output:{path:__dirname+"/build",//打包好的fileisstoredfilename:"bundle.js"//打包后输出文件的文件名}继续修改节点的配置文件package.json,增加如下配置使用更简单的命令npmstart:"scripts":{"start":"webpack"......},这是webpack的简单用法,下面详细介绍一下webpack的配置文件。1、.webpack的配置文件其实是一个node模块,用commonJS风格写的。默认名称是webpack.config.js。自定义配置文件名,可以在webpack命令中指定(显然不能写入配置文件):webpack--config./webpackConfig/dev.config.js默认为当前目录为基目录(base目录可以用--content-base代替),webpack-dev-server生成的包并不是放在你的真实目录下,而是放在内存中。可以另开一个cmd,使用监控命令输出到磁盘:webpack--watch2.入口段可以是字符串(单入口)也可以是数组(多入口),但为了后续开发,建议[使用对象]。entry.value为入口文件或内置模块名,entry.key为output.filename中[name]变量的值。当入口值为字符串或数组时,输出中没有变量[name],当入口值为对象时,输出中只有变量[name]。entry值是一个数组,也就是说数组中的所有js文件内容都打包成一个js文件作为入口js文件。entry的值为一个对象,表示这是一个多页面应用,对象中的每个属性代表一个入口js文件配置。该属性的值也可以是一个数组,表示将数组中的文件打包到同一个文件中,一般用于将第三方插件代码打包合并到同一个js文件中,减少数量的网络请求。3.输出部分相当于【一套规则】。所有的词条都必须使用这套规则,不能针对特定的词条制定输出规则。输出中的常用参数包括:path/publicPath/filename/chunkFilename。path参数(仅适用于webpack)表示生成文件的根目录,需要传入一个[文件系统绝对路径]。path参数和后面的filename参数一起构成了入口文件的完整路径。publicPath(forwebpack-dev-server)参数表示一个[URL路径](指向生成文件的根目录),用于生成css/js/图片/字体文件等资源的初始路径,这将自动添加它在资源文件的url前面。path参数其实是针对本地文件系统的,而publicPath是针对浏览器的;因此,publicPath可以是相对路径(相对于当前代码所在的文件路径),如'../../../../build/',也可以是http等绝对路径//www.xxxxx.com/。总的来说,我还是比较推荐相对路径的写法,这样整体迁移还是很方便的。什么时候使用绝对路径?其实也很简单。当你的html文件和其他资源放在不同的域名下时,应该使用绝对路径。这种情况在后端渲染模板的场景中很常见。filename参数是生成的入口文件的【命名规则】:[name]指的是入口配置的key,[hash]是和版本相关的,每次编译都不一样,但是对于在同一编译过程中生成的所有文件。同理,[chunkhash]为每个文件生成一个hash,与文件内容有关,与版本无关。chunkFilename参数也用于定义生成文件的命名方式,以入口文件以外的chunk命名。library参数中的变量[name]为webpack.DllPlugin中name参数中的变量[name]4.使用CommonsChunkPlugin[smart]判断提取打包的公共代码出现在入口js文件中varcommonsChunkPlugin=newwebpack.optimize.CommonsChunkPlugin({name:'commons',//放上common代码chunk的唯一标识(后面文件名中可以??用[name]引用),//放置普通代码Template的文件名([name]=CommonsChunkPlugin.name),其省略值为[name].jsminChunks:4,//设置代码为4个chunk(即4个入口))会被包含在公共代码中,默认只提取出现在所有入口文件中的代码。chunks:[],//表示哪些chunk需要查找公共代码进行打包,默认提取范围是所有chunk。});//最终生成文件的url为ouput.path+CommonsChunkPlugin.filename。它的作用是:在以入口文件为单位打包js的前提下,进一步提取入口文件之间的公共代码:1.如果name的值为不存在的chunk,则filename的值不能是与现有入口文件的打包名称相同:如果只给出name和filename,则的代码是单独从中提取的如果是为minChunks打包:2,对于,表示仅限于在中搜索,只有同时出现在任意两个entry文件中的代码才会被单独提取打包。如果给chunks:['a','b'],for,表示只从a和b两个入口文件中提取代码,分别打包。2.如果name的值是一个已经存在的chunk(entry.key),会提取公共代码放入同名的entry文件中(也可以通过filename打包后改文件名,和minChunks指定多少个entryfiles中出现的code为sharedcode,chunks需要提取commoncode的entryfilerange)。5.兼容旧版jQuery插件,解决使用旧版jQuery插件出现$/jQuery未定义错误。原因是当我们需要jquery时,我们实际上并没有将jQuery对象设置为全局变量。jQuery插件找不到jQuery对象,因为在各自的上下文中,既没有局部变量jQuery(因为不适配AMD/CMD,所以代码里面没有写相应的require语句引入依赖),也没有全局变量变量jQuery。(切记【三种方法不要混用】):方法一、ProvidePlugin+expose-loader【使用ProvidePlugin将局部变量jQuery引入插件,使用expose-loader引入全局变量jQuery】。varprovidePlugin=newwebpack.ProvidePlugin({$:'jquery',jQuery:'jquery','window.jQuery':'jquery','window.$':'jquery',});ProvidePlugin的机制是:【当webpack加载到一个js模块时,当有一个未定义的变量,其名称与配置中的key匹配(精确字符串匹配)】,它会自动require配置中的值指定的js模块.使用ProvidePlugin还有一个好处,就是在你自己写的代码里,不用了!还!不!使用requirejquery!。expose-loader【将指定js模块导出的变量声明为全局变量】。如果你所有的jQuery插件都是用webpack加载的,用ProvidePlugin确实够了;但是总有一些需求只能用标签手动加载jquery.min.js(意思是如果某个库没有提供文件XXX.min.js不能使用这个方法):externals:{'jquery':'window.jQuery',}方法三,imports-loader,相当于[手动版的ProvidePlugin],不推荐使用{test:require.resolve("some-module"),loader:"imports?$=jquery&jQuery=jquery",//相当于`var$=require("jquery");varjQuery=require("jquery");`}6.其他资源的封装方法加载器[扩展了require()方法的能力],使其可以导入非js模块形式的文件,所有处理导出的文件都是javascrit。loader的使用有两种方式,一种是写在require的参数中:require("!style!css!./style.css");另一种是添加到配置文件中,通过扩展名自动绑定loader。1、css的处理方式less-loader模块编译less文件,但不对url()语法做特殊转换。如果要将url()语句中涉及的文件(如图片、字体文件等)用webpack打包,就必须使用pipeline传递给css-loader做进一步处理。css-loader会把它变成require()语句,从而触发其他可以处理webpack配置文件中定义的资源的加载器(如url-loader、file-loader)。一般在url()语句中,我会将资源路径指定为相对路径(相对于该语句所在的less/css文件)。方法一、可以使用style-loader直接将css代码段用js打包,自动插入到带有