官方解释

位于对象最顶级键(key),包括了一组选项,指示 webpack 如何去输出、以及在哪里输出你的「bundle、asset 和其他你所打包或使用 webpack 载入的任何内容」

解析理解

output 配置如何输出最终想要的代码。output 是一个 object,里面包含一系列配置项,配置输出结果。

属性介绍

1. path

output 目录对应一个绝对路径。输出目录。

  1. output: {
  2. path: path.resolve(__dirname, '../dist'),
  3. },

image.png

  1. output: {
  2. path: path.resolve(__dirname, '../dist/front'),
  3. },

image.png

2. filename

配置输出文件的名称。名字可以自己定义格式,静态名称,chunk名称,或者hash值。

下面的例子是多入口。

  1. module.exports = {
  2. context: path.resolve(__dirname, "../src"),
  3. entry: { entry1a: './entry/entry1.js', entry2a: './entry/entry2.js' }, // 对象用法
  4. output: {
  5. filename: '[name].[hash].js',
  6. path: path.resolve(__dirname, '../dist/front'),
  7. },
  8. }

[name].[hash].js:name对应多入口的名称,hash是项目结构hash值。
image.png

3. chunkFilename

此选项决定了非入口(non-entry) chunk 文件的名称。有关可取的值的详细信息,请查看 output.filename 选项。

注意,这些文件名需要在 runtime 根据 chunk 发送的请求去生成。因此,需要在 webpack runtime 输出 bundle 值时,将 chunk id 的值对应映射到占位符(如 [name] 和 [chunkhash])。这会增加文件大小,并且在任何 chunk 的占位符值修改后,都会使 bundle 失效。

下面的例子用来和上面filename进行对比,新增了一个chunkFilename配置项。输出的结果只有common.js有变化,因为**chunkFilename作用与非入口文件,现在只会影响common.js**

  1. module.exports = {
  2. context: path.resolve(__dirname, "../src"),
  3. entry: { entry1a: './entry/entry1.js', entry2a: './entry/entry2.js' }, // 对象用法
  4. output: {
  5. filename: '[name].[hash].js',
  6. chunkFilename: '[name].js',
  7. path: path.resolve(__dirname, '../dist/front'),
  8. },
  9. }

image.png

4. publicPath

在复杂的项目里可能会有一些构建出的资源需要异步加载,加载这些异步资源需要对应的 URL 地址。
output.publicPath 配置发布到线上资源的 URL 前缀,为string 类型。 默认值是空字符串 ‘’,即使用相对路径。

  1. output: {
  2. filename: '[name].[hash].js',
  3. chunkFilename: '[name].js',
  4. path: path.resolve(__dirname, '../dist/front'),
  5. publicPath: '/front'
  6. }

image.png

其他属性

待添加

Demo地址

https://github.com/rodchen-king/wepack-learn/commit/9c4b4b8288f7c8ffae1ea677bbc7e10f1d466198

相关知识

1. hash / chunkhash / contenthash的区别

hash:使用hash的话,因为这是工程级别的,即每次修改任何一个文件,所有文件名的hash至都将改变。文件的hash值也相同。

  1. const path = require('path');
  2. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  3. const HtmlWebpackPlugin = require('html-webpack-plugin');
  4. const { CleanWebpackPlugin } = require('clean-webpack-plugin');
  5. module.exports = {
  6. context: path.resolve(__dirname, "../src"),
  7. // entry: './entry/entry1.js', // 字符串用法
  8. // entry: ['./entry/entry2.js', './entry/entry1.js'], // 数组用法
  9. entry: { entry1a: './entry/entry1.js', entry2a: './entry/entry2.js' }, // 对象用法
  10. output: {
  11. filename: '[name].[hash].js',
  12. chunkFilename: '[name].[hash].js',
  13. path: path.resolve(__dirname, '../dist/front'),
  14. publicPath: '/front'
  15. },
  16. resolve: { // 路径别名
  17. alias: {
  18. '@': path.resolve('src')
  19. }
  20. },
  21. ...
  22. plugins: [
  23. new MiniCssExtractPlugin({
  24. filename: '[name].[hash].css'
  25. }),
  26. new HtmlWebpackPlugin(),
  27. new CleanWebpackPlugin()
  28. ]
  29. };

image.png

chunkhash:根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。把上面的配置文件中的[hash] => [chunkhash]

  1. const path = require('path');
  2. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  3. const HtmlWebpackPlugin = require('html-webpack-plugin');
  4. const { CleanWebpackPlugin } = require('clean-webpack-plugin');
  5. module.exports = {
  6. context: path.resolve(__dirname, "../src"),
  7. // entry: './entry/entry1.js', // 字符串用法
  8. // entry: ['./entry/entry2.js', './entry/entry1.js'], // 数组用法
  9. entry: { entry1a: './entry/entry1.js', entry2a: './entry/entry2.js' }, // 对象用法
  10. output: {
  11. filename: '[name].[chunkhash].js',
  12. chunkFilename: '[name].[chunkhash].js',
  13. path: path.resolve(__dirname, '../dist/front'),
  14. publicPath: '/front'
  15. },
  16. resolve: { // 路径别名
  17. alias: {
  18. '@': path.resolve('src')
  19. }
  20. },
  21. ...
  22. plugins: [
  23. new MiniCssExtractPlugin({
  24. filename: '[name].[chunkhash].css'
  25. }),
  26. new HtmlWebpackPlugin(),
  27. new CleanWebpackPlugin()
  28. ]
  29. };

image.png

我们可以看到一个入口相关的文件hash值是相同的。两个入口的hash值不同。common是公共chunk,和其他的也不同。chunkhash有一个什么问题呢。现在修改entry2的css文件,然后执行build。
image.png

css文件的修改会影响一个chunk的所有文件。所以引出contenthash。

contenthash: 文件内容级别的,只有你自己模块的内容变了,那么hash值才改变
可以看到一个chunk下的js和css是不同的contenthash。
image.png

2. chunkname和filename的联系

chunkname配置不存在的时候,非入口文件的文件名称沿用filename的配置。

  1. filename: '[name].[contenthash].js',
  2. chunkFilename: '[name].[hash].js',

Cannot use [chunkhash] or [contenthash] for chunk in ‘[name].[contenthash].js’ (use [hash] instead)
image.png