Webpack Output(輸出)

2023-05-15 17:25 更新

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

output.assetModuleFilename

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

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

對(duì)從數(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? 一起使用時(shí),此選項(xiàng)允許用戶(hù)向?qū)С鋈萜?export wrapper)中插入注釋。要為 libraryTarget 每種類(lèi)型都插入相同的注釋?zhuān)瑢?nbsp;?auxiliaryComment? 設(shè)置為一個(gè)字符串:

webpack.config.js

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

將會(huì)生成如下:

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__) {
  // ...
});

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

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)識(shí)。

output.chunkFilename

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

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

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

默認(rèn)使用 ?[id].js? 或從 ?output.filename? 中推斷出的值(?[name]? 會(huì)被預(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 請(qǐng)求到期之前的毫秒數(shù),默認(rèn)為 120000。從 webpack 2.6.0 開(kāi)始支持此選項(xiàng)。

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 在寫(xiě)入到輸出文件系統(tǒng)時(shí)檢查輸出的文件是否已經(jīng)存在并且擁有相同內(nèi)容。

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

output.crossOriginLoading

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

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

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

output.devtoolFallbackModuleFilenameTemplate

?string? ?function (info)?

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

output.devtoolModuleFilenameTemplate

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

此選項(xiàng)僅在 「?devtool? 使用了需要模塊名稱(chēng)的選項(xiàng)」時(shí)使用。

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

webpack.config.js

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

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

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

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

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

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

output.devtoolNamespace

?string?

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

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

output.enabledChunkLoadingTypes

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

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

webpack.config.js

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

output.enabledLibraryTypes

?[string]?

入口點(diǎn)可用的 library 類(lèi)型列表.

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

output.enabledWasmLoadingTypes

?[string]?

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

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

## `output.environment` $#outputenvironment$

告訴 webpack 在生成的運(yùn)行時(shí)代碼中可以使用哪個(gè)版本的 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

此選項(xiàng)決定了每個(gè)輸出 bundle 的名稱(chēng)。這些 bundle 將寫(xiě)入到 ?output.path? 選項(xiàng)指定的目錄下。

對(duì)于單個(gè)?入口?起點(diǎn),filename 會(huì)是一個(gè)靜態(tài)名稱(chēng)。

webpack.config.js

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

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

使用入口名稱(chēng):

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é)合多個(gè)替換組合使用:

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

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

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

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

Template strings

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

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

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

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

模板 描述
[id] 此 chunk 的 ID
[name] 如果設(shè)置,則為此 chunk 的名稱(chēng),否則使用 chunk 的 ID
[chunkhash] 此 chunk 的 hash 值,包含該 chunk 的所有元素
[contenthash] 此 chunk 的 hash 值,只包括該內(nèi)容類(lè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(包含擴(kuò)展名),不含 path
[filebase] 同上,但已棄用
[path] 只有 path,不含 filename
[name] 只有 filename,不含擴(kuò)展名或 path
[ext] 帶前綴 . 的擴(kuò)展名(對(duì) ?output.filename? 不可用)

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

模塊 描述
[url] URL

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

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

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

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

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

入口點(diǎn)的返回值將會(huì)使用 ?output.library.name? 賦值給全局對(duì)象。依賴(lài)于 ?target? 配置項(xiàng),全局對(duì)象將會(huì)發(fā)生對(duì)應(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 時(shí)使用的編碼方式。支持 Node.js ?hash.digest? 的所有編碼。對(duì)文件名使用 ?'base64'?,可能會(huì)出現(xiàn)問(wèn)題,因?yàn)?base64 字母表中具有 / 這個(gè)字符(character)。同樣的,'latin1' 規(guī)定可以含有任何字符(character)。

output.hashDigestLength

?number = 20?

散列摘要的前綴長(zhǎng)度。

output.hashFunction

?string = 'md4'? ?function?

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

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

確保 hash 函數(shù)有可訪(fǎng)問(wèn)的 ?update? 和 ?digest? 方法。

output.hashSalt

一個(gè)可選的加鹽值,通過(guò) Node.JS ?hash.update? 來(lái)更新哈希。

output.hotUpdateChunkFilename

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

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

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

webpack.config.js

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

output.hotUpdateGlobal

?string?

只在 ?target? 設(shè)置為 ?'web'? 時(shí)使用,用于加載熱更新(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ù)的名稱(chēng). 可用于 polyfilling, 例如 通過(guò) ?dynamic-import-polyfill?.

webpack.config.js

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

output.library

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

  • 類(lèi)型:?string | string[] | object?

一起來(lái)看一個(gè)簡(jiǎn)單的示例。

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

此時(shí),變量 ?MyLibrary? 將與你的入口文件所導(dǎo)出的文件進(jìn)行綁定,下面是如何使用 webpack 構(gòu)建的庫(kù)的實(shí)現(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è)置了一個(gè)入口文件,然而 webpack 可以接受 多個(gè)入口,例如一個(gè) ?array? 或者一個(gè) ?object?。

  1. 如果你將 entry 設(shè)置為一個(gè) array,那么只有數(shù)組中的最后一個(gè)會(huì)被暴露。
    module.exports = {
      // …
      entry: ['./src/a.js', './src/b.js'], // 只有在 b.js 中導(dǎo)出的內(nèi)容才會(huì)被暴露
      output: {
        library: 'MyLibrary',
      },
    };
  2. 如果你將 entry 設(shè)置為一個(gè) object,所以入口都可以通過(guò) library 的 array 語(yǔ)法暴露:
    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ù),這就是如何使用這些庫(kù)的方法:

<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)容。

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

module.exports = {
  // …
  entry: {
    main: {
      import: './src/index.js',
      library: {
        // `output.library` 下的所有配置項(xiàng)可以在這里使用
        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',
        },
      },
    };

    指定庫(kù)的名稱(chēng)。

    • 類(lèi)型:
      string | string[] | {amd?: string, commonjs?: string, root?: string | string[]}

    output.library.type

    配置將庫(kù)暴露的方式。

    • 類(lèi)型:?string?

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

      對(duì)于接下來(lái)的示例,我們將會(huì)使用 ?_entry_return_? 表示被入口點(diǎn)返回的值。

      Expose a Variable

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

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

      讓你的庫(kù)加載之后,入口起點(diǎn)的返回值 將會(huì)被賦值給一個(gè)變量:

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

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

      MyLibrary = _entry_return_;

      請(qǐng)注意,如果 ?MyLibrary? 沒(méi)有在你的庫(kù)之前定義,那么它將會(huì)被設(shè)置在全局作用域。

      type: 'assign-properties'

      ?5.16.0+?

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

      與 ?type: 'assign'? 相似但是更安全,因?yàn)槿绻?nbsp;?MyLibrary? 已經(jīng)存在的話(huà),它將被重用:

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

      Expose Via Object Assignment

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

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

      入口起點(diǎn)的返回值 將會(huì)被賦值給 this 對(duì)象下的 output.library.name 屬性。this 的含義取決于你:

      this['MyLibrary'] = _entry_return_;
      
      // 在一個(gè)單獨(dú)的腳本中
      this.MyLibrary.doSomething();
      MyLibrary.doSomething(); // 如果 `this` 為 window 對(duì)象
      type: 'window'
      module.exports = {
        // …
        output: {
          library: {
            name: 'MyLibrary',
            type: 'window',
          },
        },
      };

      入口起點(diǎn)的返回值 將會(huì)被賦值給 window 對(duì)象下的 output.library.name。

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

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

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

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

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

      Module Definition Systems

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

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

      輸出 ES 模塊。

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

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

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

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

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

      type: 'commonjs-static'

      ?5.66.0+?

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

      單個(gè)導(dǎo)出將被設(shè)置為 ?module.exports? 中的屬性。名稱(chēng)中的 "static" 是指輸出是靜態(tài)可分析的,因此具名導(dǎo)出可以通過(guò) 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'

      可以將你的庫(kù)暴露為 AMD 模塊。

      AMD module 要求入口 chunk(例如,第一個(gè)通過(guò) ?<script>? 標(biāo)簽加載的腳本)使用特定的屬性來(lái)定義, 例如 ?define? 與 ?require?,這通常由 RequireJS 或任何兼容的 loader(如 almond)提供。否則,直接加載產(chǎn)生的 AMD bundle 將導(dǎo)致一個(gè)錯(cuò)誤,如 ?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...
      });

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

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

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

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

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

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

      使用該類(lèi)型的話(huà),不能使用庫(kù)的名稱(chēng)。

      type: 'umd'

      這將在所有模塊定義下暴露你的庫(kù), 允許它與 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_;
      });

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

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

      輸出將會(huì)是:

      (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 指定一個(gè)對(duì)象,每個(gè)目標(biāo)的名稱(chēng)不同:

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

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

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

      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 將以庫(kù)名作為 ?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',
          },
        },
      };

      這將把入口起點(diǎn)的返回值包裝到 jsonp 包裝器中。

      MyLibrary(_entry_return_);

      你的庫(kù)的依賴(lài)將由 ?externals? 配置定義。

      output.library.export

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

      • 類(lèi)型:?string | string[]?

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

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

      入口起點(diǎn)的默認(rèn)導(dǎo)出將會(huì)被賦值為庫(kù)名稱(chēng):

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

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

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

      這里就是庫(kù)代碼:

      var MyLibrary = _entry_return_.default.subModule;

      output.library.auxiliaryComment

      在 UMD 包裝器中添加注釋。

      • 類(lèi)型:?string | { amd?: string, commonjs?: string, commonjs2?: string, root?: string }?

      為每個(gè) ?umd? 類(lèi)型插入相同的注釋?zhuān)瑢?nbsp;?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_;
      });

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

      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"? 時(shí),將 ?output.library.umdNamedDefine? 設(shè)置為 ?true? 將會(huì)把 AMD 模塊命名為 UMD 構(gòu)建。否則使用匿名 ?define?。

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

      AMD module 將會(huì)是這樣:

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

      output.libraryExport

      ?string [string]?

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

      支持以下配置:

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

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

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

      var MyModule = _entry_return_.MyModule;

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

      var MySubModule = _entry_return_.MyModule.MySubModule;

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

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

      output.libraryTarget

      ?string = 'var'?

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

      暴露為一個(gè)變量

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

      libraryTarget: 'var' $#libraryTarget-var$

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

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

      libraryTarget: 'assign' $#libraryTarget-assign$

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

      MyLibrary = _entry_return_;

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

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

      ?5.16.0+?

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

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

      通過(guò)在對(duì)象上賦值暴露

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

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

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

      libraryTarget: 'this'

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

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

      libraryTarget: 'window'

      入口起點(diǎn)的返回值將使用 output.library 中定義的值,分配給 window 對(duì)象的這個(gè)屬性下。

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

      libraryTarget: 'global'

      入口起點(diǎn)的返回值將使用 output.library 中定義的值,分配給 global 對(duì)象的這個(gè)屬性下。

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

      libraryTarget: 'commonjs'

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

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

      模塊定義系統(tǒng)

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

      libraryTarget: 'module'

      輸出 ES 模塊。請(qǐng)確保事先啟用 experiments.outputModule。

      需要注意的是,該功能還未完全支持,請(qǐng)?jiān)?a href="http://www.o2fo.com/targetlink?url=https://github.com/webpack/webpack/issues/2933#issuecomment-774253975">此處跟進(jìn)進(jìn)度。

      libraryTarget: 'commonjs2'

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

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

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

      libraryTarget: 'amd'

      將你的 library 暴露為 AMD 模塊。

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

      配置如下:

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

      生成的 output 名稱(chēng)將被定義為 "MyLibrary":

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

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

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

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

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

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

      libraryTarget: 'amd-require'

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

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

      對(duì)于此 target,庫(kù)名稱(chēng)將被忽略。

      libraryTarget: 'umd'

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

      在這個(gè)例子中,你需要 library 屬性來(lái)命名你的模塊:

      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? 會(huì)導(dǎo)致將入口起點(diǎn)返回的所有屬性,直接賦值給 root 對(duì)象,就像對(duì)象分配章節(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 開(kāi)始,你可以將 library 指定為一個(gè)對(duì)象,用于給每個(gè) target 起不同的名稱(chēng):

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

      libraryTarget: 'system'

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

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

      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 () {
            // ...
          },
        };
      });

      你可以通過(guò) ?__system_context__? 訪(fǎng)問(wèn) SystemJS context

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

      其他 Targets

      libraryTarget: 'jsonp'

      這將把入口起點(diǎn)的返回值,包裹到一個(gè) jsonp 包裝容器中

      MyLibrary(_entry_return_);

      你的 library 的依賴(lài)將由 ?externals? 配置定義。

      output.module

      ?boolean = false?

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

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

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

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

      output.path

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

      output 目錄對(duì)應(yīng)一個(gè)絕對(duì)路徑。

      webpack.config.js

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

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

      output.pathinfo

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

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

      webpack.config.js

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

      output.publicPath

      • Type:??function??string?

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

        對(duì)于按需加載(on-demand-load)或加載外部資源(external resources)(如圖片、文件等)來(lái)說(shuō),output.publicPath 是很重要的選項(xiàng)。如果指定了一個(gè)錯(cuò)誤的值,則在加載這些資源時(shí)會(huì)收到 404 錯(cuò)誤。

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

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

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

        webpack.config.js

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

        對(duì)于這個(gè)配置:

        webpack.config.js

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

        對(duì)于一個(gè) chunk 請(qǐng)求,看起來(lái)像這樣 ?/assets/4.chunk.js?。

        對(duì)于一個(gè)輸出 HTML 的 loader 可能會(huì)像這樣輸出:

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

        或者在加載 CSS 的一個(gè)圖片時(shí):

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

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

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

        示例:

        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/', // 相對(duì)于服務(wù)(server-relative)
            publicPath: 'assets/', // 相對(duì)于 HTML 頁(yè)面
            publicPath: '../assets/', // 相對(duì)于 HTML 頁(yè)面
            publicPath: '', // 相對(duì)于 HTML 頁(yè)面(目錄相同)
          },
        };

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

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

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

        output.scriptType

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

        這個(gè)配置項(xiàng)允許使用自定義 script 類(lèi)型加載異步 chunk,例如 ?<script type="module" ...>?。

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

        output.sourceMapFilename

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

        僅在 ?devtool? 設(shè)置為 ?'source-map'? 時(shí)有效,此選項(xiàng)會(huì)向硬盤(pán)寫(xiě)入一個(gè)輸出文件。

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

        output.sourcePrefix

        ?string = ''?

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

        webpack.config.js

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

        output.strictModuleErrorHandling

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

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

        output.strictModuleExceptionHandling

        ?boolean = false?

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

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

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

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

        throw new Error('error');

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

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

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

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

        output.trustedTypes

        ?boolean = false? ?string? ?object?

        ?5.37.0+?

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

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

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

        webpack.config.js

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

        output.umdNamedDefine

        ?boolean?

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

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

        output.uniqueName

        ?string?

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

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

        • ?output.chunkLoadingGlobal?

        webpack.config.js

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

        output.wasmLoading

        ?boolean = false? ?string?

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

        其默認(rèn)值會(huì)根據(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?

        新選項(xiàng) ?workerChunkLoading? 用于控制 workder 的 chunk 加載。

        webpack.config.js

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


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

        掃描二維碼

        下載編程獅App

        公眾號(hào)
        微信公眾號(hào)

        編程獅公眾號(hào)