细节
url-loader和file-loader是什么关系?
file-loader用于将文件路径打包为另一个url,url-loader封装了file-loader。使用url-loader时,只需要安装url-loader即可,不需要安装file-loader,因为url-loader内置了file-loader。url-loader工作分两种情况:
-
文件大小小于limit参数,url-loader将会把文件编码为DataURL;
-
文件大小大于limit,url-loader会调用file-loader进行处理,参数也会直接传给file-loader。因此我们只需要安装url-loader即可。
compiler和compilation
编译器和编译集合
compilation对象代表某个版本的资源对应的编译进程。当使用Webpack的development中间件时,每次检测到项目文件有改动就会创建一个compilation,进而能够针对改动生产全新的编译文件。compilation对象包含当前模块资源、待编译文件、有改动的文件和监听依赖的所有信息。compiler对象代表的是不变的webpack环境,是针对webpack的;而compilation对象针对的是随时可变的项目文件,只要文件有改动,compilation就会被重新创建。
不加hash、hash、contenthash和chunkhash的区别
hash一般是结合CDN缓存来使用的。
-
hash是compilation对象生成的hash值,每次项目有所改动该对象就会重新生成一次,意味着任意一个文件的改动都会改变hash
-
chunkhash也根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值,不同的入口文件的chunkhash不同,但是同一个入口分离的css和js拥有相同的chunkhash并相互影响。chunkhash只会监测import和require引入的文件是否改变,不会监测css的@import引入。意味着@import引入的css改变了,但是chunkhash不会变。
-
每个文件根据内容生成的contenthash值,保证即使css文件所处的模块里就算其他文件内容改变,只要css文件内容不变,那么不会重复构建。
webpack构建流程
从启动webpack构建到输出结果经历了一系列过程,它们是:
-
解析webpack配置参数,合并从shell传入和webpack.config.js文件里配置的参数,生产最后的配置结果。
-
注册所有配置的插件,好让插件监听webpack构建生命周期的事件节点,以做出对应的反应。
-
从配置的entry入口文件开始解析文件构建AST语法树,找出每个文件所依赖的文件,递归下去。
-
在解析文件递归的过程中根据文件类型和loader配置找出合适的loader用来对文件进行转换。
-
递归完后得到每个文件的最终结果,根据entry配置生成代码块chunk。
-
输出所有chunk到文件系统。
需要注意的是,在构建生命周期中有一系列插件在合适的时机做了合适的事情,比如UglifyJsPlugin会在loader转换递归完后对结果再使用UglifyJs压缩覆盖之前的结果。
html-webpac-plugin
优化
url-loader
如果图片较多,会发很多http请求,会降低页面性能。这个问题可以通过url-loader解决。url-loader会将引入的图片编码,生成dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的还会使用file-loader进行copy。
将基础库抽离打包到单文件
比如react、react-dom等,这样做的好处是只要你不升级他们的版本这个文件永远不会被刷新。如果你把这些基础库和业务代码打包在一个文件里每次改动业务代码都会导致文件hash值变化从而导致缓存失效浏览器重复下载这些包含基础库的代码。这属于代码分割。
CommonsChunkPlugin
可以提取出多个代码块都依赖的代码形成一个单独的chunk。在应用有多个页面的场景下提取出所有页面公共的代码减少单个页面的代码,在不同页面之间切换时所有页面公共的代码之前被加载过而不必重新加载。
(持续更新)
参考资料: