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的区别
module,chunk和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
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
- ingorePlugin 避免引入无用模块
- happyPack 多进程打包
- PalralleUglifyplugin
下面的不可用于生产环境
- 自动刷新
- 热更新
- DllPlugin
12 webapck 性能优化--产出代码
- 小图片base64编码,减少一次网络请求
- bandle加hash: 内容变hash才变,然后才更新,否则用缓存
- 懒加载: 大型文件不着急使用的文件使用import懒加载
- 提取公共代码,splitChunks: {chunks: all}, 作为公共包重复引用
- IgnorePlugin
- 使用CDN加速
然后npm run build打包,将打包后的dist目录上传到cdn服务器上
图片也可以传到cdn
- 使用production
会自动开启代码压缩,
会启动TreeShaking(只有es6Module才能让treeShaking生效,commjs不行)
Vue/react会自动删掉调试的代码(如开发环境的warning)
- Scope Hosting 打包后的每个文件都会生成一个函数,scopeHosting把多个函数合并成一个函数
- 代码体积更小
- 代码可读性更好
- 创建作用于更少,占用的内存就会少
13 补充:如何抽取公共js
使用spilitChunks, chunks设置为all
14 Es6Module和commonjs的区别
- es6Module是静态引入,编译时引入
- commonjs是动态引入,执行时引入
- 只有es6module才能静态分析,实现treeShaking
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中配置sideEffets和module,其次使用者需要使用webpack。