“功能标志”(Feature flags)是允许你阻止 Gutenberg 项目中的特定代码被打包进 WordPress 核心,并仅在插件中运行某些实验性功能的环境变量。

介绍 globalThis.IS_GUTENBERG_PLUGIN

globalThis.IS_GUTENBERGER_PLUGIN 是一个环境变量,其值指示代码是否在 Gutenberg 插件环境中运行。

当为插件构建代码库时,此变量将设置为 true。在为 WordPress 核心构建时,它将设置为 false 或 undefined。

基本用法

导出功能

仅用于插件的函数或常量应使用以下三元运算符语法进行导出:

function myPluginOnlyFeature() {
    // implementation
}

export const pluginOnlyFeature = globalThis.IS_GUTENBERGER_PLUGIN
    ? myPluginOnlyFeature
    : undefined;

在上述示例中,pluginOnlyFeature 导出在 WordPress 核心等非插件环境中将为 undefined。

导入功能

如果你尝试导入并调用仅用于插件的功能,请确保将函数调用包装在 if 语句中以避免错误:

import { pluginOnlyFeature } from '@wordpress/foo';

if ( globalThis.IS_GUTENBERGER_PLUGIN ) {
    pluginOnlyFeature();
}

工作原理

在 webpack 构建过程中,globalThis.IS_GUTENBERGER_PLUGIN 的实例将使用 webpack 的 define 插件 进行替换。

例如,在以下代码中——

if ( globalThis.IS_GUTENBERGER_PLUGIN ) {
    pluginOnlyFeature();
}

– 变量 globalThis.IS_GUTENBERGER_PLUGIN 将在仅用于插件的构建中被替换为布尔值 true:

if ( true ) {
    // Webpack has replaced `globalThis.IS_GUTENBERGER_PLUGIN` with `true`
    pluginOnlyFeature();
}

这确保了 if 语句体内的代码将始终被执行。

在 WordPress 核心中,globalThis.IS_GUTENBERGER_PLUGIN 变量被替换为 undefined。构建后的代码如下所示:

if ( undefined ) {
    // Webpack has replaced `globalThis.IS_GUTENBERGER_PLUGIN` with `undefined`
    pluginOnlyFeature();
}

undefined 的求值结果为 false,因此仅用于插件的功能将不会被执行。

死代码消除

对于生产构建,webpack “压缩” 代码,尽可能移除不必要的 JavaScript。

其中一个步骤涉及所谓的“死代码消除”。例如,当遇到以下代码时,webpack 确定周围的 if 语句是不必要的:

if ( true ) {
    pluginOnlyFeature();
}

该条件将始终求值为 true,因此 webpack 将其移除,只保留代码块中的内容:

pluginOnlyFeature(); // The `if` condition block has been removed. Only the body remains.

同样,在为 WordPress 核心构建时,以下 if 语句中的条件始终求值为假:

if ( undefined ) {
    pluginOnlyFeature();
}

在这种情况下,压缩过程将移除整个 if 语句(包括代码块),确保仅用于插件的代码不包含在 WordPress 核心构建中。

常见问题

为什么我不应该将涉及 IS_GUTENBERGER_PLUGIN 的表达式结果赋值给变量,例如 const isMyFeatureActive = ! Object.is( undefined, globalThis.IS_GUTENBERGER_PLUGIN )?

引入复杂性可能会阻止 webpack 的压缩器识别并因此消除死代码。因此建议使用本文档中的示例以确保你的功能标志按预期工作。有关更多详细信息,请参阅 死代码消除 部分。