webpack面试题

440 阅读6分钟

1 基础篇

1 五大核心模块

  • entry: 指示webpack从哪个文件开始打包
  • output: 指示webpack打包后的文件输出到哪里去,如何命名
  • mode: 开发模式development 生产模式production
  • loader: webpack本身只能处理js、json,其他资源需要借助loader处理,放在module中
  • plugin: 扩展webpack的功能

2 高级篇

1 sourceMap

  • 为什么: 因为编译后的代码如果运行出错,提示的错误位置我们是看不懂的,所以我们需要更加准确的错误提示,帮助我们更好的开发代码。
  • 是什么: 源代码映射,是一个用来生成源代码与构建后的代码一一映射的文件的方案。它会生成一个xxx.map文件,里面包含源代码与构建后的代码每一行、每一列的映射关系。当构建后代码出错了,会通过xxx.map文件,从构建后代码出错位置映射到源代码出错位置,从而让浏览器提示源代码出错位置,帮助我们更快地找到出错根源。
  • 怎么用:
devtool: 'source-map', // 有行和列的映射,生产环境
devtool: 'cheap-module-source-map', // 只有行的映射,开发环境

2 treeShaking

  • 为什么:开发时我们定义一些工具函数库,或引入了第三方工具函数库或组件库。如果没有特殊处理,我们打包会引入整个库,实际上我们可能只用到了其中的一小部分,此时就需要treeshaking。
  • 是什么:移除js中没有使用上的代码。
  • 怎么用:webpack已经开启了这个功能,无需其他配置

3 面试真题

1 前端为何要进行打包和构建

从代码层面来说:
  • 体积更小,加载更快(TreeShaking, 代码压缩合并)
  • 编译高级语言或语法(Ts,es6,模块化,scss)
  • 兼容性和错误检查(polyfill,postcss,eslint)
polyfill: 一段兼容性代码,通过判断当前浏览器支持的特性,实现一个可跨浏览器使用的功能。
比如,一个浏览器如果不支持class,我们就用构造函数实现,这样的兼容性代码就是polyfill。
从研发流程来说:(提高整个部门的开发效率)
  • 统一高效的开发环境
  • 统一的构建流程和产出标准
  • 集成公司构建规范(提测、上线等)

2 module/chunk/bundle的区别

  • modulechunk 和 bundle 其实就是同一份逻辑代码在不同转换场景下取的是三个名字:
  • 直接写出来的是module,webpack处理时是chunk,最后生成浏览器可以直接运行的是bundle
module:各个源码文件,webapck中一切皆模块;
chunk:多模块合并成的还没有产出的代码块
bundle: 最终的输出文件

3 loader和plugin区别

  • loader 模块转换器, webpack本身只能处理js、json,其他资源需要借助loader处理,比如less-loader,babel-loader
  • plugin 插件,扩展webpack的功能。比如htmlWebpackPlugin,就是在原html模板的基础上自动引入编译好的js/css

4 常见的loader和plugin有哪些

  • loader
style-loader: 创建style标签,在html中引入css
css-loader: 将css编译成commjs模块到js中
less-loader: 将less转为css
babel-loader: es6- es5
  • plugin
    eslintplugin: 开启eslint检查
    htmlWebpackPlugin: 在原html模板的基础上生成新的html文件,并自动引入编译好的js/css
    CssMinimizerPlugin: 压缩css
    MiniCssExtractPlugin: 提取css为单独文件,使用link加载css

5 babel与webapck的区别

  • babel:js新语法编译工具,不处理模块化,不处理新的api
  • webpack:打包构建工具,是多个loader和plugin的集合

6 babel-polyfill 与babel-runtime的区别

  • bable-polyfill 就是core.js与regenerator的集合,是官方的高级语法的补丁集合,Babel7.4之后被弃用,推荐直接使用core.js与regenerator。
  • 但是会污染全局环境。如果做一个独立的web系统,则无碍;如果做一个第三方lib,则有问题。所以,需要babel-runtime
  • babel-runtime:不会污染全局环境。如果开发第三方库,必须用runtime

7 webpack如何实现懒加载

import(/* webpackChunkName: "con" */ './con.js')

8 如何产出一个lib

image.png

9 为何proxy不能被polyfill

  • Class可以用function模拟
  • Promise可以用callback模拟
  • Proxy没有任何现成的语法可以模拟

10 webpack有哪些常见的性能优化手段

开发环境优化:

  • 使用HMR优化构建打包速度,在某个模块发生变化时,只重新打包该模块
  • 使用soureMap优化代码调试,精准找到bug的代码位置 生产环境优化: ~ 优化速度
  • 使用oneOf优化loader的查找,让loader查找到一个合适的就不再继续查找
  • 开启多线程,提高打包速度,比如使用thread-loader ~ 优化代码运行性能
  • 使用treeShaking,去除多余代码,优化代码运行性能
  • 使用prefetch、preload等预加载,优化代码运行性能
  • 使用import动态引入某组件,实现按需加载某模块

11 webpack如何优化构建速度

  • 优化babel-loader image.png
  • ingorePlugin 避免引入无用模块 image.png image.png
  • happyPack 多进程打包

image.png

image.png

  • PalralleUglifyplugin

image.png 下面的不可用于生产环境

  • 自动刷新 image.png
  • 热更新 image.png image.png image.png
  • DllPlugin image.png

12 webapck 性能优化--产出代码

  • 小图片base64编码,减少一次网络请求
  • bandle加hash: 内容变hash才变,然后才更新,否则用缓存 image.png
  • 懒加载: 大型文件不着急使用的文件使用import懒加载
  • 提取公共代码,splitChunks: {chunks: all}, 作为公共包重复引用
  • IgnorePlugin
  • 使用CDN加速 image.png 然后npm run build打包,将打包后的dist目录上传到cdn服务器上 image.png 图片也可以传到cdn image.png
  • 使用production
会自动开启代码压缩,
会启动TreeShaking(只有es6Module才能让treeShaking生效,commjs不行)
Vue/react会自动删掉调试的代码(如开发环境的warning)
  • Scope Hosting 打包后的每个文件都会生成一个函数,scopeHosting把多个函数合并成一个函数
  • 代码体积更小
  • 代码可读性更好
  • 创建作用于更少,占用的内存就会少

image.png

image.png

image.png

13 补充:如何抽取公共js

使用spilitChunks, chunks设置为all image.png

image.png

14 Es6Module和commonjs的区别

  • es6Module是静态引入,编译时引入
  • commonjs是动态引入,执行时引入
  • 只有es6module才能静态分析,实现treeShaking

image.png

15 如何让组件库实现按需引入

blog.csdn.net/sinat_33488… blog.csdn.net/qq_36362721… zhuanlan.zhihu.com/p/473188268

  • 以前使用babel-plugin-component
  • 现在组件本身就是esmodule模块,所以可以使用treeshaking。
首先,一个个导出组件
然后,在package.json 中增加module: index.js 字段,和sideEffects: false

总之,如果想按需加载一个组件库package-demo,首先组件库需要输出es modules模块规范,并在package.json中配置sideEffetsmodule,其次使用者需要使用webpack