Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

工程化面试题 #5

Open
mewcoder opened this issue Mar 15, 2024 · 8 comments
Open

工程化面试题 #5

mewcoder opened this issue Mar 15, 2024 · 8 comments

Comments

@mewcoder
Copy link
Owner

No description provided.

@mewcoder
Copy link
Owner Author

mewcoder commented Mar 15, 2024

Vite为什么快,说一下你对 Vite 的理解

Vite 作为一款新的前端构建工具

Vite 的开发服务器是基于 ES Module 实现了按需编译,一个import对应一个请求,vite接收到请求进行编译返回。

而webapck启动开发服务,是先打包再加载,打包是递归所有依赖树,比较慢。

对于第三方模块 vite会进行预构建

  • 将以 CommonJS / UMD 形式提供的依赖项转换为 ES 模块

  • 将那些具有许多内部模块的 ESM 依赖项转换为单个模块,如 lodash-es

  • 使用esbuild 编译和打包,原生语言,利用多核并发限制,AST共有 ,所以性能更快。

  • vite 生产打包是基于 rollup 的,有丰富的插件生态。

  • 开发阶段和生产阶段可能会有差异

  • vite 团队在使用 rust 开发 rolldown

@mewcoder
Copy link
Owner Author

mewcoder commented Mar 25, 2024

Tree-shaking

Tree-Shaking 它基于 ES Module 的静态分析特性,打包工具可以分析出项目中哪些导出的代码实际上没有被导入使用。移除未引用的代码(dead-code),减少打包体积。最早是由 rollup 实现的
条件:

  • 基于ESM
  • 打包工具支持 rollup、webpack等

webpack实践

  • 在生产模式下,启动代码优化功能,通过 terser 删除 dead code(默认开启了usedExports以标记未使用的导出、也可用/*#__PURE__*/标注纯函数 )

  • webpack 默认会保留有副作用(全局变量,立即执行函数、 打印等)的代码,所以需要配置 sideEffects

  • 引入的包package.json声明sideEffects:false 代表可以安全地进行 tree-shaking;也可以声明不能被剔除的文件数组,如 css 文件。

NPM包设计

  • 打包生成 esm 格式的文件,并声明在 package.json 中的 module 指定为 ES6文件入口,以及 sideEffects

  • 基于 rollup 打包,webpack5之前 不支持生成 es2015 代码

  • 如果不基于ESM,比如组件库,可基于 babel-plugin-import 实现按需加载, 利用 babel 插件 对import语句进行转换,比如import {Button} from 'xxx' 变为 import button from 'xxx/button'

@mewcoder
Copy link
Owner Author

Webpeck 构建流程

  • 初始化阶段:
    • 从命令行中参数和配置文件,得到配置对象
    • 创建 Compiler 实例,并注册 Plugin
  • 编译阶段:
    • 从入口文件出发,调用 Loader 进行转译,根据 AST 递归所有依赖的模块
    • 递归处理完所有依赖后,得到依赖关系图
  • 输出阶段:
    • 根据依赖关系图,组装成一个个包含多个模块的 Chunk
    • 然后把 Chunk 转换成单独的文件加入到输出列表,这步可以修改输出内容,比如压缩,分离css
    • 最后根据是输出配置写入到文件系统

源码文件是 module,打包产物是 bundle

webpack 会在特定的时间点广播特定的事件,插件监听到特定的事件执行对应的逻辑,并可以调用 Webpack 提供的 API,改变构建结果。

@mewcoder
Copy link
Owner Author

mewcoder commented Mar 26, 2024

了解过Babel吗?写过Babel插件吗

AST :抽象语法树,对代码的一种结构化表示,是树形结构。应用:代码高亮,JS转义,代码压缩,ESLint,Prettier等

babel 编译 ES5 的过程:parse(词法分析 语法分析生成AST)、transform(通过 traverse 遍历 AST 进行处理转换)、generator (生成代码)

babel插件可以修改AST,
访问者模式:被操作的数据结构比较稳定,而操作逻辑需要自定义,为了分离逻辑和数据结构。

@mewcoder
Copy link
Owner Author

mewcoder commented Mar 28, 2024

pnpm

npm问题:

  • node_modules 扁平化的结构允许访问没有在 package.json 中声明的依赖,导致幽灵依赖

  • 相同依赖的不同版本,谁在根目录是由安装顺序决定的,会导致重复安装,分身依赖问题

  • 不同的前端项目无法复用安装过的依赖,重复安装,导致磁盘浪费。

    • 硬链接可以避免重复安装,节省空间,速度更快
    • 硬链接: 保证相同的包不会被重新新增,磁盘的目录下,inode相同,数据共享,节省内存,修改会同步更改
    • 软链接(符号链接):相当于快捷方式,node_modules 里的软链接到对应的.pnpm下的依赖,解决幽灵依赖问题
    • 符号链接是指向目标路径的链接,而硬链接则是指向目标数据对象的链接
    • 自带monorepo

@mewcoder
Copy link
Owner Author

mewcoder commented Apr 3, 2024

CommonJS 和 ES Module

1. 说区别

  • CJS 模块输出的是一个值的浅拷贝,ESM模块输出的是值的引用(导出的是内存地址,动态绑定)。
  • CJS 模块是运行时加载,ESM 模块是编译时通过静态分析就能确定模块依赖关系及输入输出(可以tree-shaking)。
  • CJS 模块同步加载并执行模块文件,ESM 模块提前加载并执行模块文件

2. 循环引用问题

  • CJS:运行时加载并执行模块,具体结果基于代码执行的位置,模块默认的值为空对象;会缓存已加载的模块,防止循环引用问题
  • ESM:JS引擎会缓存模块加载记录,ESM是动态引用的,需要开发者保证取值的时候能取到值

3. 说CJS原理

  • 读取文件为字符串,包裹为可执行函数,传入requiremoduleexports等参数执行。
  • module.exports默认指向一个空对象,也可以被修改;exportsmodule.exports的引用

4. ESM 和 no bundle

  • vite devserver
  • import map
  • 预构建

@mewcoder
Copy link
Owner Author

mewcoder commented Apr 3, 2024

package.json 的 dependencies

  • dependencies 表示项目依赖,devDependencies 表示开发阶段用到的依赖,比如一些打包相关的,
  • 安装一个 npm 包其中 dependencies 会自动下载;在业务项目中,只是一个规范作用 npm install 时都会被下载
  • peerDependencies 表示同版本依赖,npm 7之前不会自动安装,之后会自动安装,可能会出现问题,需要忽略安装 peerDependencies
  • package-lock.json需要提交到代码库,但发布 npm 需要忽略
  • 版本号:主版本号.次版本号.修订号
    • ^ 更新次版本和修改号
    • ~ 只更新修订版本

@mewcoder
Copy link
Owner Author

mewcoder commented Apr 3, 2024

命令行解析

process.argv 返回当前进程的所有命令行参数,返回值是一个数组,前2个元素是命令路径和被执行的文件路径.
一般使用库,如commander

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant