此 webpack 插件有两个用途:

  • 将 WordPress 站点上作为共享脚本或模块可用的依赖项外部化。
  • 为每个入口点添加一个资产文件,该文件声明一个包含入口点的 WordPress 脚本或模块依赖项列表的对象。资产文件还包含针对当前源代码计算出的当前版本。

这使得由 webpack 生成的 JavaScript 包能够利用 WordPress 样式依赖项共享功能,而无需进行容易出错的手动维护依赖项列表的过程。

此插件的第 5 版增加了对模块打包的支持。应使用 Webpack 的 output.module 选项
来选择加入此行为。此插件将根据
output.module 选项调整其行为,生成适用于 WordPress Module API 的资产文件。

有关 webpack 概念的更多信息,请参阅 webpack 网站。

安装

安装模块

npm install @wordpress/dependency-extraction-webpack-plugin --save-dev

注意:此软件包需要具有长期支持状态的 Node.js 版本(查看 Active LTS 或 Maintenance LTS 版本)。它还需要 webpack 5.0.0 或更高版本。它与旧版本不兼容。

用法

Webpack

像使用其他 webpack 插件一样使用此插件:

// webpack.config.js
const DependencyExtractionWebpackPlugin = require( '@wordpress/dependency-extraction-webpack-plugin' );

module.exports = {
    // …snip
    plugins: [ new DependencyExtractionWebpackPlugin() ],
};

注意:不支持插件的多个实例,这可能会产生意外结果。如果您计划使用自己的 DependencyExtractionWebpackPlugin 从 @wordpress/scripts 扩展 webpack 配置,请务必删除插件的默认实例:

const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
const webpackConfig = {
    ...defaultConfig,
    plugins: [
        ...defaultConfig.plugins.filter(
            ( plugin ) =>
                plugin.constructor.name !== 'DependencyExtractionWebpackPlugin'
        ),
        new DependencyExtractionWebpackPlugin( {
            injectPolyfill: true,
            requestToExternal( request ) {
                /* My externals */
            },
        } ),
    ],
};

与脚本的行为

webpack 包中的每个入口点都将包含一个资产文件,其中声明了应该排队的 WordPress 脚本依赖项。此文件还包含基于入口点文件内容(包括任何提取的样式)计算的唯一版本哈希。

资产文件名镜像发出的 JavaScript 文件名,根据配置的 outputFormat 将文件扩展名替换为 .asset.php 或 .asset.json。因为它遵循 webpack output.filename 设置,所以单个未命名入口点默认生成 main.asset.php,而像 index.min.js 这样的输出会生成 index.min.asset.php。

例如,对于名为 entrypoint 的入口点:

// Entry `entrypoint`
import { Component } from 'react';

// Webpack will produce a JavaScript output file, for example output/entrypoint.js
/* bundled JavaScript output */

// Webpack will also produce a matching asset file, for example
// output/entrypoint.asset.php, declaring script dependencies
<?php return array('dependencies' => array('react'), 'version' => 'dd4c2dc50d046ed9d4c063a7ca95702f');

生成的资产文件名基于发出的 JavaScript 输出文件名。例如,如果 webpack 配置为 output.filename: 'bunny-plugin-[name].min.js',则 entrypoint 入口点会创建 output/bunny-plugin-entrypoint.min.asset.php。

默认情况下,处理以下模块请求:

RequestGlobalScript handle
@babel/runtime/regeneratorregeneratorRuntimewp-polyfill
@wordpress/*wp['*']wp-*
jqueryjQueryjquery
lodash-eslodashlodash
lodashlodashlodash
momentmomentmoment
react-domReactDOMreact-dom
reactReactreact

注意:此插件的功能与 webpack externals 提供的功能重叠。此插件旨在从包编译中提取脚本句柄,以便不需要手动维护脚本依赖项列表。如果您不需要提取脚本依赖项列表,请直接使用 externals 选项。

此插件与 externals 兼容,但它们可能会发生冲突。例如,向 webpack 配置添加 { externals: { '@wordpress/blob': 'wp.blob' } } 将使插件有效地隐藏 @wordpress/blob 模块,并且它不会包含在依赖项列表中。

与脚本模块的行为

警告:脚本模块支持目前被视为实验性的。

本节描述此软件包打包 ECMAScript 模块并生成适合与 WordPress Script Modules API 一起使用的资产文件的行为。

此插件的一些选项会发生变化,并且 webpack 需要配置以输出脚本模块。有关最新详细信息,请参阅
webpack 的文档。

const webpackConfig = {
    ...defaultConfig,

    // These lines are necessary to enable module compilation at time-of-writing:
    output: { module: true },
    experiments: { outputModule: true },

    plugins: [
        ...defaultConfig.plugins.filter(
            ( plugin ) =>
                plugin.constructor.name !== 'DependencyExtractionWebpackPlugin'
        ),
        new DependencyExtractionWebpackPlugin( {
            // With modules, use `requestToExternalModule`:
            requestToExternalModule( request ) {
                if ( request === 'my-registered-module' ) {
                    return request;
                }
            },
        } ),
    ],
};

webpack 包中的每个入口点都将包含一个资产文件,其中声明了应该排队的 WordPress 脚本模块依赖项。此文件还包含基于入口点文件内容(包括任何提取的样式)计算的唯一版本哈希。

例如,对于名为 entrypoint 的入口点:

// Entry `entrypoint`
import { store, getContext } from '@wordpress/interactivity';

// Webpack will produce a JavaScript output file, for example output/entrypoint.js
/* bundled JavaScript output */

// Webpack will also produce a matching asset file, for example
// output/entrypoint.asset.php, declaring script module dependencies
<?php return array('dependencies' => array('@wordpress/interactivity'), 'version' => 'dd4c2dc50d046ed9d4c063a7ca95702f');

默认情况下,处理以下脚本模块请求:

Request
@wordpress/interactivity

(@wordpress/interactivity 是目前唯一可用的 WordPress 脚本模块。)

注意:此插件的功能与 webpack externals 提供的功能重叠。此插件旨在从包编译中提取脚本模块标识符,以便不需要手动维护脚本模块依赖项列表。如果您不需要提取脚本模块依赖项列表,请直接使用 externals 选项。

此插件与 externals 兼容,但它们可能会发生冲突。例如,向 webpack 配置添加 { externals: { '@wordpress/blob': 'wp.blob' } } 将使插件有效地隐藏 @wordpress/blob 模块,并且它不会包含在依赖项列表中。

选项

可以将对象传递给构造函数来自定义行为,例如:

module.exports = {
    plugins: [
        new DependencyExtractionWebpackPlugin( { injectPolyfill: true } ),
    ],
};
outputFormat
  • Type: string
  • Default: php

生成的资产文件的输出格式。有两种可用选项:‘php’ 或 ‘json’。

outputFilename
  • Type: string | function
  • Default: null

生成的资产文件的文件名。接受与 Webpack output.filename 选项相同的值。

combineAssets
  • Type: boolean
  • Default: false

默认情况下,每个入口点会创建一个资产文件。当此标志设置为 true 时,所有关于资产的信息将合并到输出目录中生成的单个 assets.(json|php) 文件中。

combinedOutputFile
  • 类型:string
  • 默认值:null

仅当启用 combineAssets 选项时,此选项才有用。它允许为生成的单个资产文件提供自定义输出文件。可以提供相对于输出目录的路径。

useDefaults
  • 类型:boolean
  • 默认值:true

传递 useDefaults: false 以禁用默认的请求处理。

injectPolyfill
  • 类型:boolean
  • 默认值:false

强制在每个入口点的依赖列表中包含 wp-polyfill。这等同于在每个入口点添加 import '@wordpress/polyfill';。

注意:此选项在脚本模块中不可用。

externalizedReport
  • 类型:boolean | string
  • 默认值:false

以 JSON 格式数组报告所有外部化依赖项。可用于进一步的手动或自动检查。
您可以提供一个文件名,或将其设置为 true 以报告到默认的 externalized-dependencies.json。

requestToExternal

注意:此选项在脚本模块中不可用。请参阅 requestToExternalModule 以了解模块用法。

  • 类型:function

requestToExternal 允许自定义模块处理。该函数应接受一个模块请求字符串,并可能返回一个表示要使用的全局变量的字符串。可以使用字符串数组通过对象路径访问全局变量,例如 wp.i18n 可以表示为 [ 'wp', 'i18n' ]。

通过配置提供的 requestToExternal 优先于默认的外部处理。除非 useDefaults 设置为 false,否则未处理的请求将由默认值处理。

/**
 * Externalize 'my-module'
 *
 * @param {string} request Requested module
 *
 * @return {(string|undefined)} Script global
 */
function requestToExternal( request ) {
    // Handle imports like `import myModule from 'my-module'`
    if ( request === 'my-module' ) {
        // Expect to find `my-module` as myModule in the global scope:
        return 'myModule';
    }
}

module.exports = {
    plugins: [ new DependencyExtractionWebpackPlugin( { requestToExternal } ) ],
};
requestToExternalModule

注意:此选项仅在脚本模块中可用。请参阅 requestToExternal 以了解脚本用法。

  • 类型:function

requestToExternalModule 允许自定义脚本模块处理。该函数应接受一个脚本模块请求字符串,并可能返回一个表示要使用的脚本模块的字符串。通常,脚本模块的名称是相同的。

通过配置提供的 requestToExternalModule 优先于默认的外部处理。除非 useDefaults 设置为 false,否则未处理的请求将由默认值处理。

/**
 * Externalize 'my-module'
 *
 * @param {string} request Requested script module
 *
 * @return {(string|boolean|undefined)} Script module ID
 */
function requestToExternalModule( request ) {
    // Handle imports like `import myModule from 'my-module'`
    if ( request === 'my-module' ) {
        // Import should be of the form `import { something } from "myModule";` in the final bundle.
        return 'myModule';
    }

    // If the script module ID in source is the same as the external script module, `true` can be returned.
    return request === 'external-module-id-no-change-required';
}

module.exports = {
    plugins: [
        new DependencyExtractionWebpackPlugin( { requestToExternalModule } ),
    ],
};
requestToHandle

注意:此选项在脚本模块中不可用。它没有相应的模块配置。

  • 类型:function

插件处理的所有外部模块都预期是 WordPress 脚本依赖项
并将被添加到依赖列表中。requestToHandle 允许自定义包含在依赖列表中的脚本句柄。

如果没有返回字符串,则假设脚本句柄与请求相同。

通过配置提供的 requestToHandle 优先于默认值。除非 useDefaults 设置为 false,否则未处理的请求将由默认值处理。

/**
 * Map 'my-module' request to 'my-module-script-handle'
 *
 * @param {string} request Requested module
 *
 * @return {(string|undefined)} Script global
 */
function requestToHandle( request ) {
    // Handle imports like `import myModule from 'my-module'`
    if ( request === 'my-module' ) {
        // `my-module` depends on the script with the 'my-module-script-handle' handle.
        return 'my-module-script-handle';
    }
}

module.exports = {
    plugins: [ new DependencyExtractionWebpackPlugin( { requestToHandle } ) ],
};
requestToExternal and requestToHandle

函数 requestToExternal 和 requestToHandle 允许此模块处理任意模块。

requestToExternal 对于处理任何模块都是必要的,它将模块请求映射到全局名称。

requestToHandle 将相同的模块请求映射到脚本句柄,这些字符串将被包含在 entrypoint.asset.php 文件中。

WordPress

像往常一样排入队列您的脚本,并动态读取脚本依赖项:

$script_path       = 'path/to/script.js';
$script_asset_path = 'path/to/script.asset.php';
$script_asset      = file_exists( $script_asset_path )
    ? require( $script_asset_path )
    : array( 'dependencies' => array(), 'version' => filemtime( $script_path ) );
$script_url = plugins_url( $script_path, __FILE__ );
wp_enqueue_script( 'script', $script_url, $script_asset['dependencies'], $script_asset['version'] );

或者使用模块(Script Module API 仅在 WordPress > 6.5 中可用):

$module_path       = 'path/to/module.js';
$module_asset_path = 'path/to/module.asset.php';
$module_asset      = file_exists( $module_asset_path )
    ? require( $module_asset_path )
    : array( 'dependencies' => array(), 'version' => filemtime( $module_path ) );
$module_url = plugins_url( $module_path, __FILE__ );
wp_register_script_module( 'my-module', $module_url, $module_asset['dependencies'], $module_asset['version'] );
wp_enqueue_script_module( 'my-module' );

Contributing to this package

This is an individual package that’s part of the Gutenberg project. The project is organized as a monorepo. It’s made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to npm and used by WordPress as well as other software projects.

To find out more about contributing to this package or Gutenberg as a whole, please read the project’s main contributor guide.