前端工程化

# 前端工程化

# 👀Webpack

# 1.babel的转译过程?以ES6代码转译为ES5代码为例。

  1. ES6代码输入。

  2. babylon进行解析得到AST。

  3. plugin用babel-traverse遍历AST转译,得到新的AST树。

  4. 用babel-generator通过AST树生成ES5代码。

# 2.babel如何处理async错误捕获转换的?

# 3. 什么是模块化?

  • 模块化就是为了减少系统耦合度,提高内聚,减少资源循环依赖,增强系统框架设计。
  • 让开发者便于维护,同时也让逻辑相同的部分可复用
  • 模块化开发:针对js、css,以功能业务为单元组织代码。js方面解决独立作用域、依赖管理、api暴露、按需加载与执行、安全合并等问题,css方面解决依赖管理、组件内部样式管理等问题。

# 4. 谈谈你对webpack的看法

本质上,webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具

当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图,然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。

它可以很好地管理、打包开发中所用到的HTML,CSS,JavaScript和静态文件(图片,字体)等

# 5. webpack的基本功能和工作原理?

基本功能:

  • 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等。
  • 文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等。
  • 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
  • 模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件。
  • 自动刷新:监听本地源代码的变化,自动构建,刷新浏览器
  • 代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过
  • 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。

构建过程:

  • 从entry里配置的module开始递归解析entry依赖的所有module
  • 每找到一个module,就会根据配置的loader去找对应的转换规则
  • 对module进行转换后,再解析出当前module依赖的module
  • 这些模块会以entry为单位分组,一个entry和其所有import的module被分到一个组initial-chunk,而动态导入的module则分到另外一个组non-chunk
  • 最后webpack会把所有Chunk转换成文件输出
  • 在整个流程中webpack会在恰当的时机执行plugin里定义的逻辑

打包原理

  • 将所有依赖打包成一个bundle.js,通过代码分割成单元片段按需加载

# 6. webpack使用的代码压缩库是?

terser (opens new window)

# 7. 什么是bundle,chunk,module?

可以查看术语表 (opens new window)

  • bundle 由许多不同的模块生成,包含已经经过加载和编译过程的源文件的最终版本。

  • chunk是webpack的特定术语,在内部用于管理捆绑过程,也可以理解为webpack在进行模块的依赖分析的时候,代码分割出来的代码块。

  • module是开发中的单个模块,在webpack中一个文件就是一个模块。

# 8. treeShaking原理?

treeShaking就是移除 JavaScript 上下文中的未引用代码(dead-code),它依赖于 ES2015 模块语法的 静态结构 (opens new window) 特性,例如 import 和 export,所以要使用webpack的treeshaking必须使用importexport

在webpack5中已经自带tree-shaking功能,在打包模式为production时,默认开启 tree-shaking功能。

默认情况下,无论有没有使用导入的模块,webpack在tree-shaking的时候会使用terser对导入的模块进行副作用分析以决定是否打包该模块中的内容。但是这样可能就会造成打包时间的增加。可以在webpack的配置中设置sideEffects值为需要进行副作用分析的文件的数组。

# 9. webpack的打包过程?

打包过程可以分为3个阶段:初始化阶段、打包阶段、输出阶段。

  • 初始化配置:根据配置文件和命令行配置参数得到最终的配置对象。

  • 加载插件:根据配置对象初始化compiler对象,加载所有插件,调用compiler实例的run方法执行编译。

  • 确定打包入口:根据配置的entry找到入口文件,对文件中的依赖调用对应的loader进行递归转移成可用模块。

  • 完成模块编译:根据AST分析出依赖关系,得到模块最终被转译后的内容。

  • 输出资源:根据入口和模块的关系,组装成一个个包含多个模块的chunk,再把每个chunk转换成单独的文件传入到输出列表。

  • 输出完成:在确定好输出内容之后,根据配置的路径和文件名,把内容写入到产物中。如果是non-initial-chunk,就是动态导入的模块,会使用它唯一的id命名,也可以使用魔术注释命名。

# 👀Git

# 1.了解常见的commit的命名规范吗?

 'feat', // 新功能 feature:产品、技术需求、技术优化等功能开发
 'fix', // 一个错误修复
 'refactor', // 重构(既不增加新功能,也不是修复bug)
 'docs', // 仅文档更改
 'test', // 添加缺失的测试或更正现有的测试
 'chore', // 文档、辅助工具等的修改
 'style', // 不影响代码含义的更改(空白,格式,缺少分号等)
 'perf', // 改进性能的代码更改
 'revert', // 回退

 // eg: 'feat: 添加了图表功能'