webpack面试题
- 1.webpack和vite区别
- 2.如何优化webpack打包速度?
- 3.说说webpack中常见的Plugin?解决了什么问题
- 4.说说如何借助webpack来优化前端性能?
- 如何优化
- JS代码压缩
- CSS代码压缩
- Html文件代码压缩
- 文件大小压缩
- 图片压缩
- Tree Shaking
- usedExports
- sideEffects
- css tree shaking
- 代码分离
- 内联chunk
- 5.说说webpack的热更新是如何做到的?原理是什么
- 6.说说webpack proxy工作原理?为什么能解决跨域?
- 一、是什么
- webpack-dev-server
- 二、工作原理
- 三、跨域
- 7.说说webpack中常见的Loader?解决了什么问题?
- 配置方式
- 二、特性
- 三、常见的loader
- css-loader
- style-loader
- less-loader
- raw-loader
- file-loader
- url-loader
- 8.说说你对webpack的理解?解决了什么问题?
- `webpack`的能力:
- 9.webpack的构建流程是什么
- 10.webpack的Loader和Plugin的不同
- 11.谈谈你对 Webpack的认识
1.webpack和vite区别
1.底层的语言
webpack
是基于nodejs
构建,js
是以毫秒计数。
vite
是基于esbulid
预构建依赖,esbulid
是采用go
语言编写的,go
语言是纳秒级别的。
因为js
是毫秒级别,go
语言是纳秒级别。所以vite
比webpack
打包器快10-100倍。
2.打包过程
webpack:分析各个模块之间的依赖=>然后进行编译打=>打包后的代码在本地服务器渲染。随着模块增多,打包的体积变大,造成热更新速度变慢。
vite:启动服务器=>请求模块时按需动态编译显示。(vite遵循的是ES Modlues模块规范来执行代码,不需要打包编译成es5模块即可在浏览器运行。)
vite启动的时候不需要分析各个模块之间的依赖关系、不需要打包编译。vite可按需动态编译缩减时间。当项目越复杂、模块越多的情况下,vite明显优于webpack
3.热更新
webpack:模块以及模块依赖的模块需重新编译
vite:浏览器重新请求该模块即可
4.使用方面
vite开箱即用,更加简单,基于浏览器esm,使得hmr更加优秀,达到极速的效果;
webpack更加灵活,api以及插件生态更加丰富。
5.原理不同
webpack是bundle,自己实现了一套模块导入导出机制。
vite是利用浏览器的esm能力,是bundless。
2.如何优化webpack打包速度?
打包速度优化:
1、使用高版本的webpack和Node.js
2、多进程打包:happyPack或thread-loader
3、多进程并行压缩:parallel-uglify-plugin、uglifyjs-webpack-plugin 开启 parallel 参数、terser-webpack-plugin 开启 parallel 参数
4、预编译资源模块:DLLPlugin
5、缓存(babel-loader、terser-webpack-plugin、cache-loader)
6、exclude、include缩小构建目标,noParse忽略、IgnorePlugin
7、resolve配置减少文件搜索范围(alias、modules、extensions、mainFields)
打包体积优化:
1、Tree-shaking擦除无用代码
2、Scope Hoisting优化代码
3、图片压缩(image-webpack-loader)
4、公共资源提取(CommonsChunkPlugin)
5、动态Polyfill
6、分包设置Externals,使用 html-webpack-externals- plugin,将 react、react-dom 基础包通过 cdn 引入,不打入 bundle 中
7、删除无用CSS代码(purgecss-webpack-plugin)
8、JS、CSS压缩(UglifyJsPlugin(3)、terser-webpack-plugin(4)、optimize-css-assets-webpack-plugin)
3.说说webpack中常见的Plugin?解决了什么问题
HtmlWebpackPlugin:将打包后的JS、CSS等文件自动注入到HTML文件中,方便开发者使用。
MiniCssExtractPlugin:将CSS文件从JS文件中分离出来,避免JS文件过大,提高页面加载速度。
CleanWebpackPlugin:每次打包前清空输出目录,避免旧文件对新文件的影响。
DefinePlugin:定义全局变量,方便在代码中使用。
HotModuleReplacementPlugin:热更新插件,可以在不刷新页面的情况下更新代码,提高开发效率。
UglifyJsPlugin:压缩JS代码,减小文件体积,提高页面加载速度。
CopyWebpackPlugin:将静态资源文件复制到输出目录中,方便开发者使用。
4.说说如何借助webpack来优化前端性能?
如何优化
通过webpack
优化前端的手段有:
- JS代码压缩
- CSS代码压缩
- Html文件代码压缩
- 文件大小压缩
- 图片压缩
- Tree Shaking
- 代码分离
- 内联 chunk
JS代码压缩
terser
是一个JavaScript
的解释、绞肉机、压缩机的工具集,可以帮助我们压缩、丑化我们的代码,让bundle
更小
在production
模式下,webpack
默认就是使用 TerserPlugin
来处理我们的代码的。如果想要自定义配置它,配置方法如下:
1const TerserPlugin = require('terser-webpack-plugin')
2module.exports = {
3 ...
4 optimization: {
5 minimize: true,
6 minimizer: [
7 new TerserPlugin({
8 parallel: true // 电脑cpu核数-1
9 })
10 ]
11 }
12}
属性介绍如下:
- extractComments:默认值为true,表示会将注释抽取到一个单独的文件中,开发阶段,我们可设置为 false ,不保留注释
- parallel:使用多进程并发运行提高构建的速度,默认值是true,并发运行的默认数量: os.cpus().length - 1
- terserOptions:设置我们的terser相关的配置:
- compress:设置压缩相关的选项,mangle:设置丑化相关的选项,可以直接设置为true
- mangle:设置丑化相关的选项,可以直接设置为true
- toplevel:底层变量是否进行转换
- keep_classnames:保留类的名称
- keep_fnames:保留函数的名称
CSS代码压缩
CSS
压缩通常是去除无用的空格等,因为很难去修改选择器、属性的名称、值等
CSS的压缩我们可以使用另外一个插件:css-minimizer-webpack-plugin
1npm install css-minimizer-webpack-plugin -D
配置方法如下:
1const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
2module.exports = {
3 // ...
4 optimization: {
5 minimize: true,
6 minimizer: [
7 new CssMinimizerPlugin({
8 parallel: true
9 })
10 ]
11 }
12}
Html文件代码压缩
使用HtmlWebpackPlugin
插件来生成HTML
的模板时候,通过配置属性minify
进行html
优化
1module.exports = {
2 ...
3 plugin:[
4 new HtmlwebpackPlugin({
5 ...
6 minify:{
7 minifyCSS:false, // 是否压缩css
8 collapseWhitespace:false, // 是否折叠空格
9 removeComments:true // 是否移除注释
10 }
11 })
12 ]
13}
设置了minify
,实际会使用另一个插件html-minifier-terser
文件大小压缩
对文件的大小进行压缩,减少http
传输过程中宽带的损耗
1npm install compression-webpack-plugin -D
1new ComepressionPlugin({
2 test:/\.(css|js)$/, // 哪些文件需要压缩
3 threshold:500, // 设置文件多大开始压缩
4 minRatio:0.7, // 至少压缩的比例
5 algorithm:"gzip", // 采用的压缩算法
6})
图片压缩
一般来说在打包之后,一些图片文件的大小是远远要比 js
或者 css
文件要来的大,所以图片压缩较为重要
配置方法如下:
1module: {
2 rules: [
3 {
4 test: /\.(png|jpg|gif)$/,
5 use: [
6 {
7 loader: 'file-loader',
8 options: {
9 name: '[name]_[hash].[ext]',
10 outputPath: 'images/',
11 }
12 },
13 {
14 loader: 'image-webpack-loader',
15 options: {
16 // 压缩 jpeg 的配置
17 mozjpeg: {
18 progressive: true,
19 quality: 65
20 },
21 // 使用 imagemin**-optipng 压缩 png,enable: false 为关闭
22 optipng: {
23 enabled: false,
24 },
25 // 使用 imagemin-pngquant 压缩 png
26 pngquant: {
27 quality: '65-90',
28 speed: 4
29 },
30 // 压缩 gif 的配置
31 gifsicle: {
32 interlaced: false,
33 },
34 // 开启 webp,会把 jpg 和 png 图片压缩为 webp 格式
35 webp: {
36 quality: 75
37 }
38 }
39 }
40 ]
41 },
42 ]
43}
Tree Shaking
Tree Shaking
是一个术语,在计算机中表示消除死代码,依赖于ES Module
的静态语法分析(不执行任何的代码,可以明确知道模块的依赖关系)
在webpack
实现Trss shaking
有两种不同的方案:
- usedExports:通过标记某些函数是否被使用,之后通过Terser来进行优化的
- sideEffects:跳过整个模块/文件,直接查看该文件是否有副作用
两种不同的配置方案, 有不同的效果
usedExports
配置方法也很简单,只需要将usedExports
设为true
1module.exports = {
2 ...
3 optimization:{
4 usedExports
5 }
6}
使用之后,没被用上的代码在webpack
打包中会加入unused harmony export mul
注释,用来告知 Terser
在优化时,可以删除掉这段代码
如下面sum
函数没被用到,webpack
打包会添加注释,terser
在优化时,则将该函数去掉
预览
sideEffects
sideEffects
用于告知webpack compiler
哪些模块时有副作用,配置方法是在package.json
中设置sideEffects
属性
如果sideEffects
设置为false,就是告知webpack
可以安全的删除未用到的exports
如果有些文件需要保留,可以设置为数组的形式
1"sideEffecis":[ "./src/util/format.js", "*.css" // 所有的css文件]
上述都是关于javascript
的tree shaking
,css
同样也能够实现tree shaking
css tree shaking
css
进行tree shaking
优化可以安装PurgeCss
插件
1npm install purgecss-plugin-webpack -D
1const PurgeCssPlugin = require('purgecss-webpack-plugin')module.exports = { ... plugins:[ new PurgeCssPlugin({ path:glob.sync(`${path.resolve('./src')}/**/*`), {nodir:true}// src里面的所有文件 satelist:function(){ return { standard:["html"] } } }) ]}
- paths:表示要检测哪些目录下的内容需要被分析,配合使用glob
- 默认情况下,Purgecss会将我们的html标签的样式移除掉,如果我们希望保留,可以添加一个safelist的属性
代码分离
将代码分离到不同的bundle
中,之后我们可以按需加载,或者并行加载这些文件
默认情况下,所有的JavaScript
代码(业务代码、第三方依赖、暂时没有用到的模块)在首页全部都加载,就会影响首页的加载速度
代码分离可以分出出更小的bundle
,以及控制资源加载优先级,提供代码的加载性能
这里通过splitChunksPlugin
来实现,该插件webpack
已经默认安装和集成,只需要配置即可
默认配置中,chunks仅仅针对于异步(async)请求,我们可以设置为initial或者all
1module.exports = { ... optimization:{ splitChunks:{ chunks:"all" } }}
splitChunks
主要属性有如下:
- Chunks,对同步代码还是异步代码进行处理
- minSize: 拆分包的大小, 至少为minSize,如何包的大小不超过minSize,这个包不会拆分
- maxSize: 将大于maxSize的包,拆分为不小于minSize的包
- minChunks:被引入的次数,默认是1
内联chunk
可以通过InlineChunkHtmlPlugin
插件将一些chunk
的模块内联到html
,如runtime
的代码(对模块进行解析、加载、模块信息相关的代码),代码量并不大,但是必须加载的
1const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin')const HtmlWebpackPlugin = require('html-webpack-plugin')mod
5.说说webpack的热更新是如何做到的?原理是什么
- 通过
webpack-dev-server
创建两个服务器:提供静态资源的服务(express)和Socket服务 - express server 负责直接提供静态资源的服务(打包后的资源直接被浏览器请求和解析)
- socket server 是一个 websocket 的长连接,双方可以通信
- 当 socket server 监听到对应的模块发生变化时,会生成两个文件.json(manifest文件)和.js文件(update chunk)
- 通过长连接,socket server 可以直接将这两个文件主动发送给客户端(浏览器)
- 浏览器拿到两个新的文件后,通过HMR runtime机制,加载这两个文件,并且针对修改的模块进行更新
6.说说webpack proxy工作原理?为什么能解决跨域?
一、是什么
webpack proxy
,即webpack
提供的代理服务
基本行为就是接收客户端发送的请求后转发给其他服务器
其目的是为了便于开发者在开发模式下解决跨域问题(浏览器安全策略限制)
想要实现代理首先需要一个中间服务器,webpack
中提供服务器的工具为webpack-dev-server
webpack-dev-server
webpack-dev-server
是 webpack
官方推出的一款开发工具,将自动编译和自动刷新浏览器等一系列对开发友好的功能全部集成在了一起
目的是为了提高开发者日常的开发效率,只适用在开发阶段
关于配置方面,在webpack
配置对象属性中通过devServer
属性提供,如下:
1// ./webpack.config.js
2const path = require('path')
3
4module.exports = {
5 // ...
6 devServer: {
7 contentBase: path.join(__dirname, 'dist'),
8 compress: true,
9 port: 9000,
10 proxy: {
11 '/api': {
12 target: 'https://api.github.com'
13 }
14 }
15 // ...
16 }
17}
devServetr
里面proxy
则是关于代理的配置,该属性为对象的形式,对象中每一个属性就是一个代理的规则匹配
属性的名称是需要被代理的请求路径前缀,一般为了辨别都会设置前缀为 /api
,值为对应的代理匹配规则,对应如下:
- target:表示的是代理到的目标地址
- pathRewrite:默认情况下,我们的 /api-hy 也会被写入到URL中,如果希望删除,可以使用pathRewrite
- secure:默认情况下不接收转发到https的服务器上,如果希望支持,可以设置为false
- changeOrigin:它表示是否更新代理后请求的 headers 中host地址
二、工作原理
proxy
工作原理实质上是利用http-proxy-middleware
这个http
代理中间件,实现请求转发给其他服务器
举个例子:
在开发阶段,本地地址为http://localhost:3000
,该浏览器发送一个前缀带有/api
标识的请求到服务端获取数据,但响应这个请求的服务器只是将请求转发到另一台服务器中
1const express = require('express');
2const proxy = require('http-proxy-middleware');
3
4const app = express();
5
6app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true}));
7app.listen(3000);
8
9// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
三、跨域
在开发阶段, webpack-dev-server
会启动一个本地开发服务器,所以我们的应用在开发阶段是独立运行在 localhost
的一个端口上,而后端服务又是运行在另外一个地址上
所以在开发阶段中,由于浏览器同源策略的原因,当本地访问后端就会出现跨域请求的问题
通过设置webpack proxy
实现代理请求后,相当于浏览器与服务端中添加一个代理者
当本地发送请求的时候,代理服务器响应该请求,并将请求转发到目标服务器,目标服务器响应数据后再将数据返回给代理服务器,最终再由代理服务器将数据响应给本地
预览
在代理服务器传递数据给本地浏览器的过程中,两者同源,并不存在跨域行为,这时候浏览器就能正常接收数据
注意:服务器与服务器之间请求数据并不会存在跨域行为,跨域行为是浏览器安全策略限制
7.说说webpack中常见的Loader?解决了什么问题?
loader
用于对模块的"源代码"进行转换,在 import
或"加载"模块时预处理文件
webpack
做的事情,仅仅是分析出各种模块的依赖关系,然后形成资源列表,最终打包生成到指定的文件中。如下图所示:
预览
在webpack
内部中,任何文件都是模块,不仅仅只是js
文件
默认情况下,在遇到import
或者load
加载模块的时候,webpack
只支持对js
文件打包
像css
、sass
、png
等这些类型的文件的时候,webpack
则无能为力,这时候就需要配置对应的loader
进行文件内容的解析
在加载模块的时候,执行顺序如下:
预览
当 webpack
碰到不识别的模块的时候,webpack
会在配置的中查找该文件解析规则
关于配置loader
的方式有三种:
- 配置方式(推荐):在 webpack.config.js文件中指定 loader
- 内联方式:在每个 import 语句中显式指定 loader
- CLI 方式:在 shell 命令中指定它们
配置方式
关于loader
的配置,我们是写在module.rules
属性中,属性介绍如下:
rules
是一个数组的形式,因此我们可以配置很多个loader
- 每一个
loader
对应一个对象的形式,对象属性test
为匹配的规则,一般情况为正则表达式 - 属性
use
针对匹配到文件类型,调用对应的loader
进行处理
代码编写,如下形式:
1module.exports = {
2 module: {
3 rules: [
4 {
5 test: /\.css$/,
6 use: [
7 { loader: 'style-loader' },
8 {
9 loader: 'css-loader',
10 options: {
11 modules: true
12 }
13 },
14 { loader: 'sass-loader' }
15 ]
16 }
17 ]
18 }
19};
二、特性
这里继续拿上述代码,来讲讲loader
的特性
从上述代码可以看到,在处理css
模块的时候,use
属性中配置了三个loader
分别处理css
文件
因为loader
支持链式调用,链中的每个loader
会处理之前已处理过的资源,最终变为js
代码。顺序为相反的顺序执行,即上述执行方式为sass-loader
、css-loader
、style-loader
除此之外,loader
的特性还有如下:
- loader 可以是同步的,也可以是异步的
- loader 运行在 Node.js 中,并且能够执行任何操作
- 除了常见的通过
package.json
的main
来将一个 npm 模块导出为 loader,还可以在 module.rules 中使用loader
字段直接引用一个模块 - 插件(plugin)可以为 loader 带来更多特性
- loader 能够产生额外的任意文件
可以通过 loader 的预处理函数,为 JavaScript 生态系统提供更多能力。用户现在可以更加灵活地引入细粒度逻辑,例如:压缩、打包、语言翻译和更多其他特性
三、常见的loader
在页面开发过程中,我们经常性加载除了js
文件以外的内容,这时候我们就需要配置响应的loader
进行加载
常见的loader
如下:
- style-loader: 将css添加到DOM的内联样式标签style里
- css-loader :允许将css文件通过require的方式引入,并返回css代码
- less-loader: 处理less
- sass-loader: 处理sass
- postcss-loader: 用postcss来处理CSS
- autoprefixer-loader: 处理CSS3属性前缀,已被弃用,建议直接使用postcss
- file-loader: 分发文件到output目录并返回相对路径
- url-loader: 和file-loader类似,但是当文件小于设定的limit时可以返回一个Data Url
- html-minify-loader: 压缩HTML
- babel-loader :用babel来转换ES6文件到ES
下面给出一些常见的loader
的使用:
css-loader
分析 css
模块之间的关系,并合成⼀个 css
1npm install --save-dev css-loader
1rules: [
2 ...,
3 {
4 test: /\.css$/,
5 use: {
6 loader: "css-loader",
7 options: {
8 // 启用/禁用 url() 处理
9 url: true,
10 // 启用/禁用 @import 处理
11 import: true,
12 // 启用/禁用 Sourcemap
13 sourceMap: false
14 }
15 }
16 }
17]
如果只通过css-loader
加载文件,这时候页面代码设置的样式并没有生效
原因在于,css-loader
只是负责将.css
文件进行一个解析,而并不会将解析后的css
插入到页面中
如果我们希望再完成插入style
的操作,那么我们还需要另外一个loader
,就是style-loader
style-loader
把 css-loader
生成的内容,用 style
标签挂载到页面的 head
中
1npm install --save-dev style-loader
1rules: [
2 ...,
3 {
4 test: /\.css$/,
5 use: ["style-loader", "css-loader"]
6 }
7]
同一个任务的 loader
可以同时挂载多个,处理顺序为:从右到左,从下往上
less-loader
开发中,我们也常常会使用less
、sass
、stylus
预处理器编写css
样式,使开发效率提高,这里需要使用less-loader
1npm install less-loader -D
1rules: [
2 ...,
3 {
4 test: /\.css$/,
5 use: ["style-loader", "css-loader","less-loader"]
6 }
7]
raw-loader
在 webpack
中通过 import
方式导入文件内容,该loader
并不是内置的,所以首先要安装
1npm install --save-dev raw-loader
然后在 webpack.config.js 中进行配置
1module.exports = { ..., module: { rules: [ { test: /\.(txt|md)$/, use: 'raw-loader' } ] }}
file-loader
把识别出的资源模块,移动到指定的输出⽬目录,并且返回这个资源在输出目录的地址(字符串)
1npm install --save-dev file-loader
1rules: [ ..., { test: /\.(png|jpe?g|gif)$/, use: { loader: "file-loader", options: { // placeholder 占位符 [name] 源资源模块的名称 // [ext] 源资源模块的后缀 name: "[name]_[hash].[ext]", //打包后的存放位置 outputPath: "./images", // 打包后文件的 url publicPath: './images', } } }]
url-loader
可以处理理 file-loader
所有的事情,但是遇到图片格式的模块,可以选择性的把图片转成 base64
格式的字符串,并打包到 js
中,对小体积的图片比较合适,大图片不合适。
1npm install --save-dev url-loader
复制1rules: [ ..., { test: /\.(png|jpe?g|gif)$/, use: { loader: "url-loader", options: { // placeholder 占位符 [name] 源资源模块的名称
8.说说你对webpack的理解?解决了什么问题?
webpack
是一个用于现代JavaScript
应用程序的静态模块打包工具
- 静态模块
这里的静态模块指的是开发阶段,可以被 webpack
直接引用的资源(可以直接被获取打包进bundle.js
的资源)
当 webpack
处理应用程序时,它会在内部构建一个依赖图,此依赖图对应映射到项目所需的每个模块(不再局限js
文件),并生成一个或多个 bundle
webpack
的能力:
编译代码能力,提高效率,解决浏览器兼容问题
模块整合能力,提高性能,可维护性,解决浏览器频繁请求文件的问题
万物皆可模块能力,项目维护性增强,支持不同种类的前端模块类型,统一的模块化方案,所有资源文件的加载都可以通过代码控制
9.webpack的构建流程是什么
- 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;
- 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
- 确定入口:根据配置中的 entry 找出所有的入口文件;
- 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;
- 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
- 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
- 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
10.webpack的Loader和Plugin的不同
不同的作用:
- Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到
loader
。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。 - Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
不同的用法:
- Loader在
module.rules
中配置,也就是说他作为模块的解析规则而存在。 类型为数组,每一项都是一个Object
,里面描述了对于什么类型的文件(test
),使用什么加载(loader
)和使用的参数(options
) - Plugin在
plugins
中单独配置。 类型为数组,每一项是一个plugin
的实例,参数都通过构造函数传入。
11.谈谈你对 Webpack的认识
WebPack是一个模块打包工具,可以使用 WebPack管理模块依赖,并编译输岀模块所需的静态文件。它能够很好地管理与打包Web开发中所用到的HTML、 JavaScript 、CSS以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源, WebPack有对应的模块加载器。Web Pack模块打包器会分析模块间的依赖关系,最后生成优化且合并后的静态资源。
WebPack的两大特色如下。
(1)代码切割( code splitting)
(2) loader可以处理各种类型的静态文件,并且支持串行操作WebPack以 CommonJS规范来书写代码,但对 AMD/CMD的支持也很全面,方便对项目进行代码迁移。
WebPack具有 require.js和 browserify的功能,但也有很多自己的新特性,
(1)对 CommonJS、AMD、ES6的语法实现了兼容。
(2)对 JavaScript、CSS、图片等资源文件都支持打包
(3)串联式模块加载器和插件机制,让其具有更好的灵活性和扩展性,例如提供对CoffeeScript、 EMAScript 6的支持
(4)有独立的配置文件 webpack.config. js。
(5)可以将代码切割成不同的块,实现按需加载,缩短了初始化时间。
(6)支持 SourceUrls和 SourceMaps,易于调试。
(7)具有强大的 Plugin接口,大多是内部插件,使用起来比较灵活
(8)使用异步I/O,并具有多级缓存,这使得 WebPack速度很快且在增量编译上更加快。