- webpack是什么?
- webpack与grunt、gulp的不同?
- webpack中什么是chunk?什么是bundle?
- Webpack 五个核心概念分别是什么?
- 有哪些常见的Loader?它们是解决什么问题的?
- 有哪些常见的Plugin?它们是解决什么问题的?
- webpack的构建流程是什么?
- webpack的热更新是什么?
- 如何利用webpack来优化前端性能?
- npm打包时需要注意哪些?如何利用webpack来更好的构建?
- hash、chunkhash、contenthash三者的区别?
1.webpack是什么?
- 一种前端资源构建工具,一个静态模块打包器(nodule bundle)
- 前端所有资源文件(js/json/css/img…)都会作为模块处理
- 它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)
2. webpack与grunt、gulp的不同?
- grunt和gulp是基于任务流(Task、Stream)的。类似jQuery,找到一个(或一类)文件,对其做一系列链式操作,整条链式操作构成了一个任务,多个任务就构成了整个web的构建流程
- webpack是基于入口的。webpack会自动地递归解析入口所需要加载的所有资源文件,然后用不同的Loader来处理不同的文件,用Plugin来扩展webpack功能
3. 什么是chunk?什么是bundle?
- 首先告诉 Webpack 一个入口文件,如 index.js 为起点作为打包,将入口文件的所有依赖项引入进来,这些依赖会跟入口文件形成一个文件(代码块),这个文件(代码块)就是 chunk
- 将这个代码块(chunk)进行处理,比如把 less 文件编译成 css,js 资源编译成浏览器能识别的 js 语法等等操作,这些就叫做打包,将打包好的资源再输出出去,这个输出的文件就叫 bundle
4. Webpack 五个核心概念分别是什么?
-
Entry
入口(Entry)指示 Webpack 以哪个文件为入口起点开始打包,分析内部构件依赖图
-
Output
输出(Output)指示 Webpack 打包后的资源 bundles 输出到哪里去,以及如何命名
-
Loader
Loader 能让 Webpack 处理非 JavaScript/json 文件(Webpack 自身只能处理 JavaScript/json )
-
Plugins
插件(Plugins)可以用于执行范围更广的任务,包括从打包优化和压缩到重新定义环境中的变量
-
Mode
模式(Mode)指示 Webpack 使用相应模式的配置,只有development(开发环境)和production(生产环境)两种模式
5.有哪些常见的Loader?它们是解决什么问题的?
- css-loader:将 css 文件变成 CommonJS 模块加载 js 中,里面内容是样式字符串
- style-loader:创建 style 标签,将 js 中的样式资源插入进行,添加到 head 中生效
- url-loader:在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
- file-loader:打包其他资源(除了css/js/html 资源)
- html-loader:处理 html 文件中的 img
- babel-loader:把 ES6 转换成 ES5
- eslint-loader:通过 ESLint 检查 JavaScript 代码
6.有哪些常见的Plugin?它们是解决什么问题的?
- html-webpack-plugin:可以复制一个有结构的html文件,并自动引入打包输出的所有资源(JS/CSS)
- clean-webpack-plugin:重新打包自动清空 dist 目录
- mini-css-extract-plugin:提取 js 中的 css 成单独文件
- optimize-css-assets-webpack-plugin:压缩css
- uglifyjs-webpack-plugin:压缩js
- commons-chunk-plugin:提取公共代码
7.webpack的构建流程是什么?
- 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;
- 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
- 确定入口:根据配置中的 entry 找出所有的入口文件;
- 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;
- 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
- 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
- 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统
8.webpack的热更新是什么?
热更新又称热替换(Hot Module Replacement),缩写为HMR,基于devServer,生产环境不需要devServer,所以生产环境不能用HMR功能
作用:
优化打包构建速度,一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块),极大提升构建速度
-
样式文件:可以使用HMR功能,因为style-loader内部实现了
-
JS文件:默认没有HMR功能,需要修改js代码,添加支持HMR功能。入口文件做不了HMR功能,只能处理非入口js文件
-
HTML文件:默认没有HMR功能,同时会导致 html 文件不能热更新(即修改没有任何反应)
解决方案:
修改entry入口,将html文件引入
entry:['./src/js/index.js','./src/index.html']
不用做HMR功能,因为只有一个html文件
9.如何利用webpack来优化前端性能?
开发环境下:
- 开启HMR功能,优化打包构建速度
- 配置 devtool: ‘source-map’,优化代码运行的性能
生产环境下:
- oneOf 优化
默认情况下,假设设置了7、8个loader,每一个文件都得通过这7、8个loader处理(过一遍),浪费性能,使用 oneOf 找到了就能直接用,提升性能 - 开启 babel 缓存
当一个 js 文件发生变化时,其它 js 资源不用变 - code split 分割
将js文件打包分割成多个bundle,避免体积过大 - 懒加载和预加载
- PWA 网站离线访问
- 多进程打包
开启多进程打包,主要处理js文件(babel-loader干的活久),进程启动大概为600ms,只有工作消耗时间比较长,才需要多进程打包,提升打包速度 - dll 打包第三方库
- code split将第三方库都打包成一个bundle,这样体积过大,会造成打包速度慢
- dll 是将第三方库打包成多个bundle,从而进行速度优化
10.npm打包时需要注意哪些?如何利用webpack来更好的构建?
NPM模块需要注意以下问题:
- 要支持CommonJS模块化规范,所以要求打包后的最后结果也遵守该规则
- Npm模块使用者的环境是不确定的,很有可能并不支持ES6,所以打包的最后结果应该是采用ES5编写的。并且如果ES5是经过转换的,请最好连同SourceMap一同上传
- Npm包大小应该是尽量小(有些仓库会限制包大小)
- 发布的模块不能将依赖的模块也一同打包,应该让用户选择性的去自行安装。这样可以避免模块应用者再次打包时出现底层模块被重复打包的情况
- UI组件类的模块应该将依赖的其它资源文件,例如.css文件也需要包含在发布的模块里
webpack配置做以下扩展和优化:
- CommonJS模块化规范的解决方案: 设置output.libraryTarget='commonjs2’使输出的代码符合CommonJS2 模块化规范,以供给其它模块导入使用
- 输出ES5代码的解决方案:使用babel-loader把 ES6 代码转换成 ES5 的代码。再通过开启devtool: 'source-map’输出SourceMap以发布调试。
- Npm包大小尽量小的解决方案:Babel 在把 ES6 代码转换成 ES5 代码时会注入一些辅助函数,最终导致每个输出的文件中都包含这段辅助函数的代码,造成了代码的冗余。解决方法是修改.babelrc文件,为其加入transform-runtime插件
- 不能将依赖模块打包到NPM模块中的解决方案:使用externals配置项来告诉webpack哪些模块不需要打包。
- 对于依赖的资源文件打包的解决方案:通过css-loader和extract-text-webpack-plugin来实现
11.hash、chunkhash、contenthash三者的区别?
浏览器访问网站后会强缓存资源,第二次刷新就不会请求服务器(一般会定个时间再去请求服务器),假设有了bug改动了文件,但是浏览器又不能及时请求服务器,所以就用到了文件资源缓存(改变文件名的hash值)
-
hash:不管文件变不变化,每次wepack构建时都会生成一个唯一的hash值
-
chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
问题:js和css同属于一个chunk,修改css,js文件同样会被打爆
-
contenthash:根据文件的内容生成hash值。不同文件hash值一定不一样