webpack学习笔记 —— output相关知识

273 阅读5分钟

1、概述

output 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。

主要输出文件的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中。

你可以通过在配置中指定一个 output 字段,来配置这些处理过程:

webpack.config.js

const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js',
  },
};

在上面的示例中,我们通过 output.filename 和 output.path 属性,来告诉 webpack bundle 的名称,以及我们想要 bundle 生成(emit)到哪里。可能你想要了解在代码最上面导入的 path 模块是什么,它是一个 Node.js 核心模块,用于操作文件路径。

2、output常见属性

webpack.configoutput包含以下属性:

1、path

代码打包后要输出的位置,且为绝对路径: 例如:path.resolve(__dirname, 'build'),则打包后的代码都会输出到当前目录下的build文件夹内。

2、publicPath

需要加载的资源( 如图片 )的真实路径,默认为''。可以理解为,webpack打包出来地html文件中,script标签会以这个为基准,链接资源。

这个前缀决定了在最终生成的 HTML 文件中,资源链接(如 CSS、JavaScript 文件、图片等)的相对路径是如何计算的。

它的写法有三种情况:

例如:"https://cdn.example.com/assets/"。表示从'https://cdn.example.com/assets/'获取资源。写的是http这种带协议的完整路径,就是CDN,链接互联网资源。 
例如:"/assets/",这是相对于服务器根路径的URL。
例如:"""./",这些比较常见,都是相对于index.html的相对地址

解释:

1、publicPath: './'

publicPath 设置为 './' 时,Webpack 生成的资源链接将是相对于 HTML 文件自身的路径。也就是说,如果 index.html 文件所在的目录也是资源文件所在的目录,那么资源链接将是相对于 index.html 的位置。  

示例

  • 假设 index.html 位于 /dist/ 目录下。
  • 假设生成的资源文件也位于 /dist/ 目录下。

则生成的资源链接将是这样的:

 <script src="./main.js"></script>
 <link rel="stylesheet" href="./styles.css">

这里的 srchref 的路径是相对于 index.html 的位置。

示例

project-root/
|-- dist/
    |-- assets/
        |-- main.js
        |-- styles.css
    |-- index.html
  • 假设 index.html 位于 /dist/ 目录下。
  • 假设生成的资源文件位于 /dist/assets 目录下。那么这时候生成的资源链接将根据实际的目录关系来确定相对路径.

则生成的资源链接是这个样子:

<script src="./assets/main.js"></script>
<link rel="stylesheet" href="./assets/styles.css">

2、publicPath: '/assets/'

publicPath 设置为 '/assets/' 时,Webpack 生成的资源链接的 URL 前缀将是服务器的根路径加上 /assets/。这意味着资源链接将始终从服务器的根路径开始。

示例

  • 假设服务器的根路径是 http://example.com/
  • 假设生成的资源文件位于 /dist/assets/ 目录下。

则生成的资源链接将是这样的:

 <script src="/assets/main.js"></script>
 <link rel="stylesheet" href="/assets/styles.css">

这里的 srchref 的路径是从服务器的根路径开始的,即 http://example.com/assets/

3、publicPath: 'https://cdn.example.com' CDN绝对路径地址


(官网)

module.exports = {
  //...
  output: {
    // One of the below
    publicPath: 'auto', // It automatically determines the public path from either `import.meta.url`, `document.currentScript`, `<script />` or `self.location`.
    publicPath: 'https://cdn.example.com/assets/', // CDN(总是 HTTPS 协议)
    publicPath: '//cdn.example.com/assets/', // CDN(协议相同)
    publicPath: '/assets/', // 相对于服务端根路径(server-relative)
    publicPath: 'assets/', // 相对于 HTML 页面
    publicPath: '../assets/', // 相对于 HTML 页面
    publicPath: '', // 相对于 HTML 页面(目录相同)
  },

相对路径,对于一个输出 HTML 的 loader 可能会像这样输出:

<link href="/assets/spinner.gif" />

或者在加载 CSS 的一个图片时:

background-image: url(/assets/spinner.gif);

(webpack-dev-server 也有个publicPath属性,不过跟 output 的 publicPath 不要混淆,其也会默认从 publicPath 为基准,使用它来决定在哪个目录下启用服务,来访问 webpack 输出的文件)

例如:http://www.baidu.com/dist/, 则在index.html中可以看到script标签的src属性的值都加了publicPath的值。一般情况下我们都将它设置为/或者./

3、crossOriginLoading:

设置scriptcross-origin属性,该属性有三个值:

  • false: 默认值, 表示不跨域;
  • anonymous: 表示跨域,不设置任何凭证;
  • use-credentials: 表示跨域,需要设置凭证;(基本用不到)

4、filename

此选项决定了每个输出 bundle 的名称。这些 bundle 将写入到 output.path 选项指定的目录下。即打包后的js文件名称,且需要写后缀。

module.exports = {
  //...
  output: {
    filename: '[name].bundle.js',
    
    filename: '[id].bundle.js', //使用内部chunk id
   
    filename: '[contenthash].bundle.js', //使用由生成的内容产生的 hash
    
    filename: '[name].[contenthash].bundle.js', //多个结合替换

    filename: (pathData) => {
      return pathData.chunk.name === 'main' ? '[name].js' : '[name]/[name].js';
    }, //使用函数替换

  },
};

可在 chunk 层面进行替换的内容:

模板描述
[id]此 chunk 的 ID
[name]如果设置,则为此 chunk 的名称,否则使用 chunk 的 ID
[chunkhash]此 chunk 的 hash 值,包含该 chunk 的所有元素
[contenthash]此 chunk 的 hash 值,只包括该内容类型的元素(受 optimization.realContentHash 影响)

可在模块层面替换的内容:

模板描述
[id]模块的 ID
[moduleid]同上,但已弃用
[hash]模块的 Hash 值
[modulehash]同上,但已弃用
[contenthash]模块内容的 Hash 值

5、assetModuleFilename

string = '[hash][ext][query]' 静态资源输出名称。

与 output.filename 相同,不过应用于 Asset Modules

对从数据 URI 替换构建的静态资源,[name][file][query][fragment][base] 与 [path] 为空字符串。

6、chunkFilename 

异步引入的文件名称。

即在js中import('XXX.js').then(_=>{})这样引入或者通过webpack自带的异步引入方式等其他异步引入js的方式。默认使用 [id].js 或从 output.filename 中推断出的值([name] 会被预先替换为 [id] 或 [id].)。这里就会使用配置的名称;asseet_[name]_[id].js可以配置成通用形式,也可以自己指定[chunk]值。


【注意】:[hash][contenthash] 或者 [chunkhash] 的长度可以使用 [hash:16],[contenthash:8]这种(默认为 20)来指定。或者,通过指定output.hashDigestLength 在全局配置长度。