likes
comments
collection
share

从零开始的中大厂前端项目落地(四)

作者站长头像
站长
· 阅读数 39

我正在参加「掘金·启航计划」

从零开始的中大厂前端项目落地(四)

落地一个前端项目涉及非常多知识,因此从6个角度入手,化整为零,逐个击破:

  1. 选择合适的构建工具
  2. 定制团队代码规范
  3. 测试工具
  4. 封装自己的组件
  5. 自动部署
  6. 安全

深入构建工具

通过前面三章,我们的项目已具雏形。但是复盘了下前三篇,感觉对构建工具讲述的不够深入,所以在向前推进之前,打算再用一两篇文章来补充之前讲的不够深入的地方。

在前端构建工具泛滥的今天,webpack凭借统一资源构建模型以及极强的开放性稳稳地占据C位,可谓AKA构建大哥了。紧跟其后是GulpViteRollup

有很多同学觉得这些构建工具不必深入研究,日常工作中修改webpack配置的占比不高,想到用的时候再去看文档。其实不然,如果有空闲时间,还是有必要主动地对这些构建工具有更深的见解。

《从零开始的中大厂前端项目落地(四)》将深入构建工具中的大哥webpack,和webpack的亲儿子turbopack,以及他们强劲的对手vite

由于篇幅有限,turbopackvite留到下篇文章。

webpack构建工具

深入构建工具,本篇文章打算从两个方向向webpack入手,一是从webpack的底层工作流揭开webpack打包的流程,另一个则是从webpack的配置掌握其用法。

    webpack的底层工作流

我们先来看下面这个图:

从零开始的中大厂前端项目落地(四)

整个构建过程可以分成三个阶段,分别是:初始化阶段、构建阶段(编译阶段)、封装阶段。

简单总结起来,流程大概如下:

  • 首先webpack会从shell语句中读取参数(如果有的话),再读取项目中的webpack.config.js文件,然后将所有参数结合,得出最终的参数。

  • 接着将创建编译对象Compiler,以及将你的项目中webpack所需的插件实例化,在webpack事件流上挂载插件钩子。

  • 然后根据配置的entry参数确定所有的入口文件,调用 compilation.addEntry 将入口文件转换为 dependence 对象。

  • 确定入口文件后,初始化阶段结束。

  • 开始构建阶段(编译阶段),根据入口文件进行依赖收集,对所有依赖的文件进行编译,调用 loader 将模块转译为标准 JS 内容,调用 JS 解析器将内容转换为 AST 对象,从中找出该模块依赖的模块,再 递归 处理这些依赖模块,直到所有入口依赖的文件都经过了本步骤的处理。

  • 所有依赖的文件都被处理过后,构建阶段结束。

  • 开始封装阶段,就是将编译后的内容重新打包,输出到配置好的output中。

需要强调的是,在构建过程中,webpack和插件都采用基于事件流的发布订阅模式,监听某些构建节点,并在这些环节中执行plugin等任务。

从上面webpack整个执行过程中可以看出,三个阶段都有各自的重点,缺一不可,但是构建阶段(编译阶段)却是重中之重,下面来细看编译过程:

从零开始的中大厂前端项目落地(四)

    webpack的配置

webpack的配置非常繁多,很多人只在项目初期使用,使用的时候还得查阅文档,但是过一阵子不用的话又会忘记。我个人记性不好,只能把配置抽出来,做成脑图,以备后续之需。

下面来看看webpack的基本配置:

从零开始的中大厂前端项目落地(四)

  • 输入输出,可以在这里配置webpack的入口起点和产物输出路径。

  • 后处理配置,包括mode、optimization、target,这三个配置项都是跟产物有关:

    • 其中mode负责声明环境变量,例如prod,则输出压缩后的产物

    • optimization用于webpack的代码压缩、混淆等,从webpack4开始会根据mode执行不同优化,但是所有优化还是能手动配置

    • 而target用于配置编译产物的目标运行环境,支持 web、node、electron 等值,不同值最终产物会有所差异

  • 开发类配置,常见的devServer、devtool、watch,在本地开发环境相关

    • devServer用于开启HRM热替换,使得开发变得更丝滑
  • 性能优化配置有performance、cache等

编译阶段相关的配置

除了以上的配置,还有与构建阶段(编译阶段)相关的配置:

从零开始的中大厂前端项目落地(四)

这几个配置项是我们日常与webpack打交道最多的几个

  • resolve配置,配置模块解析,用法如下:
// webpack.config.js

module.exports = {
  //...
  resolve: {
    // configuration options
  },
};

常用的有alias、extensions、fallback、mainFiles、modules、plugins、cachePredicate、roots

字段描述解析
alias使用别名通过resolve.alias.util:path.resolve(__dirname, 'src/util/')设置util别名
extensions指定解析顺序如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀
fallback重定向模块-
mainFiles解析的文件名-
modules解析的模块-
plugins额外的插件-
cachePredicate是否缓存决定请求是否应该被缓存的函数。函数传入一个带有 path 和 request 属性的对象。 必须返回一个 boolean 值
roots解析的目录-

  • module就是用来处理不同类型的模块,先来看看module有哪些配置项:
字段描述解析
generator使用生成器统一设置rules.generator
parser使用解析器统一设置rules.parser
noParse忽略文件-
unsafeCache缓存解析-
rules解析的模块配置模块的规则,使用频率最高的配置项

rules的配置项又可以分为三类:匹配规则(条件)、处理模块

  • 匹配规则(条件)

    • test(与resource.test冲突)

      • test以字符串、正则表达式、函数、数组去匹配资源

        • 字符串匹配绝对路径

        • 函数返回值也为绝对路径

        • 正则匹配到的资源

        • 数组可以传入多个,以字符串、正则、函数组成

    从零开始的中大厂前端项目落地(四)

    • exclude(与resource.exclude冲突)

      • 排除exclude以下任何条件的模块,规则和test一样
    • include(与resource.include冲突)

      • 引入符合include以下任何条件的模块,规则和test一样
    • resource,更具体的筛选资源项

      • resource里面也能配置test、exclude、include
    • resourceQuery,更具体的筛选资源项,与resource的区别是resourceQuery匹配Query

    • schema

    • type,匹配文件类型

      • type可以设置的值:'javascript/auto' | 'javascript/dynamic' | 'javascript/esm' | 'json' | 'webassembly/sync' | 'webassembly/async' | 'asset' | 'asset/source' | 'asset/resource' | 'asset/inline'

  • 处理模块

    • use可以用字符串、函数、数组传入一个或多个loader

    从零开始的中大厂前端项目落地(四)

    从零开始的中大厂前端项目落地(四)

    • resolve可以配置该模块层级的解析,而不采用全局resolve解析

  • plugins,webpack的插件配置项,plugins是webpack的核心。plugins接收一个数组,用法如下

从零开始的中大厂前端项目落地(四)

下面看看webpack的一些小技巧

从零开始的中大厂前端项目落地(四)

最后,让我们一起加油吧!

从零开始的中大厂前端项目落地(四)

参考资料:

webpack.js.org/ 2022.stateofjs.com/en-US/libra… juejin.cn/book/711559…

转载自:https://juejin.cn/post/7246641306893303866
评论
请登录