Webpack Output(輸出)

2023-05-15 17:25 更新

?output? 位于對象最頂級鍵(key),包括了一組選項,指示 webpack 如何去輸出、以及在哪里輸出你的「bundle、asset 和其他你所打包或使用 webpack 載入的任何內(nèi)容」。

output.assetModuleFilename

?string = '[hash][ext][query]'?

與 ?output.filename? 相同,不過應(yīng)用于 Asset Modules。

對從數(shù)據(jù) URI 替換構(gòu)建的靜態(tài)資源,?[name]?, ?[file]?, ?[query]?, ?[fragment]?, ?[base]? 與 ?[path]? 為空字符串。

output.asyncChunks

?boolean = true?

創(chuàng)建按需加載的異步 chunk。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    asyncChunks: true,
  },
};

output.auxiliaryComment

?string? ?object?

在和 ?output.library? 和 ?output.libraryTarget? 一起使用時,此選項允許用戶向?qū)С鋈萜?export wrapper)中插入注釋。要為 libraryTarget 每種類型都插入相同的注釋,將 ?auxiliaryComment? 設(shè)置為一個字符串:

webpack.config.js

module.exports = {
  //...
  output: {
    library: 'someLibName',
    libraryTarget: 'umd',
    filename: 'someLibName.js',
    auxiliaryComment: 'Test Comment',
  },
};

將會生成如下:

someLibName.js

(function webpackUniversalModuleDefinition(root, factory) {
  // Test Comment
  if (typeof exports === 'object' && typeof module === 'object')
    module.exports = factory(require('lodash'));
  // Test Comment
  else if (typeof define === 'function' && define.amd)
    define(['lodash'], factory);
  // Test Comment
  else if (typeof exports === 'object')
    exports['someLibName'] = factory(require('lodash'));
  // Test Comment
  else root['someLibName'] = factory(root['_']);
})(this, function (__WEBPACK_EXTERNAL_MODULE_1__) {
  // ...
});

對于 ?libraryTarget? 每種類型的注釋進(jìn)行更細(xì)粒度地控制,請傳入一個對象:

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    auxiliaryComment: {
      root: 'Root Comment',
      commonjs: 'CommonJS Comment',
      commonjs2: 'CommonJS2 Comment',
      amd: 'AMD Comment',
    },
  },
};

output.charset

?boolean = true?

告訴 webpack 為 HTML 的 ?<script>? 標(biāo)簽添加 ?charset="utf-8"? 標(biāo)識。

output.chunkFilename

?string = '[id].js'? ?function (pathData, assetInfo) => string?

此選項決定了非初始(non-initial)chunk 文件的名稱。有關(guān)可取的值的詳細(xì)信息,請查看 ?output.filename? 選項。

注意,這些文件名需要在運行時根據(jù) chunk 發(fā)送的請求去生成。因此,需要在 webpack runtime 輸出 bundle 值時,將 chunk id 的值對應(yīng)映射到占位符(如 ?[name]? 和 ?[chunkhash]?)。這會增加文件大小,并且在任何 chunk 的占位符值修改后,都會使 bundle 失效。

默認(rèn)使用 ?[id].js? 或從 ?output.filename? 中推斷出的值(?[name]? 會被預(yù)先替換為 ?[id]? 或 ?[id]?.)。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    chunkFilename: '[id].js',
  },
};

Usage as a function:

webpack.config.js

module.exports = {
  //...
  output: {
    chunkFilename: (pathData) => {
      return pathData.chunk.name === 'main' ? '[name].js' : '[name]/[name].js';
    },
  },
};

output.chunkFormat

?false? ?string: 'array-push' | 'commonjs' | 'module' | <any string>?

chunk 的格式(formats 默認(rèn)包含 ?'array-push' ?(web/WebWorker)、?'commonjs'? (node.js)、?'module'? (ESM),還有其他情況可由插件添加)。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    chunkFormat: 'commonjs',
  },
};

output.chunkLoadTimeout $#outputchunkLoadtimeout$

?number = 120000?

chunk 請求到期之前的毫秒數(shù),默認(rèn)為 120000。從 webpack 2.6.0 開始支持此選項。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    chunkLoadTimeout: 30000,
  },
};

output.chunkLoadingGlobal

?string = 'webpackChunkwebpack'?

webpack 用于加載 chunk 的全局變量。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    chunkLoadingGlobal: 'myCustomFunc',
  },
};

output.chunkLoading

?false? ?string: 'jsonp' | 'import-scripts' | 'require' | 'async-node' | 'import' | <any string>

加載 chunk 的方法(默認(rèn)值有 ?'jsonp'? (web)、?'import'? (ESM)、?'importScripts'? (WebWorker)、?'require'? (sync node.js)、?'async-node'? (async node.js),還有其他值可由插件添加)。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    chunkLoading: 'async-node',
  },
};

output.clean

5.20.0+

?boolean? ?{ dry?: boolean, keep?: RegExp | string | ((filename: string) => boolean) }

module.exports = {
  //...
  output: {
    clean: true, // 在生成文件之前清空 output 目錄
  },
};
module.exports = {
  //...
  output: {
    clean: {
      dry: true, // 打印而不是刪除應(yīng)該移除的靜態(tài)資源
    },
  },
};
module.exports = {
  //...
  output: {
    clean: {
      keep: /ignored\/dir\//, // 保留 'ignored/dir' 下的靜態(tài)資源
    },
  },
};

// 或者

module.exports = {
  //...
  output: {
    clean: {
      keep(asset) {
        return asset.includes('ignored/dir');
      },
    },
  },
};

你也可以使用鉤子函數(shù):

webpack.CleanPlugin.getCompilationHooks(compilation).keep.tap(
  'Test',
  (asset) => {
    if (/ignored\/dir\//.test(asset)) return true;
  }
);

output.compareBeforeEmit

?boolean = true?

告知 webpack 在寫入到輸出文件系統(tǒng)時檢查輸出的文件是否已經(jīng)存在并且擁有相同內(nèi)容。

module.exports = {
  //...
  output: {
    compareBeforeEmit: false,
  },
};

output.crossOriginLoading

?boolean = false? ?string: 'anonymous' | 'use-credentials'?

告訴 webpack 啟用 cross-origin 屬性 加載 chunk。僅在 ?target? 設(shè)置為 'web' 時生效,通過使用 JSONP 來添加腳本標(biāo)簽,實現(xiàn)按需加載模塊。

  • ?'anonymous'? - 不帶憑據(jù)(credential) 啟用跨域加載
  • ?'use-credentials'? - 攜帶憑據(jù)(credential) 啟用跨域加載

output.devtoolFallbackModuleFilenameTemplate

?string? ?function (info)?

當(dāng)上面的模板字符串或函數(shù)產(chǎn)生重復(fù)時使用的備用內(nèi)容。

output.devtoolModuleFilenameTemplate

?string = 'webpack://[namespace]/[resource-path]?[loaders]'? ?function (info) => string?

此選項僅在 「?devtool? 使用了需要模塊名稱的選項」時使用。

自定義每個 source map 的 ?sources? 數(shù)組中使用的名稱??梢酝ㄟ^傳遞模板字符串(template string)或者函數(shù)來完成。例如,當(dāng)使用 ?devtool: 'eval'?,默認(rèn)值是:

webpack.config.js

module.exports = {
  //...
  output: {
    devtoolModuleFilenameTemplate:
      'webpack://[namespace]/[resource-path]?[loaders]',
  },
};

模板字符串(template string)中做以下替換(通過 webpack 內(nèi)部的 ):

Template Description
[absolute-resource-path] 絕對路徑文件名
[all-loaders] 自動和顯式的 loader,并且參數(shù)取決于第一個 loader 名稱
[hash] 模塊標(biāo)識符的 hash
[id] 模塊標(biāo)識符
[loaders] 顯式的 loader,并且參數(shù)取決于第一個 loader 名稱
[resource] 用于解析文件的路徑和用于第一個 loader 的任意查詢參數(shù)
[resource-path] 不帶任何查詢參數(shù),用于解析文件的路徑
[namespace] 模塊命名空間。在構(gòu)建成為一個 library 之后,通常也是 library 名稱,否則為空

當(dāng)使用一個函數(shù),同樣的選項要通過 info 參數(shù)并使用駝峰式(camel-cased):

module.exports = {
  //...
  output: {
    devtoolModuleFilenameTemplate: (info) => {
      return `webpack:///${info.resourcePath}?${info.loaders}`;
    },
  },
};

如果多個模塊產(chǎn)生相同的名稱,使用 ?output.devtoolFallbackModuleFilenameTemplate? 來代替這些模塊。

output.devtoolNamespace

?string?

此選項確定 ?output.devtoolModuleFilenameTemplate? 使用的模塊名稱空間。未指定時的默認(rèn)值為:?output.uniqueName?。在加載多個通過 webpack 構(gòu)建的 library 時,用于防止 source map 中源文件路徑?jīng)_突。

例如,如果你有兩個 library,分別使用命名空間 library1 和 library2,并且都有一個文件 ?./src/index.js?(可能具有不同內(nèi)容),它們會將這些文件暴露為 ?webpack://library1/./src/index.js? 和 ?webpack://library2/./src/index.js?。

output.enabledChunkLoadingTypes

?[string: 'jsonp' | 'import-scripts' | 'require' | 'async-node' | <any string>]?

允許入口點使用的 chunk 加載類型列表。將被 webpack 自動填充。只有當(dāng)使用一個函數(shù)作為入口配置項并從那里返回 chunkLoading 配置項時才需要。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    enabledChunkLoadingTypes: ['jsonp', 'require'],
  },
};

output.enabledLibraryTypes

?[string]?

入口點可用的 library 類型列表.

module.exports = {
  //...
  output: {
    enabledLibraryTypes: ['module'],
  },
};

output.enabledWasmLoadingTypes

?[string]?

用于設(shè)置入口支持的 wasm 加載類型的列表。

module.exports = {
  //...
  output: {
    enabledWasmLoadingTypes: ['fetch'],
  },
};

## `output.environment` $#outputenvironment$

告訴 webpack 在生成的運行時代碼中可以使用哪個版本的 ES 特性。

```javascript
module.exports = {
  output: {
    environment: {
      // The environment supports arrow functions ('() => { ... }').
      arrowFunction: true,
      // The environment supports BigInt as literal (123n).
      bigIntLiteral: false,
      // The environment supports const and let for variable declarations.
      const: true,
      // The environment supports destructuring ('{ a, b } = obj').
      destructuring: true,
      // The environment supports an async import() function to import EcmaScript modules.
      dynamicImport: false,
      // The environment supports 'for of' iteration ('for (const x of array) { ... }').
      forOf: true,
      // The environment supports ECMAScript Module syntax to import ECMAScript modules (import ... from '...').
      module: false,
      // The environment supports optional chaining ('obj?.a' or 'obj?.()').
      optionalChaining: true,
      // The environment supports template literals.
      templateLiteral: true,
    },
  },
};

output.filename

string function (pathData, assetInfo) => string

此選項決定了每個輸出 bundle 的名稱。這些 bundle 將寫入到 ?output.path? 選項指定的目錄下。

對于單個?入口?起點,filename 會是一個靜態(tài)名稱。

webpack.config.js

module.exports = {
  //...
  output: {
    filename: 'bundle.js',
  },
};

然而,當(dāng)通過多個入口起點(entry point)、代碼拆分(code splitting)或各種插件(plugin)創(chuàng)建多個 bundle,應(yīng)該使用以下一種替換方式,來賦予每個 bundle 一個唯一的名稱……

使用入口名稱:

webpack.config.js

module.exports = {
  //...
  output: {
    filename: '[name].bundle.js',
  },
};

使用內(nèi)部 chunk id

webpack.config.js

module.exports = {
  //...
  output: {
    filename: '[id].bundle.js',
  },
};

使用由生成的內(nèi)容產(chǎn)生的 hash:

webpack.config.js

module.exports = {
  //...
  output: {
    filename: '[contenthash].bundle.js',
  },
};

結(jié)合多個替換組合使用:

webpack.config.js

module.exports = {
  //...
  output: {
    filename: '[name].[contenthash].bundle.js',
  },
};

使用函數(shù)返回 filename:

webpack.config.js

module.exports = {
  //...
  output: {
    filename: (pathData) => {
      return pathData.chunk.name === 'main' ? '[name].js' : '[name]/[name].js';
    },
  },
};

請確保已閱讀過 指南 - 緩存 的詳細(xì)信息。這里涉及更多步驟,不僅僅是設(shè)置此選項。

注意此選項被稱為文件名,但是你還是可以使用像 ?'js/[name]/bundle.js' ?這樣的文件夾結(jié)構(gòu)。

注意,此選項不會影響那些「按需加載 chunk」的輸出文件。它只影響最初加載的輸出文件。對于按需加載的 chunk 文件,請使用 ?output.chunkFilename? 選項來控制輸出。通過 loader 創(chuàng)建的文件也不受影響。在這種情況下,你必須嘗試 loader 特定的可用選項。

Template strings

可以使用以下替換模板字符串(通過 webpack 內(nèi)部的?TemplatedPathPlugin?):

可在編譯層面進(jìn)行替換的內(nèi)容:

模板 描述
[fullhash] compilation 完整的 hash 值
[hash] 同上,但已棄用

可在 chunk 層面進(jìn)行替換的內(nèi)容:

模板 描述
[id] 此 chunk 的 ID
[name] 如果設(shè)置,則為此 chunk 的名稱,否則使用 chunk 的 ID
[chunkhash] 此 chunk 的 hash 值,包含該 chunk 的所有元素
[contenthash] 此 chunk 的 hash 值,只包括該內(nèi)容類型的元素(受 optimization.realContentHash 影響)

可在模塊層面替換的內(nèi)容:

模板 描述
[id] 模塊的 ID
[moduleid] 同上,但已棄用
[hash] 模塊的 Hash 值
[modulehash] 同上,但已棄用
[contenthash] 模塊內(nèi)容的 Hash 值

可在文件層面替換的內(nèi)容:

模板 描述
[file] filename 和路徑,不含 query 或 fragment
[query] 帶前綴 ? 的 query
[fragment] 帶前綴 # 的 fragment
[base] 只有 filename(包含擴展名),不含 path
[filebase] 同上,但已棄用
[path] 只有 path,不含 filename
[name] 只有 filename,不含擴展名或 path
[ext] 帶前綴 . 的擴展名(對 ?output.filename? 不可用)

可在 URL 層面替換的內(nèi)容:

模塊 描述
[url] URL

?[hash]?,?[contenthash]? 或者 ?[chunkhash]? 的長度可以使用 ?[hash:16]?(默認(rèn)為 20)來指定?;蛘?,通過指定?output.hashDigestLength? 在全局配置長度。

當(dāng)你要在實際文件名中使用占位符時,webpack 會過濾出需要替換的占位符。例如,輸出一個文件 ?[name].js?, 你必須通過在括號之間添加反斜杠來轉(zhuǎn)義?[name]?占位符。 因此,?[\name\]? 生成 ?[name]? 而不是 ?name?。

例如:?[\id\]? 生成 ?[id]? 而不是 ?id?。

如果將這個選項設(shè)為一個函數(shù),函數(shù)將返回一個包含上面表格中含有替換信息數(shù)據(jù)的對象。 替換也會被應(yīng)用到返回的字符串中。 傳遞的對象將具有如下類型(取決于上下文的屬性):

type PathData = {
  hash: string;
  hashWithLength: (number) => string;
  chunk: Chunk | ChunkPathData;
  module: Module | ModulePathData;
  contentHashType: string;
  contentHash: string;
  contentHashWithLength: (number) => string;
  filename: string;
  url: string;
  runtime: string | SortableSet<string>;
  chunkGraph: ChunkGraph;
};
type ChunkPathData = {
  id: string | number;
  name: string;
  hash: string;
  hashWithLength: (number) => string;
  contentHash: Record<string, string>;
  contentHashWithLength: Record<string, (number) => string>;
};
type ModulePathData = {
  id: string | number;
  hash: string;
  hashWithLength: (number) => string;
};

output.globalObject

?string = 'self'?

當(dāng)輸出為 library 時,尤其是當(dāng) ?libraryTarget? 為 ?'umd'?時,此選項將決定使用哪個全局對象來掛載 library。為了使 UMD 構(gòu)建在瀏覽器和 Node.js 上均可用,應(yīng)將 ?output.globalObject? 選項設(shè)置為 ?'this'?。對于類似 web 的目標(biāo),默認(rèn)為 ?self?。

入口點的返回值將會使用 ?output.library.name? 賦值給全局對象。依賴于 ?target? 配置項,全局對象將會發(fā)生對應(yīng)的改變,例如:?self?, ?global? 或者 ?globalThis?。

示例:

webpack.config.js

module.exports = {
  // ...
  output: {
    library: 'myLib',
    libraryTarget: 'umd',
    filename: 'myLib.js',
    globalObject: 'this',
  },
};

output.hashDigest

?string = 'hex'?

在生成 hash 時使用的編碼方式。支持 Node.js ?hash.digest? 的所有編碼。對文件名使用 ?'base64'?,可能會出現(xiàn)問題,因為 base64 字母表中具有 / 這個字符(character)。同樣的,'latin1' 規(guī)定可以含有任何字符(character)。

output.hashDigestLength

?number = 20?

散列摘要的前綴長度。

output.hashFunction

?string = 'md4'? ?function?

散列算法。支持 Node.JS ?crypto.createHash? 的所有功能。從 ?4.0.0-alpha2? 開始,hashFunction 現(xiàn)在可以是一個返回自定義 hash 的構(gòu)造函數(shù)。出于性能原因,你可以提供一個不加密的哈希函數(shù)(non-crypto hash function)。

module.exports = {
  //...
  output: {
    hashFunction: require('metrohash').MetroHash64,
  },
};

確保 hash 函數(shù)有可訪問的 ?update? 和 ?digest? 方法。

output.hashSalt

一個可選的加鹽值,通過 Node.JS ?hash.update? 來更新哈希。

output.hotUpdateChunkFilename

?string = '[id].[fullhash].hot-update.js'?

自定義熱更新 chunk 的文件名??蛇x的值的詳細(xì)信息,請查看 ?output.filename? 選項。

其中值唯一的占位符是 [id] 和 [fullhash],其默認(rèn)為:

webpack.config.js

module.exports = {
  //...
  output: {
    hotUpdateChunkFilename: '[id].[fullhash].hot-update.js',
  },
};

output.hotUpdateGlobal

?string?

只在 ?target? 設(shè)置為 ?'web'? 時使用,用于加載熱更新(hot update)的 JSONP 函數(shù)。

JSONP 函數(shù)用于異步加載(async load)熱更新(hot-update) chunk。

output.hotUpdateMainFilename

?string = '[runtime].[fullhash].hot-update.json'? ?function?

自定義熱更新的主文件名(main filename)。?[fullhash]? 和 ?[runtime]? 均可作為占位符。

output.iife

?boolean = true?

告訴 webpack 添加 IIFE 外層包裹生成的代碼.

module.exports = {
  //...
  output: {
    iife: true,
  },
};

output.importFunctionName

?string = 'import'?

內(nèi)部 ?import()? 函數(shù)的名稱. 可用于 polyfilling, 例如 通過 ?dynamic-import-polyfill?.

webpack.config.js

module.exports = {
  //...
  output: {
    importFunctionName: '__import__',
  },
};

output.library

輸出一個庫,為你的入口做導(dǎo)出。

  • 類型:?string | string[] | object?

一起來看一個簡單的示例。

webpack.config.js

module.exports = {
  // …
  entry: './src/index.js',
  output: {
    library: 'MyLibrary',
  },
};

假設(shè)你在 ?src/index.js? 的入口中導(dǎo)出了如下函數(shù):

export function hello(name) {
  console.log(`hello ${name}`);
}

此時,變量 ?MyLibrary? 將與你的入口文件所導(dǎo)出的文件進(jìn)行綁定,下面是如何使用 webpack 構(gòu)建的庫的實現(xiàn):

<script src="https://example.org/path/to/my-library.js" rel="external nofollow" ></script>
<script>
  MyLibrary.hello('webpack');
</script>

在上面的例子中,我們?yōu)?nbsp;?entry? 設(shè)置了一個入口文件,然而 webpack 可以接受 多個入口,例如一個 ?array? 或者一個 ?object?。

  1. 如果你將 entry 設(shè)置為一個 array,那么只有數(shù)組中的最后一個會被暴露。
    module.exports = {
      // …
      entry: ['./src/a.js', './src/b.js'], // 只有在 b.js 中導(dǎo)出的內(nèi)容才會被暴露
      output: {
        library: 'MyLibrary',
      },
    };
  2. 如果你將 entry 設(shè)置為一個 object,所以入口都可以通過 library 的 array 語法暴露:
    module.exports = {
      // …
      entry: {
        a: './src/a.js',
        b: './src/b.js',
      },
      output: {
        filename: '[name].js',
        library: ['MyLibrary', '[name]'], // name is a placeholder here
      },
    };

假設(shè) a.js 與 b.js 導(dǎo)出名為 hello 的函數(shù),這就是如何使用這些庫的方法:

<script src="https://example.org/path/to/a.js" rel="external nofollow" ></script>
<script src="https://example.org/path/to/b.js" rel="external nofollow" ></script>
<script>
  MyLibrary.a.hello('webpack');
  MyLibrary.b.hello('webpack');
</script>

查看 示例 獲取更多內(nèi)容。

請注意,如果你打算在每個入口點配置 library 配置項的話,以上配置將不能按照預(yù)期執(zhí)行。這里是如何 在每個入口點下 做的方法:

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',
      },
    },
  },
};

    output.library.name

    module.exports = {
      // …
      output: {
        library: {
          name: 'MyLibrary',
        },
      },
    };

    指定庫的名稱。

    • 類型:
      string | string[] | {amd?: string, commonjs?: string, root?: string | string[]}

    output.library.type

    配置將庫暴露的方式。

    • 類型:?string?

    類型默認(rèn)包括 ?'var'?、 ?'module'?、 ?'assign'?、 ?'assign-properties'?、 ?'this'?、 ?'window'?、 ?'self'?、 ?'global'?、 ?'commonjs'?、 ?'commonjs2'?、 ?'commonjs-module'?、 ?'commonjs-static'?、 ?'amd'?、 ?'amd-require'?、 ?'umd'?、 ?'umd2'?、 ?'jsonp'? 以及 ?'system'?,除此之外也可以通過插件添加。

      對于接下來的示例,我們將會使用 ?_entry_return_? 表示被入口點返回的值。

      Expose a Variable

      這些選項將入口點的返回值(例如,入口點導(dǎo)出的內(nèi)容)分配給輸出庫的名稱(由 ?output.library.name? 提供),并將其包含在包被引入的作用域中。

      type: 'var'
      module.exports = {
        // …
        output: {
          library: {
            name: 'MyLibrary',
            type: 'var',
          },
        },
      };

      讓你的庫加載之后,入口起點的返回值 將會被賦值給一個變量:

      var MyLibrary = _entry_return_;
      
      // 在加載了 `MyLibrary` 的單獨腳本中
      MyLibrary.doSomething();
      type: 'assign'
      module.exports = {
        // …
        output: {
          library: {
            name: 'MyLibrary',
            type: 'assign',
          },
        },
      };

      這將生成一個隱含的全局變量,它有可能重新分配一個現(xiàn)有的值(請謹(jǐn)慎使用):

      MyLibrary = _entry_return_;

      請注意,如果 ?MyLibrary? 沒有在你的庫之前定義,那么它將會被設(shè)置在全局作用域。

      type: 'assign-properties'

      ?5.16.0+?

      module.exports = {
        // …
        output: {
          library: {
            name: 'MyLibrary',
            type: 'assign-properties',
          },
        },
      };

      與 ?type: 'assign'? 相似但是更安全,因為如果 ?MyLibrary? 已經(jīng)存在的話,它將被重用:

      // 僅在當(dāng)其不存在是創(chuàng)建 MyLibrary
      MyLibrary = typeof MyLibrary === 'undefined' ? {} : MyLibrary;
      // 然后復(fù)制返回值到 MyLibrary
      // 與 Object.assign 行為類似
      
      // 例如,你像下面這樣在你的入口導(dǎo)出一個 `hello` 函數(shù)
      export function hello(name) {
        console.log(`Hello ${name}`);
      }
      
      // 在另外一個已經(jīng)加載 MyLibrary 的腳本中
      // 你可以像這樣運行 `hello` 函數(shù)
      MyLibrary.hello('World');

      Expose Via Object Assignment

      這些配置項分配入口點的返回值(例如:無論入口點導(dǎo)出的什么內(nèi)容)到一個名為 ?output.library.name? 的對象中。

      type: '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 對象
      type: 'window'
      module.exports = {
        // …
        output: {
          library: {
            name: 'MyLibrary',
            type: 'window',
          },
        },
      };

      入口起點的返回值 將會被賦值給 window 對象下的 output.library.name。

      window['MyLibrary'] = _entry_return_;
      
      window.MyLibrary.doSomething();
      type: 'global'
      module.exports = {
        // …
        output: {
          library: {
            name: 'MyLibrary',
            type: 'global',
          },
        },
      };

      入口起點的返回值 將會被復(fù)制給全局對象下的 ?output.library.name?。取決于 ?target? 值,全局對象可以分別改變,例如,?self?、?global? 或者 ?globalThis?。

      global['MyLibrary'] = _entry_return_;
      
      global.MyLibrary.doSomething();
      type: 'commonjs'
      module.exports = {
        // …
        output: {
          library: {
            name: 'MyLibrary',
            type: 'commonjs',
          },
        },
      };

      入口起點的返回值 將使用 output.library.name 賦值給 exports 對象。顧名思義,這是在 CommonJS 環(huán)境中使用。

      exports['MyLibrary'] = _entry_return_;
      
      require('MyLibrary').doSomething();

      Module Definition Systems

      這些配置項將生成一個帶有完整 header 的 bundle,以確保與各種模塊系統(tǒng)兼容。?output.library.name? 配置項在不同的 ?output.library.type? 中有不同的含義。

      type: 'module'
      module.exports = {
        // …
        experiments: {
          outputModule: true,
        },
        output: {
          library: {
            // do not specify a `name` here
            type: 'module',
          },
        },
      };

      輸出 ES 模塊。

      然而該特性仍然是實驗性的,并且沒有完全支持,所以請確保事先啟用 experiments.outputModule。除此之外,你可以在 這里 追蹤開發(fā)進(jìn)度。

      type: 'commonjs2'
      module.exports = {
        // …
        output: {
          library: {
            // note there's no `name` here
            type: 'commonjs2',
          },
        },
      };

      入口起點的返回值 將會被賦值給 module.exports。顧名思義,這是在 Node.js(CommonJS)環(huán)境中使用的:

      module.exports = _entry_return_;
      
      require('MyLibrary').doSomething();

      如果我們指定 ?output.library.name? 為 ?type: commmonjs2?,你的入口起點的返回值將會被賦值給 ?module.exports.[output.library.name]?。

      type: 'commonjs-static'

      ?5.66.0+?

      module.exports = {
        // …
        output: {
          library: {
            // note there's no `name` here
            type: 'commonjs-static',
          },
        },
      };

      單個導(dǎo)出將被設(shè)置為 ?module.exports? 中的屬性。名稱中的 "static" 是指輸出是靜態(tài)可分析的,因此具名導(dǎo)出可以通過 Node.js 導(dǎo)入到 ESM 中:

      輸入:

      export function doSomething() {}

      輸出:

      function doSomething() {}
      
      // …
      
      exports.doSomething = __webpack_exports__.doSomething;

      Consumption (CommonJS):

      const { doSomething } = require('./output.cjs'); // doSomething => [Function: doSomething]

      Consumption (ESM):

      import { doSomething } from './output.cjs'; // doSomething => [Function: doSomething]
      type: 'amd'

      可以將你的庫暴露為 AMD 模塊。

      AMD module 要求入口 chunk(例如,第一個通過 ?<script>? 標(biāo)簽加載的腳本)使用特定的屬性來定義, 例如 ?define? 與 ?require?,這通常由 RequireJS 或任何兼容的 loader(如 almond)提供。否則,直接加載產(chǎn)生的 AMD bundle 將導(dǎo)致一個錯誤,如 ?define is not defined?。

      按照下面的配置

      module.exports = {
        //...
        output: {
          library: {
            name: 'MyLibrary',
            type: 'amd',
          },
        },
      };

      生成的輸出將被定義為 ?"MyLibrary"?,例如:

      define('MyLibrary', [], function () {
        return _entry_return_;
      });

      該 bundle 可以使用 script 標(biāo)簽引入,并且可以被這樣引入:

      require(['MyLibrary'], function (MyLibrary) {
        // Do something with the library...
      });

      如果沒有定義 ?output.library.name? 的話,會生成以下內(nèi)容。

      define(function () {
        return _entry_return_;
      });

      如果使用一個 ?<script>? 標(biāo)簽直接加載。它只能通過 RequireJS 兼容的異步模塊 loader 通過文件的實際路徑工作,所以在這種情況下,如果 ?output.path? 與 ?output.filename? 直接在服務(wù)端暴露,那么對于這種特殊設(shè)置可能會變得很重要。

      type: 'amd-require'
      module.exports = {
        //...
        output: {
          library: {
            name: 'MyLibrary',
            type: 'amd-require',
          },
        },
      };

      它會用一個立即執(zhí)行的 AMD ?require(dependencies, factory)? 包裝器來打包輸出。

      ?'amd-require'? 類型允許使用 AMD 的依賴,而不需要單獨的后續(xù)調(diào)用。與 ?'amd'? 類型一樣,這取決于在加載 webpack 輸出的環(huán)境中適當(dāng)?shù)?nbsp;?require? 函數(shù) 是否可用。

      使用該類型的話,不能使用庫的名稱。

      type: 'umd'

      這將在所有模塊定義下暴露你的庫, 允許它與 CommonJS、AMD 和作為全局變量工作??梢圆榭?nbsp;UMD Repository 獲取更多內(nèi)容。

      在這種情況下,你需要使用 ?library.name? 屬性命名你的模塊:

      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_;
      });

      請注意,根據(jù) 對象賦值部分,省略 ?library.name? 將導(dǎo)致入口起點返回的所有屬性直接賦值給根對象。示例:

      module.exports = {
        //...
        output: {
          libraryTarget: '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 {
          var a = factory();
          for (var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
        }
      })(global, function () {
        return _entry_return_;
      });

      你可以為 library.name 指定一個對象,每個目標(biāo)的名稱不同:

      module.exports = {
        //...
        output: {
          library: {
            name: {
              root: 'MyLibrary',
              amd: 'my-library',
              commonjs: 'my-common-library',
            },
            type: 'umd',
          },
        },
      };
      type: 'system'

      這將會把你的庫暴露為一個 ?System.register? 模塊。這個特性最初是在 webpack 4.30.0 中發(fā)布。

      System 模塊要求當(dāng) webpack bundle 執(zhí)行時,全局變量 ?System? 出現(xiàn)在瀏覽器中。編譯的 ?System.register? 格式允許你在沒有額外配置的情況下使用 ?System.import('/bundle.js')?,并將你的 webpack bundle 加載到系統(tǒng)模塊注冊表中。

      module.exports = {
        //...
        output: {
          library: {
            type: 'system',
          },
        },
      };

      輸出:

      System.register([], function (__WEBPACK_DYNAMIC_EXPORT__, __system_context__) {
        return {
          execute: function () {
            // ...
          },
        };
      });

      除了設(shè)置 ?output.library.type? 為 ?system?,還要將 ?output.library.name? 添加到配置中,輸出的 bundle 將以庫名作為 ?System.register? 的參數(shù):

      System.register(
        'MyLibrary',
        [],
        function (__WEBPACK_DYNAMIC_EXPORT__, __system_context__) {
          return {
            execute: function () {
              // ...
            },
          };
        }
      );

      Other Types

      type: 'jsonp'
      module.exports = {
        // …
        output: {
          library: {
            name: 'MyLibrary',
            type: 'jsonp',
          },
        },
      };

      這將把入口起點的返回值包裝到 jsonp 包裝器中。

      MyLibrary(_entry_return_);

      你的庫的依賴將由 ?externals? 配置定義。

      output.library.export

      指定哪一個導(dǎo)出應(yīng)該被暴露為一個庫。

      • 類型:?string | string[]?

      默認(rèn)為 ?undefined?,將會導(dǎo)出整個(命名空間)對象。下面的例子演示了使用 ?output.library.type: 'var'? 配置項產(chǎn)生的作用。

      module.exports = {
        output: {
          library: {
            name: 'MyLibrary',
            type: 'var',
            export: 'default',
          },
        },
      };

      入口起點的默認(rèn)導(dǎo)出將會被賦值為庫名稱:

      // 如果入口有一個默認(rèn)導(dǎo)出
      var MyLibrary = _entry_return_.default;

      你也可以向 ?output.library.export? 傳遞一個數(shù)組,它將被解析為一個要分配給庫名的模塊的路徑:

      module.exports = {
        output: {
          library: {
            name: 'MyLibrary',
            type: 'var',
            export: ['default', 'subModule'],
          },
        },
      };

      這里就是庫代碼:

      var MyLibrary = _entry_return_.default.subModule;

      output.library.auxiliaryComment

      在 UMD 包裝器中添加注釋。

      • 類型:?string | { amd?: string, commonjs?: string, commonjs2?: string, root?: string }?

      為每個 ?umd? 類型插入相同的注釋,將 ?auxiliaryComment? 設(shè)置為 string。

      module.exports = {
        // …
        mode: 'development',
        output: {
          library: {
            name: 'MyLibrary',
            type: 'umd',
            auxiliaryComment: 'Test Comment',
          },
        },
      };

      這將產(chǎn)生以下結(jié)果:

      (function webpackUniversalModuleDefinition(root, factory) {
        //Test Comment
        if (typeof exports === 'object' && typeof module === 'object')
          module.exports = factory();
        //Test Comment
        else if (typeof define === 'function' && define.amd) define([], factory);
        //Test Comment
        else if (typeof exports === 'object') exports['MyLibrary'] = factory();
        //Test Comment
        else root['MyLibrary'] = factory();
      })(self, function () {
        return _entry_return_;
      });

      對于細(xì)粒度控制,可以傳遞一個對象:

      module.exports = {
        // …
        mode: 'development',
        output: {
          library: {
            name: 'MyLibrary',
            type: 'umd',
            auxiliaryComment: {
              root: 'Root Comment',
              commonjs: 'CommonJS Comment',
              commonjs2: 'CommonJS2 Comment',
              amd: 'AMD Comment',
            },
          },
        },
      };

      output.library.umdNamedDefine

      ?boolean?

      當(dāng)使用 ?output.library.type: "umd"? 時,將 ?output.library.umdNamedDefine? 設(shè)置為 ?true? 將會把 AMD 模塊命名為 UMD 構(gòu)建。否則使用匿名 ?define?。

      module.exports = {
        //...
        output: {
          library: {
            name: 'MyLibrary',
            type: 'umd',
            umdNamedDefine: true,
          },
        },
      };

      AMD module 將會是這樣:

      define('MyLibrary', [], factory);

      output.libraryExport

      ?string [string]?

      通過配置 ?libraryTarget? 決定暴露哪些模塊。默認(rèn)情況下為 ?undefined?,如果你將 ?libraryTarget? 設(shè)置為空字符串,則與默認(rèn)情況具有相同的行為。例如,如果設(shè)置為 ?''?,將導(dǎo)出整個(命名空間)對象。下述 demo 演示了當(dāng)設(shè)置 ?libraryTarget: 'var'? 時的效果。

      支持以下配置:

      ?libraryExport: 'default'? - 入口的默認(rèn)導(dǎo)出將分配給 library target:

      // if your entry has a default export of `MyDefaultModule`
      var MyDefaultModule = _entry_return_.default;

      ?libraryExport: 'MyModule'? - 這個 確定的模塊 將被分配給 library target:

      var MyModule = _entry_return_.MyModule;

      ?libraryExport: ['MyModule', 'MySubModule']? - 數(shù)組將被解析為要分配給 library target 的 模塊路徑

      var MySubModule = _entry_return_.MyModule.MySubModule;

      使用上述指定的 libraryExport 配置時,library 的結(jié)果可以這樣使用:

      MyDefaultModule.doSomething();
      MyModule.doSomething();
      MySubModule.doSomething();

      output.libraryTarget

      ?string = 'var'?

      配置如何暴露 library??梢允褂孟旅娴倪x項中的任意一個。注意,此選項與分配給 ?output.library? 的值一同使用。對于下面的所有示例,都假定將 ?output.library? 的值配置為 ?MyLibrary?。

      暴露為一個變量

      這些選項將入口起點的返回值(例如,入口起點的任何導(dǎo)出值),在 bundle 包所引入的位置,賦值給 ?output.library? 提供的變量名。

      libraryTarget: 'var' $#libraryTarget-var$

      當(dāng) library 加載完成,入口起點的返回值將分配給一個變量:

      var MyLibrary = _entry_return_;
      
      // 在一個單獨的 script...
      MyLibrary.doSomething();

      libraryTarget: 'assign' $#libraryTarget-assign$

      這將產(chǎn)生一個隱含的全局變量,可能會潛在地重新分配到全局中已存在的值(謹(jǐn)慎使用):

      MyLibrary = _entry_return_;

      注意,如果 ?MyLibrary? 在作用域中未在前面代碼進(jìn)行定義,則你的 library 將被設(shè)置在全局作用域內(nèi)。

      libraryTarget: 'assign-properties' $#libraryTarget-assign-properties$

      ?5.16.0+?

      如果目標(biāo)對象存在,則將返回值 copy 到目標(biāo)對象,否則先創(chuàng)建目標(biāo)對象:

      // 如果不存在的話就創(chuàng)建目標(biāo)對象
      MyLibrary = typeof MyLibrary === 'undefined' ? {} : MyLibrary;
      // 然后復(fù)制返回值到 MyLibrary
      // 與 Object.assign 行為類似
      
      // 例如,你在入口導(dǎo)出了一個 `hello` 函數(shù)
      export function hello(name) {
        console.log(`Hello ${name}`);
      }
      
      // 在另一個腳本中運行 MyLibrary
      // 你可以像這樣運行 `hello` 函數(shù)
      MyLibrary.hello('World');

      通過在對象上賦值暴露

      這些選項將入口起點的返回值(例如,入口起點的任何導(dǎo)出值)賦值給一個特定對象的屬性(此名稱由 ?output.library? 定義)下。

      如果 ?output.library? 未賦值為一個非空字符串,則默認(rèn)行為是,將入口起點返回的所有屬性都賦值給一個對象(此對象由 ?output.libraryTarget? 特定),通過如下代碼片段:

      (function (e, a) {
        for (var i in a) {
          e[i] = a[i];
        }
      })(output.libraryTarget, _entry_return_);

      libraryTarget: 'this'

      入口起點的返回值將分配給 this 的一個屬性(此名稱由 output.library 定義)下,this 的含義取決于你:

      this['MyLibrary'] = _entry_return_;
      
      // 在一個單獨的 script...
      this.MyLibrary.doSomething();
      MyLibrary.doSomething(); // 如果 this 是 window

      libraryTarget: 'window'

      入口起點的返回值將使用 output.library 中定義的值,分配給 window 對象的這個屬性下。

      window['MyLibrary'] = _entry_return_;
      
      window.MyLibrary.doSomething();

      libraryTarget: 'global'

      入口起點的返回值將使用 output.library 中定義的值,分配給 global 對象的這個屬性下。

      global['MyLibrary'] = _entry_return_;
      
      global.MyLibrary.doSomething();

      libraryTarget: 'commonjs'

      入口起點的返回值將使用 ?output.library? 中定義的值,分配給 exports 對象。這個名稱也意味著,模塊用于 CommonJS 環(huán)境:

      exports['MyLibrary'] = _entry_return_;
      
      require('MyLibrary').doSomething();

      模塊定義系統(tǒng)

      這些選項將使得 bundle 帶有更完整的模塊頭,以確保與各種模塊系統(tǒng)的兼容性。根據(jù) ?output.libraryTarget? 選項不同,?output.library? 選項將具有不同的含義。

      libraryTarget: 'module'

      輸出 ES 模塊。請確保事先啟用 experiments.outputModule。

      需要注意的是,該功能還未完全支持,請在此處跟進(jìn)進(jìn)度。

      libraryTarget: 'commonjs2'

      入口起點的返回值將分配給 module.exports 對象。這個名稱也意味著模塊用于 CommonJS 環(huán)境:

      module.exports = _entry_return_;
      
      require('MyLibrary').doSomething();

      注意,?output.library? 不能與 ?output.libraryTarget? 一起使用,具體原因請參照此 issue。

      libraryTarget: 'amd'

      將你的 library 暴露為 AMD 模塊。

      AMD 模塊要求入口 chunk(例如使用 ?<script>? 標(biāo)簽加載的第一個腳本)通過特定的屬性定義,例如 ?define? 和 ?require?,它們通常由 RequireJS 或任何兼容的模塊加載器提供(例如 almond)。否則,直接加載生成的 AMD bundle 將導(dǎo)致報錯,如 ?define is not defined?。

      配置如下:

      module.exports = {
        //...
        output: {
          library: 'MyLibrary',
          libraryTarget: 'amd',
        },
      };

      生成的 output 名稱將被定義為 "MyLibrary":

      define('MyLibrary', [], function () {
        return _entry_return_;
      });

      可以在 script 標(biāo)簽中,將 bundle 作為一個模塊整體引入,并且可以像這樣調(diào)用 bundle:

      require(['MyLibrary'], function (MyLibrary) {
        // Do something with the library...
      });

      如果 ?output.library? 未定義,將會生成以下內(nèi)容。

      define([], function () {
        return _entry_return_;
      });

      如果直接加載 ?<script>? 標(biāo)簽,此 bundle 無法按預(yù)期運行,或者根本無法正常運行(在 almond loader 中)。只能通過文件的實際路徑,在 RequireJS 兼容的異步模塊加載器中運行,因此在這種情況下,如果這些設(shè)置直接暴露在服務(wù)器上,那么 ?output.path? 和 ?output.filename? 對于這個特定的設(shè)置可能變得很重要。

      libraryTarget: 'amd-require'

      這將使用立即執(zhí)行的 AMD ?require(dependencies, factory)? 包裝器包裝您的輸出。

      ?'amd-require'? 目標(biāo)(target)允許使用 AMD 依賴項,而無需單獨的后續(xù)調(diào)用。與 ?'amd'? 目標(biāo)(target)一樣, 這取決于在加載 webpack 輸出的環(huán)境中適當(dāng)可用的 ?require function?。

      對于此 target,庫名稱將被忽略。

      libraryTarget: 'umd'

      將你的 library 暴露為所有的模塊定義下都可運行的方式。它將在 CommonJS, AMD 環(huán)境下運行,或?qū)⒛K導(dǎo)出到 global 下的變量。了解更多請查看 UMD 倉庫。

      在這個例子中,你需要 library 屬性來命名你的模塊:

      module.exports = {
        //...
        output: {
          library: 'MyLibrary',
          libraryTarget: 'umd',
        },
      };

      最終的輸出結(jié)果為:

      (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();
      })(typeof self !== 'undefined' ? self : this, function () {
        return _entry_return_;
      });

      注意,省略 ?library? 會導(dǎo)致將入口起點返回的所有屬性,直接賦值給 root 對象,就像對象分配章節(jié)。例如:

      module.exports = {
        //...
        output: {
          libraryTarget: 'umd',
        },
      };

      輸出結(jié)果如下:

      (function webpackUniversalModuleDefinition(root, factory) {
        if (typeof exports === 'object' && typeof module === 'object')
          module.exports = factory();
        else if (typeof define === 'function' && define.amd) define([], factory);
        else {
          var a = factory();
          for (var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
        }
      })(typeof self !== 'undefined' ? self : this, function () {
        return _entry_return_;
      });

      從 webpack 3.1.0 開始,你可以將 library 指定為一個對象,用于給每個 target 起不同的名稱:

      module.exports = {
        //...
        output: {
          library: {
            root: 'MyLibrary',
            amd: 'my-library',
            commonjs: 'my-common-library',
          },
          libraryTarget: 'umd',
        },
      };

      libraryTarget: 'system'

      這將暴露你的 library 作為一個由 System.register 的模塊。此特性首次發(fā)布于 webpack 4.30.0。

      當(dāng) webpack bundle 被執(zhí)行時,系統(tǒng)模塊依賴全局的變量 ?System?。編譯為 ?System.register? 形式后,你可以使用 ?System.import('/bundle.js')? 而無需額外配置,并會將你的 webpack bundle 包加載到系統(tǒng)模塊注冊表中。

      module.exports = {
        //...
        output: {
          libraryTarget: 'system',
        },
      };

      輸出:

      System.register([], function (_export) {
        return {
          setters: [],
          execute: function () {
            // ...
          },
        };
      });

      除了將 ?output.libraryTarget? 設(shè)置為 ?system? 之外,還可將 ?output.library? 添加到配置中,輸出 bundle 的 library 名將作為 ?System.register? 的參數(shù):

      System.register('my-library', [], function (_export) {
        return {
          setters: [],
          execute: function () {
            // ...
          },
        };
      });

      你可以通過 ?__system_context__? 訪問 SystemJS context

      // 記錄當(dāng)前系統(tǒng)模塊的 URL
      console.log(__system_context__.meta.url);
      
      // 導(dǎo)入一個系統(tǒng)模塊,通過將當(dāng)前的系統(tǒng)模塊的 url 作為 parentUrl
      __system_context__.import('./other-file.js').then((m) => {
        console.log(m);
      });

      其他 Targets

      libraryTarget: 'jsonp'

      這將把入口起點的返回值,包裹到一個 jsonp 包裝容器中

      MyLibrary(_entry_return_);

      你的 library 的依賴將由 ?externals? 配置定義。

      output.module

      ?boolean = false?

      以模塊類型輸出 JavaScript 文件。由于此功能還處于實驗階段,默認(rèn)禁用。

      當(dāng)啟用時,webpack 會在內(nèi)部將 ?output.iife? 設(shè)置為 ?false?,將 ?output.scriptType? 為 ?'module'?,并將 ?terserOptions.module? 設(shè)置為 ?true?

      如果你需要使用 webpack 構(gòu)建一個庫以供別人使用,當(dāng) ?output.module? 為 ?true? 時,一定要將 ?output.libraryTarget? 設(shè)置為 ?'module'?。

      module.exports = {
        //...
        experiments: {
          outputModule: true,
        },
        output: {
          module: true,
        },
      };

      output.path

      ?string = path.join(process.cwd(), 'dist')?

      output 目錄對應(yīng)一個絕對路徑

      webpack.config.js

      const path = require('path');
      
      module.exports = {
        //...
        output: {
          path: path.resolve(__dirname, 'dist/assets'),
        },
      };

      注意,?[fullhash]? 在參數(shù)中被替換為編譯過程(compilation)的 hash。詳細(xì)信息請查看指南 - 緩存。

      output.pathinfo

      ?boolean=true? ?string: 'verbose'?

      告知 webpack 在 bundle 中引入「所包含模塊信息」的相關(guān)注釋。此選項在 ?development? 模式時的默認(rèn)值為 ?true?,而在 production 模式時的默認(rèn)值為 ?false?。當(dāng)值為 ?'verbose'? 時,會顯示更多信息,如 export,運行時依賴以及 bailouts。

      webpack.config.js

      module.exports = {
        //...
        output: {
          pathinfo: true,
        },
      };

      output.publicPath

      • Type:??function??string?

      targets 設(shè)置為 ?web? 與 ?web-worker? 時 ?output.publicPath? 默認(rèn)為 ?'auto'?,查看該指南獲取其用例

        對于按需加載(on-demand-load)或加載外部資源(external resources)(如圖片、文件等)來說,output.publicPath 是很重要的選項。如果指定了一個錯誤的值,則在加載這些資源時會收到 404 錯誤。

        此選項指定在瀏覽器中所引用的「此輸出目錄對應(yīng)的公開 URL」。相對 URL(relative URL) 會被相對于 HTML 頁面(或 ?<base>? 標(biāo)簽)解析。相對于服務(wù)的 URL(Server-relative URL),相對于協(xié)議的 URL(protocol-relative URL) 或絕對 URL(absolute URL) 也可是可能用到的,或者有時必須用到,例如:當(dāng)將資源托管到 CDN 時。

        該選項的值是以 runtime(運行時) 或 loader(載入時) 所創(chuàng)建的每個 URL 的前綴。因此,在多數(shù)情況下,此選項的值都會以 / 結(jié)束。

        規(guī)則如下:?output.path? 中的 URL 以 HTML 頁面為基準(zhǔn)。

        webpack.config.js

        const path = require('path');
        
        module.exports = {
          //...
          output: {
            path: path.resolve(__dirname, 'public/assets'),
            publicPath: 'https://cdn.example.com/assets/',
          },
        };

        對于這個配置:

        webpack.config.js

        module.exports = {
          //...
          output: {
            publicPath: '/assets/',
            chunkFilename: '[id].chunk.js',
          },
        };

        對于一個 chunk 請求,看起來像這樣 ?/assets/4.chunk.js?。

        對于一個輸出 HTML 的 loader 可能會像這樣輸出:

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

        或者在加載 CSS 的一個圖片時:

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

        webpack-dev-server 也會默認(rèn)從 ?publicPath? 為基準(zhǔn),使用它來決定在哪個目錄下啟用服務(wù),來訪問 webpack 輸出的文件。

        注意,參數(shù)中的 ?[fullhash]? 將會被替換為編譯過程(compilation) 的 hash。詳細(xì)信息請查看指南 - 緩存。

        示例:

        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 協(xié)議)
            publicPath: '//cdn.example.com/assets/', // CDN(協(xié)議相同)
            publicPath: '/assets/', // 相對于服務(wù)(server-relative)
            publicPath: 'assets/', // 相對于 HTML 頁面
            publicPath: '../assets/', // 相對于 HTML 頁面
            publicPath: '', // 相對于 HTML 頁面(目錄相同)
          },
        };

        在編譯時(compile time)無法知道輸出文件的 ?publicPath? 的情況下,可以留空,然后在入口文件(entry file)處使用自由變量(free variable) ?__webpack_public_path__?,以便在運行時(runtime)進(jìn)行動態(tài)設(shè)置。

        __webpack_public_path__ = myRuntimePublicPath;
        
        // 應(yīng)用程序入口的其他部分

        有關(guān) ?__webpack_public_path__? 的更多信息,請查看此討論

        output.scriptType

        ?string: 'module' | 'text/javascript' boolean = false?

        這個配置項允許使用自定義 script 類型加載異步 chunk,例如 ?<script type="module" ...>?。

        module.exports = {
          //...
          output: {
            scriptType: 'module',
          },
        };

        output.sourceMapFilename

        ?string = '[file].map[query]'?

        僅在 ?devtool? 設(shè)置為 ?'source-map'? 時有效,此選項會向硬盤寫入一個輸出文件。

        可以使用 ?#output-filename? 中的 ?[name]?, ?[id]?, ?[hash] ?和 ?[chunkhash]? 替換符號。除此之外,還可以使用 ?Template strings? 在 Filename-level 下替換。

        output.sourcePrefix

        ?string = ''?

        修改輸出 bundle 中每行的前綴。

        webpack.config.js

        module.exports = {
          //...
          output: {
            sourcePrefix: '\t',
          },
        };

        output.strictModuleErrorHandling

        按照 ES Module 規(guī)范處理 module 加載時的錯誤,會有性能損失。

        • 類型:?boolean?
        • 可用版本:5.25.0+
        module.exports = {
          //...
          output: {
            strictModuleErrorHandling: true,
          },
        };

        output.strictModuleExceptionHandling

        ?boolean = false?

        如果一個模塊是在 ?require? 時拋出異常,告訴 webpack 從模塊實例緩存?(require.cache)?中刪除這個模塊。

        出于性能原因,默認(rèn)為 ?false?。

        當(dāng)設(shè)置為 ?false? 時,該模塊不會從緩存中刪除,這將造成僅在第一次 ?require? 調(diào)用時拋出異常(會導(dǎo)致與 node.js 不兼容)。

        例如,設(shè)想一下 ?module.js?:

        throw new Error('error');

        將 ?strictModuleExceptionHandling? 設(shè)置為 ?false?,只有第一個 ?require? 拋出異常:

        // with strictModuleExceptionHandling = false
        require('module'); // <- 拋出
        require('module'); // <- 不拋出

        相反,將 ?strictModuleExceptionHandling? 設(shè)置為 ?true?,這個模塊所有的 ?require? 都拋出異常:

        // with strictModuleExceptionHandling = true
        require('module'); // <- 拋出
        require('module'); // <- 仍然拋出

        output.trustedTypes

        ?boolean = false? ?string? ?object?

        ?5.37.0+?

        控制 Trusted Types 兼容性。啟用時,webpack 將檢測 Trusted Types 支持,如果支持,則使用 Trusted Types 策略創(chuàng)建它動態(tài)加載的腳本 url。當(dāng)應(yīng)用程序在 ?require-trusted-types-for? 內(nèi)容安全策略指令下運行時使用。

        默認(rèn)為 ?false?(不兼容,腳本 URL 為字符串)。

        • 設(shè)置為 true 時,webpack 將會使用 ?output.uniqueName? 作為 Trusted Types 策略名稱。
        • 設(shè)置為非空字符串時,它的值將被用作策略名稱。
        • 設(shè)置為一個對象時,策略名稱取自對象 ?policyName? 屬性。

        webpack.config.js

        module.exports = {
          //...
          output: {
            //...
            trustedTypes: {
              policyName: 'my-application#webpack',
            },
          },
        };

        output.umdNamedDefine

        ?boolean?

        當(dāng)使用 ?libraryTarget: "umd"? 時,設(shè)置 ?output.umdNamedDefine? 為 ?true? 將命名由 UMD 構(gòu)建的 AMD 模塊。否則將使用一個匿名的 ?define?。

        module.exports = {
          //...
          output: {
            umdNamedDefine: true,
          },
        };

        output.uniqueName

        ?string?

        在全局環(huán)境下為防止多個 webpack 運行時 沖突所使用的唯一名稱。默認(rèn)使用 ?output.library? 名稱或者上下文中的 ?package.json? 的 包名稱(package name), 如果兩者都不存在,值為 ?''?。

        ?output.uniqueName? 將用于生成唯一全局變量:

        • ?output.chunkLoadingGlobal?

        webpack.config.js

        module.exports = {
          // ...
          output: {
            uniqueName: 'my-package-xyz',
          },
        };

        output.wasmLoading

        ?boolean = false? ?string?

        此選項用于設(shè)置加載 WebAssembly 模塊的方式。默認(rèn)可使用的方式有 ?'fetch'?(web/WebWorker),?'async-node'?(Node.js),其他額外方式可由插件提供。

        其默認(rèn)值會根據(jù) ?target? 的變化而變化:

        • 如果 ?target? 設(shè)置為 ?'web'?,?'webworker'?,?'electron-renderer'? 或 ?'node-webkit'? 其中之一,其默認(rèn)值為 ?'fetch'?。
        • 如果 ?target? 設(shè)置為 ?'node'?,?'async-node'?,?'electron-main'? 或 ?'electron-preload'?,其默認(rèn)值為 ?'async-node'?。
        module.exports = {
          //...
          output: {
            wasmLoading: 'fetch',
          },
        };

        output.workerChunkLoading

        ?string: 'require' | 'import-scripts' | 'async-node' | 'import' | 'universal' boolean: false?

        新選項 ?workerChunkLoading? 用于控制 workder 的 chunk 加載。

        webpack.config.js

        module.exports = {
          //...
          output: {
            workerChunkLoading: false,
          },
        };


        以上內(nèi)容是否對您有幫助:
        在線筆記
        App下載
        App下載

        掃描二維碼

        下載編程獅App

        公眾號
        微信公眾號

        編程獅公眾號