《Webpack实战》学习总结

第1章 Webpack简介

1.模块化通过导入导出解决依赖关系问题、加载合并后的资源文件减少网络开销、隔离模块作用域解决js的缺点。

2.js社区对模块化进行不断的尝试,依次出现了AMD、CommonJS、CMD等解决方案,直到2015年ES6的出现,才使得js拥有了模块这一概念。

3.模块打包工具的任务就是解决模块间的依赖,使其打包后的结果能运行在浏览器上。

4.Webpack支持多种模块标准,具有完备的code splitting解决方案,可以处理各种类型的资源,拥有庞大的社区支持。

5.使用WDS可以令Webpack进行模块打包,并处理打包结果的资源请求,可以处理静态资源文件请求,具有live-reloading的特性。

 

第2章 模块打包

1.Browserify可以将CommonJS模块打包为浏览器可以运行的单个文件。

2.CommonJS通过module.exports可以导出模块中的内容,使用require进行模块导入。

3.require的模块被加载只执行一次。

4.ES6 Module使用export命令导出模块,export分为命名导出和默认导出,使用import语法导入模块。

5.CommonJS模块依赖关系的建立发生在代码运行阶段,ES6 Module则是模块依赖关系的建立发生在代码编译阶段。

6.CommonJS在导入值时是值拷贝,而在ES6 Module是动态映射。

7.ES6 Module的特性动态映射使其可以更好地支持循环依赖。

8.webpack可以导入非模块化文件、AMD模块(使用define和require定义和调用模块),可以使用UMD使得一个模块能运行在各种环境下。

9.每个npm模块都有一个入口,这个入口被维护在模块内部package.json文件的main字段中。

 

第3章 资源输入输出

1.一棵依赖树称为一个chunk,由chunk打包后的产物称为bundle。在特殊情况下,一个入口也可能产生多个chunk并最终生成多个bundle。

2.context是配置资源的入口前缀,entry的配置可以有多种形式:字符串、数组、对象、函数。

3.如果js文件的体积过大,我们可以通过使用CommonsChunkPlugin或optimization.splitChunks将app与vendor这两个chunk的公共模块提取出来。

4.多页应用也可以通过提取vendor将各个页面之间的公共模块进行打包。

5.output对象常用的配置项是filename、path(资源的输出位置)、publicPath(间接资源的请求位置),一般WDS的publicPath配置会与output.path保持一致。

6.多入口output.filename一般在开发环境会配置为[name].js,在生产环境会配置为[name]@[chunkhash].js。

 

第4章 预处理器

1.我们可以通过webpack,在js中引入css,提高代码的可维护性。

2.Style label = style-loader( css-loader( sass-loader(SCSS) ) )。

3.loader的使用配置在module.rules下,使用test匹配文件名后缀,使用use使用loader,支持链式调用,调用顺序为从后往前。

4.loader支持传入配置项options,可以使用exclude和include确定适用范围,使用resource和issuer更加精确地确定模块规则的作用范围,使用enforce指定loader是在最前(pre)还是最后(post)执行。

5.常用loader有babel-loader、ts-loader、html-loader、handlebars-loader、file-loader、url-loader、vue-loader。

6.我们可以自定义loader,首先实现loader的初始化,实现基本功能,然后启用缓存,获取options,最后根据options实现功能(书中以实现source-map功能为例)。

 

第5章 样式处理

1.输出css文件可使用extract-text-webpack-plugin来实现,该插件需要导入、配置在plugins中,再在module.rules中使用。

2.多入口输出css文件时,也需要对应配置[name].css进行输出。

3.mini-css-extract-plugin是升级版的插件,可以实现按需加载css,从而在单入口中额外输出按需加载的js文件和css文件。

4.我们可以使用sass和less进行样式的预处理,要想在浏览器中查看源码,则需要在sass-loader、less-loader和css-loader中配置sourceMap的值。

5.postcss是编译插件的容器,使用postcss-loader可以轻松地将PostCSS和webpack连接起来,postcss使用postcss.config.js进行插件的配置。

6.postcss可承载autoprefixer、stylelint、CSSNext这些插件。

7.使用CSS Modules不需要额外安装模块,只要开启css-loader中的modules配置项即可,通过CSS模块化可以避免样式冲突。

 

第6章 代码分片

1.代码分片是Webpack特有的技术,通过这项技术我们可以把代码按照特定的形式拆分,使用户按需加载,从而有效降低首屏加载资源的大小。

2.通过合理规划入口,可以将库放在一个单独的入口中,从而利用客户端缓存,提升页面的性能。

3.使用webpack自带的CommonsChunkPlugin可以提取多个chunk中的公共模块,从而减少重复模块的打包,提升开发速度,减小整体资源的体积,合理分片后的代码可以更有效地利用客户端缓存。

4.CommonsChunkPlugin可以通过提取vendor解决单入口应用的公共模块提取问题,配置chunks可以设置提取范围,配置minChunks可以设置提取规则。

5.通过CommonsChunkPlugin提取Webpack的运行时,即初始化环境代码,生成manifest.js文件,可以使vendor.js的hash值不变,从而实现长效缓存。

6.CommonsChunkPlugin的不足是一个插件只能提取一个vendor,会增加重复的配置代码;会多加载一个manifest文件;会破坏chunk中模块的依赖关系,使得无法在异步的情况下正确提取公共模块。

7.optimization.SplitChunks功能更强,解决了异步加载无法正确提取公共模块的问题,将配置方式从命令式演进为声明式。

8.SplitChunks默认对异步资源进行提取,我们也可以修改其默认配置。

9.使用Webpack特有的import()可以实现资源的异步加载,从而减少首屏加载的资源数。我们可以通过特有的注释让Webpack获取到异步chunk的名字,打包输出有意义的名字。

 

第7章 生产环境配置

1.我们可以采用相同的配置文件,通过条件判断区分是开发环境还是生产环境,也可以通过对两种环境各自创建配置文件,将公共的配置提取出来,各自引用来实现,可以使用webpack-merge来实现配置文件的合并。

2.在Webpack4我们可以开启production模式,Webpack会自动添加许多适用于生产环境的配置项,从而使得配置文件越写越少。

3.我们可以使用DefinePlugin添加环境变量,环境变量涉及到字符串必须加上JSON.stringify()封装。

4.在webpack配置文件加上devtool:'source-map'即可开启源码映射功能。只要不打开开发者工具,浏览器是不会加载map文件的。

5.source-map的简略版有cheap-source-map和eval-source-map,还有一种折中的版本是cheap-module-eval-source-map。

6.为了保证源码的安全,Webpack提供了hidden-source-map(通过上传map到Sentry,返回错误栈)和nosources-source-map(只能看到目录,看不到文件内容,能看到源码的错误栈)来提升安全性,我们也可以通过nginx设置白名单来实现。

7.我们可以通过UglifyJS和terser来实现js代码的压缩,在css样式被提取出来后,通过optimize-css-assets-webpack-plugin对css进行压缩。

8.我们通过给输出资源加上chunkhash监听文件的修改,从而合理地使用缓存,通过html-webpack-plugin生成index.html,自动引用不断变化的资源文件。

9.Webpack4之前的版本在新增模块时,会影响其他模块的chunk id,从而影响chunkhash的值,进而影响缓存效果,解决方式为增加HashedModuleIdsPlugin的插件配置。

10.通过VSCode的插件Import Cost可以计算模块压缩后和gzip后所占体积,使用webpack-bundle-analyzer可以生成模块组成结构图,在package.json添加bundlesize的配置,可以自动化地对资源体积进行监控。

 

第8章 打包优化

1.打包优化即是让打包的速度更快,输出的资源更小。我们对项目不要过早优化。

2.HappyPack是通过多线程提升打包速度的工具,使用babel-loader或ts-loader迁移到HappyPack上会收到不错的效果。

3.在module.rules中,我们使用happypack/loader替换原有的loader,并在plugins中添加HappyPack的插件,将原有的loader连同它的配置插入进去即可。在优化多个loader时,需要为每一个loader配置一个id。

4.缩小打包作用域可以使用exclude和include确定loader的规则范围,noParse不去解析但仍会打包到bundle中,IgnorePlugin可以完全排除一些模块,被排除的模块即使被引用也不会打包进资源文件中,cache是使用缓存,提升打包速度。

5.DllPlugin与code splitting类似,都可以用来提取公共模块。DllPlugin是将vendor完全拆出来,独立打包,因此在打包速度上更快。

6.使用DllPlugin,我们首先要配置vendor,然后对vendor进行打包,打包生成vendor.js和manifest.json资源清单,最后使用DllReferencePlugin将资源清单进行配置,再在业务代码中加载vendor.js。

7.由于vendor修改时里面的模块的chunk id发生变化,导致其他引用vendor的文件发生变更。为解决此问题,可以增加HashedModuleIdsPlugin配置。

8.Tree Shaking可以在打包时去除死代码,它只对ES6 Module生效。若在工程中使用了babel-loader,则需要通过配置禁用它的模块依赖解析,否则转化为CommonJS的模块,就无法进行tree-shaking了。

9.Tree Shaking是给死代码加上标记,使用terser-webpack-plugin真正去除死代码。

 

第9章 开发环境调优

1.使用webpack-dashboard可以在控制台分成几个面板来展示不同的信息。

2.使用webpack-merge可以通过merge.smart()函数智能合并公共配置代码和该环境的配置代码,取代Object.assign的合并配置方式。

3.使用speed-measure-webpack-plugin(SMP),通过给配置加上smp.wrap()进行封装,可以分析出打包过程在各个loader和plugin上耗费的时间。

4.使用size-plugin可以帮助我们监控打包生成的资源体积的变化情况。

5.HMR即是模块热替换,可以让代码在网页不刷新的前提下得到最新的改动,是live reload的升级版。

6.我们通过引用HotModuleReplacementPlugin来配置HMR,可以选用手动调用HMR的API,也可以借助现成的工具,如react-hot-loader何vue-loader。

7.HMR实现的原理是基于WDS和浏览器之间建立的websocket链接。当WDS检测到代码更新,则向浏览器推送更新事件,并带上新的hash值,浏览器对hash值进行比对,然后向WDS发起请求获取chunk diff,WDS再返回浏览器增量更新的内容,浏览器收到后调用相关的API进行处理。

8.为了避免index.js中因为HMR而新建多个定时器,我们可以使用module.hot.decline()函数禁止页面使用HMR,改为自动刷新,再使用module.hot.accept([file]),使得当file改变时依然可以启用HMR更新。

 

第10章 更多JavaScript打包工具

1.相较之下,Webpack的优势在于它更全面,Rollup则更专注于js的打包。

2.Rollup的配置文件是rollup.config.js。Rollup不需要装在项目内部,直接全局安装即可,用rollup -c rollup.config.js命令进行打包,打包出来的东西很干净,没有添加额外的代码。

3.Rollup最先实现了tree shaking,也是基于对ES6 Module的静态分析,通过配置output.format可以选择输出的资源形式,如cjs或esm等。

4.Rollup经常被用于打包一些库和框架,如React和Vue,React团队将React从原有的打包工具Browserify迁移到了Rollup。

5.Rollup没有各种loader和plugin、HMR等功能。

6.Parcel在打包工具中属于后来者,其打包速度块,宣称实现了零配置(Webpack4也是零配置)。

7.Parcel在使用多个loader进行资源处理时,只需要在资源输入时,对String转换成AST,然后不断地进行语法转换即可,最后再将AST转换为String进行资源输出,节省了大量的解析AST的时间。

8.Parcel可以用HTML文件作为项目入口,也自动为输出文件生成了hash版本号和source map,内容都是默认压缩过的,我们可以通过修改Babel、PostHTML和PostCSS的配置文件,实现定制化。

9.Parcel提供了快速配置的方法,如安装vue后,只需要安装parcel-bundler即可,不需要进行更多的配置。

10.打包工具的选择需要在通用性和性能之间做一些权衡和取舍,现在的打包工具正在向配置极小化和工程标准化的方向发展。

11.我们可以将C或Java编译为WebAssembly在浏览器上运行,现在的打包工具都支持WebAssembly,可以导入wasm模块并使用。

 

posted @ 2021-09-06 11:24  罗毅豪  阅读(112)  评论(0编辑  收藏  举报