构建过程是一种将源代码文件转换为计算机可读的最终构建/生产版本的方法。特别是,主题通常会将源代码压缩或转换为 CSS 或 JavaScript,以便浏览器可以读取。

在创建 WordPress 主题时,您可能需要构建过程来处理更复杂的项目。有许多系统可供选择,您可以使用您喜欢的任何系统。但是,WordPress 也提供了一个标准包,您可以确信它会持续更新,并应满足您的大部分需求。

在本文中,您将学习如何集成 @wordpress/scripts 包来处理主题构建过程。

先决条件

大多数 WordPress 主题开发基本上即插即用。您只需要一个代码编辑器,并在某种开发环境中安装 WordPress,如 工具和设置 中所述。但是,要使用构建过程,还有其他要求:

这些是比构建主题通常所需的更高级的工具,但如果您想使用标准的 WordPress 构建过程,它们是必要的。

设置您的文件和文件夹

@wordpress/scripts 包最初是为块开发而创建的,但它随着时间的推移也演变为适用于主题。默认情况下,它期望开发文件位于 /src 文件夹中,并将构建文件输出到 /build 文件夹。由于大多数主题作者使用自定义系统来处理资源,本指南将向您展示如何做到这一点。

对于以下示例,您将在主题文件夹中使用此结构:

  • public/
  • resources/
    • js/
      • editor.js
    • scss/
      • editor.scss
      • screen.scss
  • package.json
  • webpack.config.js

安装 WordPress 脚本包

设置好文件和文件夹后,您需要在本地计算机上安装正确的包。

首先,打开主题的 package.json 文件并添加以下代码:

{
	"name": "your-project-name",
	"scripts": {
		"start": "wp-scripts start --webpack-src-dir=resources --output-path=public",
		"build": "wp-scripts build --webpack-src-dir=resources --output-path=public"
	}
}

@wordpress/scripts 包还有其他 可用脚本,您可以添加它们,但您肯定需要 start 和 build。

现在在计算机上打开命令行工具,导航到您的主题文件夹,并输入以下命令:

npm install @wordpress/scripts path webpack-remove-empty-scripts --save-dev

该命令安装了三个包:

  • @wordpress/scripts
  • path
  • webpack-remove-empty-scripts

后两个是第三方包,但它们对于在下一步中与 Webpack 集成很有用。

配置 webpack

@wordpress/scripts 包构建在 Webpack 之上。如果您正在构建块,一切都已经就位。但是,由于您正在构建主题,您需要使用自己的配置覆盖 @wordpress/scripts 包的某些默认配置。

这就是您的主题的自定义 webpack.config.js 文件发挥作用的地方。您需要配置两件事:

  • 您自定义 CSS 和 JavaScript 文件的入口点(代码中的这些对应于本文中的文件结构)。
  • webpack-remove-empty-scripts 插件,以便没有剩余的 .js 文件映射到您的 CSS。

将以下代码添加到您的 webpack.config.js 文件中:

// WordPress webpack config.
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );

// Plugins.
const RemoveEmptyScriptsPlugin = require( 'webpack-remove-empty-scripts' );

// Utilities.
const path = require( 'path' );

// Add any new entry points by extending the webpack config.
module.exports = {
	...defaultConfig,
	...{
		entry: {
			'js/editor':  path.resolve( process.cwd(), 'resources/js',   'editor.js'   ),
			'css/screen': path.resolve( process.cwd(), 'resources/scss', 'screen.scss' ),
			'css/editor': path.resolve( process.cwd(), 'resources/scss', 'editor.scss' ),
		},
		plugins: [
			// Include WP's plugin config.
			...defaultConfig.plugins,

			// Removes the empty `.js` files generated by webpack but
			// sets it after WP has generated its `*.asset.php` file.
			new RemoveEmptyScriptsPlugin( {
				stage: RemoveEmptyScriptsPlugin.STAGE_AFTER_PROCESS_PLUGINS
			} )
		]
	}
};

使用 WordPress 脚本包

要使用 WordPress 脚本包处理您的资源,您可以在命令行工具中运行两个命令之一:

  • start:构建文件的开发版本并激活“监视”模式,这将处理任何代码更改。
  • build:构建文件的生产版本。

现在在计算机上打开命令行工具并运行 start 命令:

npm run start

它应该自动从 /resources 文件夹处理您的文件,并将它们放置在 /public 文件夹中,结构如下:

  • public/
    • js/
      • editor.js
      • editor.asset.php
    • scss/
      • editor.scss
      • editor.asset.php
      • screen.scss
      • screen.asset.php

您现在将为每个 CSS 和 JavaScript 文件看到新的 *.asset.php 文件。这些文件将包含有关每个资源文件的元数据,您可以在加载文件时使用它们。这在下方的“加载脚本和样式”部分中涵盖。

要禁用 start 命令,请在命令行工具中输入 Ctrl + C(在 Windows 或 Mac 上)。

当您准备好对文件进行最终生产构建时,在命令行工具中运行此命令:

npm run build

加载脚本和样式

加载脚本和样式的方法已在手册中的 包含资源 文档中详细涵盖。在继续下一步之前,您应该已经熟悉如何执行此操作。

下面的文档主要是教您如何为每个资源生成 *.asset.php 文件。在每个文件中,您将看到一个类似于以下代码段的数组:

<?php return array('dependencies' => array('wp-block-editor'), 'version' => '2eae4c519afeff2a8c77');

特别是,该数组将有两个元数据,您可以在任何 wp_enqueue_*() 函数中使用:

  • dependencies: 您的脚本/样式依赖的依赖项数组。
  • version: 可用于缓存清除的版本号。

由于该文件返回数组,您可以使用 PHP 的 include 将数组分配给代码中的变量。以下示例显示获取 screen.asset.php 文件的数组:

$asset = include get_theme_file_path( 'public/css/screen.asset.php' );
// Returns: array( 'dependencies' => array(), 'version' => '0000' );

当使用 wp_enqueue_script() 或 wp_enqueue_style() 加载脚本或样式时,您可以将 $asset['dependencies'] 和 $asset['version'] 传递给函数中的相应参数。

尝试将以下代码添加到主题的 functions.php 文件中以加载您之前定义的资源:

// Load front-end assets.
add_action( 'wp_enqueue_scripts', 'themeslug_assets' );

function themeslug_assets() {
	$asset = include get_theme_file_path( 'public/css/screen.asset.php' );

	wp_enqueue_style(
		'themeslug-style',
		get_theme_file_uri( 'public/css/screen.css' ),
		$asset['dependencies'],
		$asset['version']
	);
}

// Load editor stylesheets.
add_action( 'after_setup_theme', 'themeslug_editor_styles' );

function themeslug_editor_styles() {
	add_editor_style( [
		get_theme_file_uri( 'public/css/screen.css' )
	] );
}

// Load editor scripts.
add_action( 'enqueue_block_editor_assets', 'themeslug_editor_assets' );

function themeslug_editor_assets() {
	$script_asset = include get_theme_file_path( 'public/js/editor.asset.php'  );
	$style_asset  = include get_theme_file_path( 'public/css/editor.asset.php' );

	wp_enqueue_script(
		'themeslug-editor',
		get_theme_file_uri( 'public/js/editor.js' ),
		$script_asset['dependencies'],
		$script_asset['version'],
		true
	);

	wp_enqueue_style(
		'themeslug-editor',
		get_theme_file_uri( 'public/css/editor.css' ),
		$style_asset['dependencies'],
		$style_asset['version']
	);
}