1.常见的loader:
- css-loader:解析css。
- style-loader:将css样式插入到dom中。
- less-loader:将less解析成css。
- postcss-loader:它会根据根目录配置的browserslist的规则查询浏览器市场占有率来决定是否要做兼容,根据postcss-preset-env来给css样式添加前缀实现兼容。
- file-loader:解析一些资源,例如图片、音频、字体。
- url-loader:与file-loader类似。它可以设置超过limit大小,小于limit的资源会转位base64。base64会减少http请求缓解服务器压力,但是滥用会导致打包后的文件体积过大。
- ts-loader:用来解析ts文件,会检验ts类型。但不能使用polyfill功能。
- babel-loader:解析js文件,结合
@babel/preset-env预设可以将代码转位es5。结合@babel/preset-typescript"预设可以解析ts文件,但需要结合tsc来检查类型。可以设置targer字段来实现目标兼容的浏览器,否则会根据browserslist的规则去实现兼容。 - vue-loader:解析vue文件。
2.常见的plugin
- clean-webpack-plugin:每次打包前都会将之前的的打包文件删除。
- html-webpack-plugin:根据html模板生成到打包文件中的html。
- copy-webpack-plugin:将某个文件夹下的资源复制到打包后的目录下,这些资源不会被打包压缩。
- webpack.DefinePlugin:用来定义全局变量。
- min-css-extract-plugin:将css单独打包成一个文件。
- terser-webpack-plugin:丑化js,压缩js。
- css-minimizer-webpack-plugin:对css进行压缩。
- progress-bar-webpack-plugin:打包时显示进度
3.webpack打包流程
- 初始化阶段。
webpack会根据传入的配置通过createCompiler创建一个compiler并返回,在创建compiler过程中会遍历用户的plugins调用插件的apply注册。调用 new WebpackOptionsApply().process 方法,加载各种内置插件。比如会注入 EntryOptionPlugin 插件,处理 entry 配置。
创建完compiler后就会调用compiler.run方法。run方法中会调用compile方法。compile方法中执行了beforeCompile、compile、make、finishMake、afterCompile钩子,并会创建compilation。在make阶段会执行entryOptionPlugin的EntryPlugin中注册的make函数。他会根据entry配置找到入口文件最终通过handleModuleCreate根据文件类型创建module子类,然后通过子类module.build开始构建。
- 构建阶段。
build过程中会执行runLoaders转译 module 内容,会将各类资源类型转译为 JavaScript 文本,通过 acorn将js解析为ast,对于模块中的依赖会递归调用 runLoaders,直到所有依赖全部解析完毕,构建阶段结束。
- 生成阶段
构建完成后通过compilation.seal会将所有的module转换为chunk,通过hooks.optimizeChunkModules优化压缩chunk,通过createChunkAssets创建资源。然后通过compilation.emitAssets将资源保存到compilation.assets中。最后通过fs.mkdir输出资源。
4.webpack热更新(HMR)原理
5.Babel原理 将源代码经过词法分析转换为token数组(每一个词都是数组中的对象,对象存放类型、值),再经过语法分析转换为AST,遍历AST访问每个节点通过插件对es6进行转换然后得到新的AST,最后生成es5代码。
6.vue-loader原理:
-
webpack配置中在plugin中使用 new VueLoaderPlugin()会创建一个pitcher-loader。用户的rules中剔除vue-loader的rule,然后经过cloneRule 处理,再将用户定义的原始rules拼接成[pitcher, ...clonedRules, ...rules] 。
-
webpack运行时,如果命中 /.vue$/i ,则会通过vue-loader去解析。通过parse解析器解析源文件得到描述符,分别处理template、script、style三个模块得到对应的import,加上type、lang参数。
-
这些import会命中pitcher-laoder,经过pitcher-loader处理后会根据用户提供的rules将每一模块的import组装成内联loader的方式。
-
通过内联调用loader就会重新来到vue-loader,通过selectBlock 处理不同type后传递给下一个loader做处理。template经过vue-loader后会再经过tempalte-laoder最终解析生成render函数生成vnode。script经过vue-loader会再经过babel-laoder。style模块经过vue-loader后会再经过css-loader、style-loader。
7.如何使用chunk:
- 多入口方式,对于output.filename通过占位符区分不同的chunk。
- 设置SplitChunks,通过里面的属性设置chunk的大小以及分包的条件。
- 通过动态倒入import()方式也会实现分包。
8.treeShaking: 去除无用的代码
9.hash,chunkHash,contentHash的区别
- hash:和整个项目有关,项目文件内容发生改变,hash值就会改变。
- chunkHash:和Webpack打包的chunk有关,不同的入口会生成不同的chunkhash,当一个入口文件内容不改变时chunkhash不会改变。
- contentHash:根据文件内容来定义hash,文件内容不变,则contenthash不变。适用情况,当一个文件在另一个文件中被导入,自身内容没有发生变化,导入他的文件发生改变了,如果使用chunckhash,这个文件名也会改变,如果使用contenthash则不会。