ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## webpack的打包流程 简单回答 * 1、读取`webpack`的配置参数;启动`webpack`,创建`Compiler`对象并开始解析项目; * 2、从入口文件(`entry`)开始解析,并且找到其导入的依赖模块,递归遍历分析,形成依赖关系树; * 3、对不同文件类型的依赖模块文件使用对应的`Loader`进行编译,组装成一个个包含多个模块的 Chunk, 最终转为`Javascript`文件输出; * 4、整个过程中`webpack`会通过发布订阅模式,向外抛出一些`hooks`,而`webpack`的插件即可通过监听这些关键的事件节点,执行插件任务进而达到干预输出结果的目的。 **初始化 -- 解析编译 -- Chunk输出** ## 执行loader顺序 在实际工程中,配置文件上百行乃是常事,如何保证各个loader按照预想方式工作? 使用 enforce 强制执行 loader 的作用顺序,pre 代表在所有正常 loader 之前执行,post 是所有 loader 之后执行。(inline 官方不推荐使用) ## Babel原理 Babel大概分为三大部分: * 解析:将代码转换成 AST * 词法分析:将代码(字符串)分割为token流,即语法单元成的数组 * 语法分析:分析token流(上面生成的数组)并生成 AST * 转换:访问 AST 的节点进行变换操作生产新的 AST * Taro就是利用 babel 完成的小程序语法转换 * 生成:以新的 AST 为基础生成代码 ## 代码分割的本质和意义 源代码直接上线:虽然过程可控,但是http请求多,性能开销大。 打包成唯一脚本:一把梭完自己爽,服务器压力小,但是页面空白期长,用户体验不好。 ## source map `source map`是将编译、打包、压缩后的代码映射回源代码的过程。打包压缩后的代码不具备良好的可读性,想要调试源码就需要 soucre map。 map文件只要不打开开发者工具,浏览器是不会加载的。 ## 热更新原理 [webpack的热更新](https://www.jianshu.com/p/652fbae768bf) webpack的热更新又称热替换(Hot Module Replacement),缩写为HMR。 这个机制可以做到不用刷新浏览器而将新变更的模块替换掉旧的模块。 1,Webpack编译期,为需要热更新的 entry 注入热更新代码(EventSource通信) 2,页面首次打开后,服务端与客户端通过 EventSource 建立通信渠道,把下一次的 hash 返回前端。 3,客户端获取到hash,这个hash将作为下一次请求服务端 hot-update.js 和 hot-update.json的hash, 4,修改页面代码后,Webpack 监听到文件修改后,开始编译,编译完成后,发送 build 消息给客户端 5,客户端获取到hash,成功后客户端构造hot-update.js script链接,然后插入主文档, 6,hot-update.js 插入成功后,执行hotAPI 的 createRecord 和 reload方法,获取到 Vue 组件的 render方法,重新 render 组件, 继而实现 UI 无刷新更新。 ## 文件监听原理 ## 文件指纹 文件指纹是打包后输出的文件名的后缀。 * `Hash`:和整个项目的构建相关,只要项目文件有修改,整个项目构建的 hash 值就会更改 * `Chunkhash`:和 Webpack 打包的 chunk 有关,不同的 entry 会生出不同的 chunkhash * `Contenthash`:根据文件内容来定义 hash,文件内容不变,则 contenthash 不变 JS的文件 :设置 output 的 filename,用 chunkhash `filename: '[name][chunkhash:8].js'` CSS的文件: 设置 MiniCssExtractPlugin 的 filename,使用 contenthash ```js plugins:[ new MiniCssExtractPlugin({ filename: `[name][contenthash:8].css` }) ] ``` 图片的文件指纹: 设置file-loader的name,使用hash。 ```js use:[{ loader:'file-loader', options:{ name:'img/[name][hash:8].[ext]' } }] ``` ## 具体 文件的解析与构建是一个比较复杂的过程,主要依赖于`compiler`和`compilation`两个核心对象实现。 >`compiler`对象是一个全局单例,他负责把控整个`webpack`打包的构建流程。 `compilation`对象是每一次构建的上下文对象,它包含了当次构建所需要的所有信息,每次热更新和重新构建,`compiler`都会重新生成一个新的`compilation`对象,负责此次更新的构建过程。 >而每个模块间的依赖关系,则依赖于`AST`语法树。每个模块文件在通过`Loader`解析完成之后,会通过`acorn`库生成模块代码的`AST`语法树,通过语法树就可以分析这个模块是否还有依赖的模块,进而继续循环执行下一个模块的编译解析。 >最终`Webpack`打包出来的`bundle`文件是一个`IIFE`的执行函数。