likes
comments
collection
share

前端面试题之——webpack会问到的点

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

大家好,这是一个小白前端的更文挑战。(写错的各位看官包容) 这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战

前言

面试会问到的🈶️以下点,常用的loader和plugin这个应该大家都是知道,就不做赘述,其中比较重要的应该是最后一点,就是关于提高性能和体验的

  1. webpack与grunt、gulp的不同?
  2. 与webpack类似的工具还有哪些?谈谈你为什么最终选择(或放弃)使用webpack?
  3. 有哪些常见的Loader?他们是解决什么问题的?
  4. 有哪些常见的Plugin?他们是解决什么问题的?
  5. Loader和Plugin的不同?
  6. 是否写过Loader和Plugin?描述一下编写loader或plugin的思路?
  7. 如何利用webpack来优化前端性能?(提高性能和体验)

下面是我整理的关于以上问题的答案:

webpack与之相似的

rollup

  • 适用于基础库的打包,如vue、react

parcel

  • 适用于简单的实验性项目,他可以满足低门槛的快速看到效果

Loader

配置

  • Loader在module.rules中配置

常见的Loader

  • file-loader

    • 把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
  • url-loader

    • 和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
  • source-map-loader

    • 加载额外的 Source Map 文件,以方便断点调试
  • image-loader

    • 加载并且压缩图片文件
  • babel-loader

    • 把 ES6 转换成 ES5
  • css-loader

    • 加载 CSS,支持模块化、压缩、文件导入等特性
  • style-loader

    • 把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。
  • eslint-loader

    • 通过 ESLint 检查 JavaScript 代码
  • ...

常见的Plugin

Plugin在plugins中单独配置

常见的Plugin

  • define-plugin

    • 定义环境变量
  • commons-chunk-plugin

    • 提取公共代码
  • uglifyjs-webpack-plugin

    • 通过UglifyES压缩ES6代码
  • ...

Loader和Plugin的不同

loader

  • webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力

plugin

  • Plugin可以扩展webpack的功能,让webpack具有更多的灵活性

文件指纹是?

文件指纹是打包后输出的文件名的后缀

使用

  • Hash

    • 和整个项目的构建相关,只要项目文件有修改,整个项目构建的 hash 值就会更改
  • Chunkhash

    • 和 Webpack 打包的 chunk 有关,不同的 entry 会生出不同的 chunkhash
  • Contenthash

    • 根据文件内容来定义 hash,文件内容不变,则 contenthash 不变

在实际工程中,配置文件上百行乃是常事,如何保证各个loader按照预想方式工作

使用 enforce 强制执行 loader 的作用顺序

pre 代表在所有正常 loader 之前执行

post 是所有 loader 之后执行

如何优化 Webpack 的构建速度

使用高版本的 Webpack 和 Node.js

多进程/多实例构建:HappyPack(不维护了)、thread-loader

压缩代码

  • 多进程并行压缩

    • webpack-paralle-uglify-plugin
    • uglifyjs-webpack-plugin 开启 parallel 参数 (不支持ES6)
    • terser-webpack-plugin 开启 parallel 参数
  • 通过 mini-css-extract-plugin 提取 Chunk 中的 CSS 代码到单独文件,通过 css-loader 的 minimize 选项开启 cssnano 压缩 CSS。

图片压缩

  • 使用基于 Node 库的 imagemin (很多定制选项、可以处理多种图片格式)
  • 配置 image-webpack-loader

缩小打包作用域

  • exclude/include (确定 loader 规则范围)
  • resolve.modules 指明第三方模块的绝对路径 (减少不必要的查找)
  • resolve.mainFields 只采用 main 字段作为入口文件描述字段 (减少搜索步骤,需要考虑到所有运行时依赖的第三方模块的入口文件描述字段)
  • resolve.extensions 尽可能减少后缀尝试的可能性
  • noParse 对完全不需要解析的库进行忽略 (不去解析但仍会打包到 bundle 中,注意被忽略掉的文件里不应该包含 import、require、define 等模块化语句)
  • IgnorePlugin (完全排除模块)
  • 合理使用alias

提取页面公共资源

  • 基础包分离

    • 使用 html-webpack-externals-plugin,将基础包通过 CDN 引入,不打入 bundle
  • 使用 SplitChunksPlugin 进行(公共脚本、基础包、页面公共文件)分离(Webpack4内置) ,替代了 CommonsChunkPlugin 插件

DLL

  • 使用 DllPlugin 进行分包,使用 DllReferencePlugin(索引链接) 对 manifest.json 引用,让一些基本不会改动的代码先打包成静态资源,避免反复编译浪费时间。
  • HashedModuleIdsPlugin 可以解决模块数字id问题

充分利用缓存提升二次构建速度

  • babel-loader 开启缓存
  • terser-webpack-plugin 开启缓存
  • 使用 cache-loader 或者 hard-source-webpack-plugin

Tree shaking

Scope hoisting

  • 构建后的代码会存在大量闭包,造成体积增大,运行代码时创建的函数作用域变多,内存开销变大。Scope hoisting 将所有模块的代码按照引用顺序放在一个函数作用域里,然后适当的重命名一些变量以防止变量名冲突
  • 必须是ES6的语法,因为有很多第三方库仍采用 CommonJS 语法,为了充分发挥 Scope hoisting 的作用,需要配置 mainFields 对第三方模块优先采用 jsnext:main 中指向的ES6模块化语法

动态Polyfill

  • 建议采用 polyfill-service 只给用户返回需要的polyfill,社区维护

是否写过Plugin?简单描述一下编写Plugin的思路?

compiler 暴露了和 Webpack 整个生命周期相关的钩子

compilation 暴露了与模块和依赖有关的粒度更小的事件钩子

插件需要在其原型上绑定apply方法,才能访问 compiler 实例

Babel原理

解析:将代码转换成 AST

  • 语法分析:分析token流(上面生成的数组)并生成 AST
  • 词法分析:将代码(字符串)分割为token流,即语法单元成的数组

转换:访问 AST 的节点进行变换操作生产新的 AST

  • Taro就是利用 babel 完成的小程序语法转换

生成:以新的 AST 为基础生成代码