本章为 output 专栏,参考 output详细配置
这里只介绍常用的
1. filename
输出 bundle 的名称。这些 bundle 将写入到output.path
选项指定的目录下。
对于单个入口起点,filename 通常是一个静态名称
module.exports = {
//...
output: {
filename: 'bundle.js',
},
};
当entry
设置了多入口、或代码拆分或各种插件创建多个 bundle,此时若还采用上述静态命名,结果就会产生多个 bundle.js
导致报错。
解决方式就是使用替换方式,来赋予每个 bundle 一个唯一的名称
module.exports = {
//...
output: {
filename: '[name].bundle.js',
// filename: '[chunkhash].bundle.js',
// filename: '[name].[contenthash].bundle.js',
},
};
不同层面,可替换的内容不一样: 替换模板
2. chunkFilename
它的取值与 filename
相同,但主要是它俩的区分
filename
对应于entry
里面的输入文件,经过webpack 打包后输出文件的文件名chunkFilename
指未被列在entry
中,却又需要被打包出来的chunk
文件的名称。一般来说,这个chunk
文件指的就是要懒加载的代码
注意,这些文件名需要在运行时根据 chunk 发送的请求去生成。因此,需要在 webpack runtime 输出 bundle 值时,将 chunk id 的值对应映射到占位符(如
[name]
和[chunkhash]
)。这会增加文件大小,并且在任何 chunk 的占位符值修改后,都会使 bundle 失效
3. path
webpack 输出文件的绝对路径
4. module
以模块类型输出 JavaScript 文件。由于此功能还处于实验阶段,默认禁用;如果需要使用,一定要开启experiments.outputModule
module.exports = {
//...
experiments: {
outputModule: true,
},
output: {
module: true,
},
};
5. publicPath
官方:选项指定在浏览器中所引用的「此输出目录对应的公开 URL」,对于按需加载(on-demand-load)或加载外部资源(external resources)(如图片、文件等)来说,output.publicPath 是很重要的选项,如果指定了一个错误的值,则在加载这些资源时会收到 404 错误。
看不懂是吧?我也看不懂
通俗:主要用来转换url中的相对路径的。publicPath 并不会对生成文件的路径造成影响,主要是对你的页面里面引入的资源的路径做对应的补全,常见的就是css文件里面引入的图片。配置了此项,webpack在打包时才能根据配置动态修改uri中的相对值,相当于给你的uri加一个 publicPath 前缀!默认前缀是 /
如果在编译时,不知道最终输出文件的 publicPath
是什么地址,则可以将其留空,并且在运行时通过入口起点文件中的 __webpack_public_path__
动态设置
publicPath举例讲解
publicPath举例讲解2
对资源使用 CDN 和 hash 的复杂示例
module.exports = {
//...
output: {
path: '/home/proj/cdn/assets/[fullhash]',
publicPath: 'https://cdn.example.com/assets/[fullhash]/',
},
};
区分不同mode下的publicPath
publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath
6. asyncChunks
创建按需加载的异步 chunk
module.exports = {
//...
output: {
//...
asyncChunks: true,
},
};
7. globalObject
默认为 window
。
当输出为 library 时,尤其是当 library.type
为 'umd'
时,此选项将决定使用哪个全局对象来挂载 library。为了使 UMD 构建在浏览器和 Node.js 上均可用,应将 output.globalObject
选项设置为 'this'
。
8. library
输出一个库,为你的入口做导出
library.name
指定库的名称library.type
指定库暴露的方式library.export
指定哪一个导出应该被暴露为一个库library.auxiliaryComment
在 UMD 包装器中添加注释library.umdNamedDefine
export
替代 output.libraryExport
默认为 undefined
,将会导出整个(命名空间)对象。可以配置成 string 或 string[]
module.exports = {
output: {
library: {
name: 'MyLibrary',
type: 'var',
export: 'default',
},
},
};
入口起点的默认导出将会被赋值为库名称:
// 如果入口有一个默认导出
var MyLibrary = _entry_return_.default;
type
替代 output.libraryTarget
这个参数是用来确定你的bundle中,模块组织是遵循的什么规范
- 赋值成
commonjs
module.exports = {
// …
output: {
library: {
name: 'MyLibrary',
type: 'commonjs',
},
},
};
入口起点的返回值 将使用 output.library.name
赋值给 exports
对象。顾名思义,这是在 CommonJS 环境中使用。
// webpack内部赋值
exports['MyLibrary'] = _entry_return_;
// 使用的js
require('MyLibrary').doSomething();
不设置
output.library.name
将导致入口起点返回的所有属性都被赋值给给定的对象;不检查现有的属性名
- 赋值成
this
module.exports = {
// …
output: {
library: {
name: 'MyLibrary',
type: 'this',
},
},
};
入口起点的返回值 将会被赋值给 this 对象下的 output.library.name
属性。this
的含义取决于你:
this['MyLibrary'] = _entry_return_;
// 在一个单独的脚本中
this.MyLibrary.doSomething();
MyLibrary.doSomething(); // 如果 `this` 为 window 对象
- 赋值成
umd
这将在所有模块定义下暴露你的库, 允许它与 CommonJS、AMD 和作为全局变量工作
module.exports = {
//...
output: {
library: {
name: 'MyLibrary',
type: 'umd',
},
},
};
最终的输出为:
(function webpackUniversalModuleDefinition(root, factory) {
if (typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if (typeof define === 'function' && define.amd) define([], factory);
else if (typeof exports === 'object') exports['MyLibrary'] = factory();
else root['MyLibrary'] = factory();
})(global, function () {
return _entry_return_;
});
单entry
module.exports = {
// …
entry: './src/index.js',
output: {
library: 'MyLibrary',
},
};
假设你在 src/index.js
的入口中导出了如下函数:
export function hello(name) {
console.log(`hello ${name}`);
}
此时,变量 MyLibrary
将与你的入口文件所导出的文件进行绑定,下面是如何使用 webpack 构建的库的实现:
<script src="https://example.org/path/to/my-library.js"></script>
<script>
MyLibrary.hello('webpack');
</script>
数组entry
module.exports = {
// …
entry: ['./src/a.js', './src/b.js'], // 只有在最后一个入口也就是 b.js 中导出的内容才会被暴露
output: {
library: 'MyLibrary',
},
};
对象entry
module.exports = {
// …
entry: {
a: './src/a.js',
b: './src/b.js',
},
output: {
filename: '[name].js',
library: ['MyLibrary', '[name]'], // name is a placeholder here
},
};
假设 a.js
与 b.js
导出名为 hello
的函数,这就是如何使用这些库的方法:
<script src="https://example.org/path/to/a.js"></script>
<script src="https://example.org/path/to/b.js"></script>
<script>
MyLibrary.a.hello('webpack');
MyLibrary.b.hello('webpack');
</script>
entry里配置library
-
module.exports = { // … entry: { main: { import: './src/index.js', library: { // `output.library` 下的所有配置项可以在这里使用 name: 'MyLibrary', type: 'umd', umdNamedDefine: true, }, }, another: { import: './src/another.js', library: { name: 'AnotherLibrary', type: 'commonjs2', }, }, }, };
9. clean
对于 output 目录的清空配置,支持 boolean 或者 对象(dry/keep/function)
module.exports = {
//...
output: {
clean: true, // 在生成文件之前清空 output 目录
},
};
module.exports = {
//...
output: {
clean: {
keep: /ignored/dir//, // 保留 'ignored/dir' 下的静态资源
},
},
};
// 或者
module.exports = {
//...
output: {
clean: {
keep(asset) {
return asset.includes('ignored/dir');
},
},
},
};
也可以使用钩子函数
webpack.CleanPlugin.getCompilationHooks(compilation).keep.tap(
'Test',
(asset) => {
if (/ignored/dir//.test(asset)) return true;
}
);
10. Other
-
scriptType 允许使用自定义 script 类型加载异步 chunk,例如
<script type="module" ...>
-
sourceMapFilename 仅在
devtool
设置为'source-map'
时有效,此选项会向硬盘写入一个输出文件 -
sourcePrefix 修改输出 bundle 中每行的前缀。例如,可以加缩进
'\t'
增加美观,但这会增加代码量,我们一般还要压缩,所以一般都用不到这个 -
chunkLoadTimeout chunk 请求到期之前的毫秒数,默认为 120000
Notice
- 即使可以存在多个
entry
起点,但只能指定一个output
配置