本笔记部分内容参考webpack中文官网。
笔记从概念开始介绍webpack, 如果对概念有所了解,可以跳转到入门-极简教程。 极简教程之后是对插件和loader的举例,最后是webpack插件和loader的综合运用。
PS:部分代码前的“+”号表示增加的代码,如果想使用,请删除前面的“+”号。
webpack是静态模块打包器,当使用webpack处理应用程序时,会将这些模块打包成一个或多个文件。
它可以处理js/css/图片/字体/图标等文件,用于处理静态(本地)文件。
模块化是一种将系统分离成独立功能部分的方法,严格定义模块接口、模块间具有透明性。
入口起点(entry point) 指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图(dependency graph) 的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
默认值是 ./src/index.js
,但你可以通过在 webpack configuration 中配置 entry
属性,来指定一个(或多个)不同的入口起点。例如:
webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js',
};
用法:entry: {
webpack.config.js
module.exports = {
entry: {
app: './src/app.js',
adminApp: './src/adminApp.js',
},
};
用于描述入口的对象。你可以使用如下属性:
dependOn
: 当前入口所依赖的入口。它们必须在该入口被加载前被加载。filename
: 指定要输出的文件名称。import
: 启动时需加载的模块。library
: 指定 library 选项,为当前 entry 构建一个 library。runtime
: 运行时 chunk 的名字。如果设置了,就会创建一个以这个名字命名的运行时 chunk,否则将使用现有的入口作为运行时。publicPath
: 当该入口的输出文件在浏览器中被引用时,为它们指定一个公共 URL 地址。请查看 output.publicPath。runtime
和 dependOn
不应在同一个入口上同时使用,所以如下配置无效,并且会抛出错误:
webpack.config.js
module.exports = {
entry: {
a2: './a',
b2: {
runtime: 'x2',
dependOn: 'a2',
import: './b',
},
},
};
确保 runtime
不能指向已存在的入口名称,例如下面配置会抛出一个错误:
module.exports = {
entry: {
a1: './a',
b1: {
runtime: 'a1',
import: './b',
},
},
};
另外 dependOn
不能是循环引用的,下面的例子也会出现错误:
module.exports = {
entry: {
a3: {
import: './a',
dependOn: 'b3',
},
b3: {
import: './b',
dependOn: 'a3',
},
},
};
output 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。主要输出文件的默认值是 ./dist/main.js
,其他生成文件默认放置在 ./dist
文件夹中。
注意,即使可以存在多个 entry
起点,但只能指定一个 output
配置。
你可以通过在配置中指定一个 output
字段,来配置这些处理过程:
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
// path:绝对路径
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js',
},
};
在上面的示例中,我们通过 output.filename
和 output.path
属性,来告诉 webpack bundle 的名称,以及我们想要 bundle 生成(emit)到哪里。在代码最上面导入的 path 模块是什么,它是一个 Node.js 核心模块,用于操作文件路径。
如果有多个入口文件,出口文件需要改名,否则就会覆盖。
const path=require('path');
module.exports={
entry:{
"main":'./src/index.js',
"app":'./src/module.js'
},
output:{
// [name]表示入口的名字
filename:'[name].bundle.js',
path:path.resolve(__dirname,'dist'),
// 清除没有用到的文件
clean:true
},
mode:'development',
};
webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。
Warning
注意,loader 能够
import
导入任何类型的模块(例如.css
文件),这是 webpack 特有的功能,其他打包程序或任务执行器的可能并不支持。我们认为这种语言扩展是很有必要的,因为这可以使开发人员创建出更准确的依赖关系图。
在更高层面,在 webpack 的配置中,loader 有两个属性:
test
属性,识别出哪些文件会被转换。use
属性,定义出在进行转换时,应该使用哪个 loader。webpack.config.js
const path = require('path');
module.exports = {
output: {
filename: 'my-first-webpack.bundle.js',
},
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
};
以上配置中,对一个单独的 module 对象定义了 rules
属性,里面包含两个必须属性:test
和 use
。这告诉 webpack 编译器(compiler) 如下信息:
“嘿,webpack 编译器,当你碰到「在
require()
/import
语句中被解析为 ‘.txt’ 的路径」时,在你对它打包之前,先 use(使用)raw-loader
转换一下。”
Warning
重要的是要记住,在 webpack 配置中定义 rules 时,要定义在
module.rules
而不是rules
中。为了使你便于理解,如果没有按照正确方式去做,webpack 会给出警告。
loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。
想要使用一个插件,你只需要 require()
它,然后把它添加到 plugins
数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new
操作符来创建一个插件实例。
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 用于访问内置插件
module.exports = {
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};
在上面的示例中,html-webpack-plugin
为应用程序生成一个 HTML 文件,并自动注入所有生成的 bundle。
通过选择 development
, production
或 none
之中的一个,来设置 mode
参数,你可以启用 webpack 内置在相应环境下的优化。其默认值为 production
。
module.exports = {
mode: 'production',
};
webpack 支持所有符合 ES5 标准 的浏览器(不支持 IE8 及以下版本)。webpack 的 import()
和 require.ensure()
需要 Promise
。如果你想要支持旧版本浏览器,在使用这些表达式之前,还需要 提前加载 polyfill。
https://webpack.docschina.org/guides,用这个入门非常棒,讲解非常详细,内容也超级丰富,只练一遍是记不住的。
1.首先要先在项目中初始化,npm init -y
,会生成一个package.json文件,-y表示全部默认,省去回车过程。
2.在powershell中输入npm install --save-dev webpack webpack-cli
来安装webpack。
3.项目根目录下创建一个名为webpack.config.js
的配置文件,在这个配置文件中用module.exports来导出配置。
下面的代码的意思为入口为’./src/indec.js’,出口为’dist’文件夹,文件名为’bundle.js’。
const path=require('path');
module.exports={
entry:'./src/index.js',
output:{
path:path.resolve(__dirname,'dist'),
filename:"bundle.js"
}
};
4.在package.json
文件中的scrpits下添加如下代码:
"scripts": {
"build":"webpack"
}
5.在终端中输入npm run build
,webpack即会开始编译,可以在dist目录下看到编译结果。
如果在webpack配置文件中(默认为webpack.config.js)中将模式改为development(默认为production),编译后的文件会看起来更加清晰。
const path=require('path');
module.exports={
entry:'./src/index.js',
output:{
path:path.resolve(__dirname,'dist'),
filename:"bundle.js"
},
+ mode:'development',
};
loader被用于帮助webpack处理各种模块,而插件则可用于执行范围更广的任务。
如果我们更改了一个入口起点的名称,甚至添加了一个新的入口,会发生什么?会在构建时重新命名生成的 bundle,但是我们的 index.html
文件的script
标签仍然引用旧的名称。让我们用 HtmlWebpackPlugin
来解决这个问题。
有了这个插件,就不用在npm run build
改变了js的名字后手动去改变html中script
标签引入的js路径。
首先安装插件,并且调整 webpack.config.js
文件:
npm install --save-dev html-webpack-plugin
webpack.config.js
const path = require('path');
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js',
},
+ plugins: [
+ new HtmlWebpackPlugin({
+ //指定一个html文件作为模板
+ template:"./index.html"
+ }),
+ ],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
mode:'development'
};
虽然在 dist/
文件夹我们已经有了 index.html
这个文件,然而 HtmlWebpackPlugin
还是会默认生成它自己的 index.html
文件。也就是说,它会用新生成的 index.html
文件,替换我们的原有文件。
配置含有2个html和2个js的项目。
const path=require('path');
const HtmlWebpackPlugin=require('html-webpack-plugin');
module.exports={
mode:'development',
// 多入口
+ entry:{
+ index:'./src/index.js',
+ search:'./src/search.js'
+ },
output:{
filename:'[name].js',
path:path.resolve(__dirname,"dist"),
},
// 多入口 有几个入口就实例化几次
+ plugins:[
+ new HtmlWebpackPlugin({
+ //指定一个html文件作为模板
+ template:"./index.html",
+ //多个html必须要命名,否则默认为index.html
+ //同名文件,后生成的文件会覆盖前面的
+ filename:'index.html',
+ //指定要引入的js文件,否则会引入所有的js文件
+ chunks:['index'] //写entry中的名字
+ }),
+ new HtmlWebpackPlugin({
+ template:"./search.html",
+ filename:'./search.html',
+ // 同时引入index和search两个文件
+ chunks:['index','search'],
+ })
+ ]
}
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js',
},
plugins: [
new HtmlWebpackPlugin({
//指定一个html文件作为模板
template:"./index.html",
+ minify:{
+ //删除index.html中的注释
+ removeComments:true,
+ // 删除index.html中的空格
+ collapseWhitespace:true,
+ //删除html标签属性值的双引号
+ removeAttributeQuotes:true
+ }
}),
],
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
mode:'development'
};
loader可以用webpack能够处理非JS文件(css、图片、字体等)的模块。
在你的应用程序中,有两种使用 loader 的方式:
import
语句中显式指定 loader。module.rules
允许你在 webpack 配置中指定多个 loader。 这种方式是展示 loader 的一种简明方式,并且有助于使代码变得简洁和易于维护。同时让你对各个 loader 有个全局概览:
loader **从右到左(或从下到上)**地取值(evaluate)/执行(execute)。在下面的示例中,从 sass-loader 开始执行,然后继续执行 css-loader,最后以 style-loader 为结束。查看 loader 功能 章节,了解有关 loader 顺序的更多信息。
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
// [style-loader](/loaders/style-loader)
{ loader: 'style-loader' },
// [css-loader](/loaders/css-loader)
{
loader: 'css-loader',
options: {
modules: true
}
},
// [sass-loader](/loaders/sass-loader)
{ loader: 'sass-loader' }
]
}
]
}
};
可以在 import
语句或任何 与 “import” 方法同等的引用方式 中指定 loader。使用 !
将资源中的 loader 分开。每个部分都会相对于当前目录解析。
import Styles from 'style-loader!css-loader?modules!./styles.css';
v5 版本已废弃file-loader: 请向 asset modules
迁移。资源模块(asset module)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader。
在 webpack 5 之前,通常使用:
raw-loader
将文件导入为字符串url-loader
将文件作为 data URI 内联到 bundle 中file-loader
将文件发送到输出目录资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:
asset/resource
发送一个单独的文件并导出 URL。之前通过使用 file-loader
实现。asset/inline
导出一个资源的 data URI。之前通过使用 url-loader
实现。asset/source
导出资源的源代码。之前通过使用 raw-loader
实现。asset
在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader
,并且配置资源体积限制实现。先要安装babel,毕竟活是babel干的,webpack只是打包的。
npm install --save-dev @babel/core @babel/cli @babel/preset-env
接着安装babel-loader这个插件。
npm install --save-dev babel-loader
接下来,配置babel,在根目录下创建babel.config.json
的文件,并写下如下代码。
{
"presets": ["@babel/env"]
}
下一步,便是在webpack.config.js
文件中配置loader。
const path = require('path');
module.exports = {
entry: {
"index": './src/module.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ // 排除node_modules里面的js文件
+ exclude: /node_modules/,
+ use: "babel-loader"
+ },
+ ],
+ },
mode: 'development',
};
如果想要转换promise这些,需要安装babel的垫片插件。
第一步要先安装core-js
。
npm install --save-dev core-js
接着在源文件夹下(src)的js代码中引入该模块。
import "core-js/stable";
值得注意的是安装babel-loader和core-js的版本,尝试了很多次发现,他们需要低版本。
"devDependencies": {
"@babel/core": "^7.11.0",
"@babel/preset-env": "^7.11.0",
"babel-loader": "^8.1.0",
"core-js": "^3.6.5",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12"
}
首先要在src文件夹下的某个js文件中导入css文件。
import './src/style.css';
为了在 JavaScript 模块中 import
一个 CSS 文件,你需要安装 style-loader 和 css-loader,并在 module
配置 中添加这些 loader:
npm install --save-dev style-loader css-loader
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
+ module: {
+ rules: [
+ {
+ test: /\.css$/i,
+ use: ['style-loader', 'css-loader'],
+ },
+ ],
+ },
};
模块 loader 可以链式调用。链中的每个 loader 都将对资源进行转换。链会逆序执行。第一个 loader 将其结果(被转换后的资源)传递给下一个 loader,依此类推。最后,webpack 期望链中的最后的 loader 返回 JavaScript。
应保证 loader 的先后顺序:'style-loader'
在前,而 'css-loader'
在后。loader数组是从右到左执行,先通过’css-loader’识别css文件,再通过style-loader
将css代码嵌入到style标签中。(在控制台可以看到)
和上面的style-loader
在style标签中内联不同,插件mini-css-extract-plugin
会让html文件通过link
标签引入css文件
首先要在src文件夹下的某个js文件中导入css文件。
import './src/style.css';
接着安装插件mini-css-extract-plugin
和css-loader
。
npm install --save-dev css-loader mini-css-extract-plugin
配置webpack.config.js
const path = require('path');
+ const MiniCssExtractPlugin=require('mini-css-extract-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
+ module: {
+ rules: [
+ {
+ test: /\.css$/i,
+ //注意导入顺序
+ use: [MiniCssExtractPlugin.loader, 'css-loader'],
+ },
+ ],
+ },
+ plugins: [
+ new MiniCssExtractPlugin({
+ //指定生成的css的文件名
+ filename:'[name].css'
+ }),
+ ],
};
最后,可以在dist文件夹下看到生成的css文件。
而且在控制台可以看到样式是通过link
标签引入的。
如果是远程图片,则可以直接显示。而本地图片通过webpack打包,需要额外处理。
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
+ {
+ test: /\.(png|svg|jpg|jpeg|gif)$/i,
+ type: 'asset/resource',
+ },
],
},
};
现在,在 import MyImage from './my-image.png'
时,此图像将被处理并添加到 output
目录,并且 MyImage
变量将包含该图像在处理后的最终 url。在使用 css-loader 时,如前所示,会使用类似过程处理你的 CSS 中的 url('./my-image.png')
。loader 会识别这是一个本地文件,并将 './my-image.png'
路径,替换为 output
目录中图像的最终路径。而 html-loader 以相同的方式处理 。
如果需要在js文件中使用图片,也可以用asset module
这个loader,无需额外安装其他的loader。只需要在js中使用import
引入图片即可。
// 把图片当做模块引入
import logo from './image/img.png';
console.log(logo); // 会输出图片的路径
const myLogo = new Image();
myLogo.src = logo;
document.body.appendChild(myLogo)
默认情况下,asset/resource
模块以 [hash][ext][query]
文件名发送到输出目录。
可以通过在 webpack 配置中设置 output.assetModuleFilename
来修改此模板字符串:
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
+ assetModuleFilename: 'images/[hash][ext][query]'
},
module: {
rules: [
{
test: /\.png/,
type: 'asset/resource'
}
]
},
};
如可以设置为assetModuleFilename: 'images/[name][ext]'
,此时的[name]指图片本身的名字,而是entry中的名字,[ext]是指"filename extension",用它表示文件原来的后缀。
另一种自定义输出文件名的方式是,将某些资源发送到指定目录:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
+ assetModuleFilename: 'images/[hash][ext][query]'
},
module: {
rules: [
{
test: /\.png/,
type: 'asset/resource'
- }
+ },
+ {
+ test: /\.html/,
+ type: 'asset/resource',
+ generator: {
+ filename: 'static/[hash][ext][query]'
+ }
+ }
]
},
};
使用此配置,所有 html
文件都将被发送到输出目录中的 static
目录中。
Rule.generator.filename
与 output.assetModuleFilename
相同,并且仅适用于 asset
和 asset/resource
模块类型。
当使用MiniCssExtractPlugin
生成的css在dist下一个文件夹时(如dist/css/style.css
),此时如果不设置生成的css的公共路径(publicPath
),图片不会正常显示。
因为css-loader
以为生成的style.css
文件直接在dist目录下,所以图片路径会默认设置为url(./随机名字.png)
,而事实上图片的正确的路径为url(../随机名字.png)
。
img-demo
|- package.json
|- webpack.config.js
|- /dist
|- index.js
|- index.html
+ |- 随机字符.png
+ |- /css
+ |- style.css
|- /src
|- icon.png
|- style.css
|- index.js
|- /node_modules
因此,需要在options
中设置publicPath
为../
,这样该css文件引入的所有url前面都会加上../
的前缀。
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin=require('mini-css-extract-plugin');
module.exports = {
entry: {
index: './src/index.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
module:{
rules:[
{
test:/\.css$/i,
//此时生成的css在dist/css的文件夹下,要设置公共路径
//这样该css文件所有的url前面都会加上../的前缀。
+ use:[{
+ loader:MiniCssExtractPlugin.loader,
+ options:{
+ publicPath:'../'
+ }
+ }, 'css-loader']},
{
test:/\.(png|svg|jepg|gif)/,
type:'asset/resource'
}
]
},
plugins: [
new HtmlWebpackPlugin({
//指定一个html文件作为模板
template: "./index.html"
}),
+ new MiniCssExtractPlugin({
+ //在dist/css文件夹下创建一个index.css文件
+ filename:'css/[name].css'
+ })
],
mode: 'development'
};
css中引入的图片可以用type:asset/resource;
,html中的图片则需要额外安装loaderhtml-withimg-loader
npm install --save-dev html-withimg-loader
此时,我只写出新增的代码,其他的如图片loader,html-webpack-plugin和mini-css-extract-plugin插件用法参考上面的代码。
注意:这个html-withimg-loader
必须要配合处理图片的loader——asset module
一起使用,因为真正能够加载图片的还是asset module
,html-withimg-loader
用来处理路径问题。
module:{
rules:[
{
test:/\.(html|htm)/i,
use:'html-withimg-loader'
}
]
},
asset/inline输出的 data URI,默认是呈现为使用 Base64 算法编码的文件内容。
webpack.config.js
关于rules.parser
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
+ {
+ test: /\.svg/,
+ type: 'asset/inline',
+ parser:{
+ dataUrlCondition:
+ maxSize:10000
+ //表示10kb
+ }
+ },
]
}
};
maxSize为10000,表示小于10kb将其转换为base64格式,大于则按照asset/resource来处理。一般只对较小的图片进行这种操作,因为转为base64格式后,图片会以base64格式来存在js中。
当 webpack 打包源代码时,可能会很难追踪到 error(错误) 和 warning(警告) 在源代码中的原始位置。例如,如果将三个源文件(a.js
, b.js
和 c.js
)打包到一个 bundle(bundle.js
)中,而其中一个源文件包含一个错误,那么堆栈跟踪就会直接指向到 bundle.js
。你可能需要准确地知道错误来自于哪个源文件,所以这种提示这通常不会提供太多帮助。
为了更容易地追踪 error 和 warning,JavaScript 提供了 source maps 功能,可以将编译后的代码映射回原始源代码。如果一个错误来自于 b.js
,source map 就会明确的告诉你。
source map 有许多 可用选项,请务必仔细阅读它们,以便可以根据需要进行配置。
对于本指南,我们将使用 inline-source-map
选项,这有助于解释说明示例意图(此配置仅用于示例,不要用于生产环境):
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
print: './src/print.js',
},
+ devtool: 'inline-source-map',
plugins: [
new HtmlWebpackPlugin({
title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};
webpack-dev-server
为你提供了一个基本的 web server,并且具有 live reloading(实时重新加载) 功能。设置如下:
npm install --save-dev webpack-dev-server
修改配置文件,告知 dev server,从什么位置查找文件:
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
print: './src/print.js',
},
devtool: 'inline-source-map',
+ devServer: {
+ contentBase: './dist',
+ },
plugins: [
new HtmlWebpackPlugin({
title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};
以上配置告知 webpack-dev-server
,将 dist
目录下的文件 serve 到 localhost:8080
下。(serve,将资源作为 server 的可访问文件)
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
+ "start": "webpack serve --open",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"html-webpack-plugin": "^4.5.0",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"lodash": "^4.17.20"
}
}
现在,在命令行中运行 npm start
,我们会看到浏览器自动加载页面。如果你更改任何源文件并保存它们,web server 将在编译代码后自动重新加载。试试看!
webpack-dev-server
具有许多可配置的选项。关于其他更多配置,请查看 配置文档。
Warning
webpack-dev-server 在编译之后不会写入到任何输出文件。而是将 bundle 文件保留在内存中,然后将它们 serve 到 server 中,就好像它们是挂载在 server 根路径上的真实文件一样。如果你的页面希望在其他不同路径中找到 bundle 文件,则可以通过 dev server 配置中的
publicPath
选项进行修改。