前端面试工程化
Contents
1 常见loader和plugin有哪些,二者的区别是什么?
-
常见
loader
babel-loader
把ES6+转义为ES5ts-loader
把TS编译为JS,并提示类型错误markdown-loader
把markdown变成htmlhtml-loader
把html变成js字符串sass-loader
把Sass/Scss变成css(一般与6、7搭配使用)css-loader
把css变成js字符串(一般与7搭配使用)style-loader
把js字符串变成style标签(一般与6搭配使用)postcss-loader
把css变成更优化的css(需要在6之前使用)vue-loader
把单文件组件变成js模块thread-loader
用于多进程打包
-
常用
plugin
html-webpack-plugin
用于创建HTML页面并自动引入JS和CSSclean-webpack-plugin
用于清理之前打包的残余文件mini-css-extract-plugin
用于将JS中的CSS抽离成单独的CSS文件,以解决js改动导致css重新加载的问题SplitChunkPlugin
用于代码分包DllPlugin + DllReferencePlugin
用于避免大依赖被频繁重新打包,大幅降低打包时间(例如react)eslint-webpack-plugin
用于检查代码中的错误DefinePlugin
用于在webpack config中添加全局变量copy-webpack-plugin
用于拷贝静态文件到dist
-
二者区别
- loader是文件加载器
- 功能:能够对文件进行编译(babel)、优化(postcss)、压缩等
- 运行时机:在创建最终产物之前运行
- plugin是webpack插件
- 功能:对webpack功能的扩展,比如定义全局变量、加速编译等
- 运行时机:在整个打包过程(包括前后)都能运行
- loader是文件加载器
2 Webpack如何解决开发时的跨域问题
在开发环境下,用js直接访问后端接口会出现跨域的问题
为了解决这个问题,可以在webpack.config.js中添加如下配置
|
|
3 如何实现Tree-Shaking
-
是什么
- tree-shaking就是让没有用到的js代码不打包,以减小包的体积
-
怎么做
-
如何开启
- 在
webpack.config
中将mode
设置为production
(开发环境没必要tree-shaking)即可
- 在
-
怎么shake
-
使用**
ES Modules
语法**(即ES6的import
和export
关键字) -
CommonJS
语法无法tree-shaking(即require
和exports
语法)- 需要给
babel-loader
添加modules: false
选项,禁止babel将代码转译为CommonJS的形式
- 需要给
-
引入的时候只引用需要的模块
-
要写
import { isEmpty } from 'lodash-es'
,因为方便tree-shaking(后缀的es表示这个库是用ES modules写的) -
不要写
import _ from 'lodash'
,因为会导致无法tree-shaking无用模块
-
-
-
怎么保证不被shake:在
package.json
中配置sideEffects
,防止某些文件被shake- 例如import了
x.js
,而x.js只是增加了window.x
属性,那么x.js就要放到sideEffects中 - 全部被import的
CSS
也都要放在sideEffects
中
- 例如import了
-
4 如何提高webpack构建速度
- 使用
DllPlugin
将不常变化的代码提前打包,并复用;如vue
、react
- 使用
thread-loader
或HapplyPack(过时)进行多线程打包 - 处于开发环境时,在
webpack.config
中将cache
设为true
- 处于生产环境时,关闭不必要的环节,比如可以关闭
source map
(在浏览器调试时能定位源文件代码)
5 webpack和vite的区别
-
开发环境
- vite自己实现server,**不对代码打包,仅进行路径的映射,**充分利用浏览器对
<script type=module>
的支持- 该server仅仅会改变import的路径,即
import {createApp} from 'vue'
改为import {createApp} from '/node_modules/.vite/vue.js'
,这样浏览器就知道去哪里找vue.js了
- 该server仅仅会改变import的路径,即
- webpack在开发环境会使用
babel-loader
基于内存提前打包好,这是其比vite慢的主要原因之一- 该server会把vue.js的代码打包进main.js
- vite自己实现server,**不对代码打包,仅进行路径的映射,**充分利用浏览器对
-
生产环境
- vite使用
rollup + esbuild(go)
打包JS代码 - webpack使用
babel(js)
来打包JS代码,比esbuild要慢很多
- vite使用
-
文件处理时机
- vite只会在请求某个文件时处理该文件(先请求再打包)
- webpack会提前打包好main.js,请求时候直接输出打包好的js(先打包再请求)
-
vite缺点
- 热更新常常失效(刷新即可)
- rollup生态较webpack还是有一定差距
- 兼容性差,不支持非现代浏览器
6 webpack如何配置多页应用
通过chunks与js关联
7 webpack编译过程
-
babel原理
- 将code解析为AST,遍历AST进行修改(ES5),最后基于新的AST生成code
-
递归分析js文件的依赖关系
-
构建流程:
- 启动构建,读取与合并配置参数,加载 Plugin,实例化 Compiler
- 从 Entry 出发,针对每个 Module 串行调用对应的 Loader 去翻译文件的内容,再找到该 Module 依赖的 Module,递归地进行编译处理
- 将编译后的 Module 组合成 Chunk,将 Chunk 转换成文件,输出到文件系统中
- 在以上过程中,
Webpack
会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。
-
Webpack 的 Tapable 事件流机制保证了插件的有序性,使得整个系统扩展性良好。
Author gsemir
LastMod 2021-05-19