フィーチャーフラグ
Gutenberg プロジェクトのフェーズ2を開始するにあたってはコード変更のリリースコントロールを改良する必要がありました。フェーズ2以降で開発された新しい機能は Gutenberg プラグインとしてリリースする一方、改良やバグの修正は引き続きコアリリースに反映しなければなりません。
こうした処理技術は「フィーチャーフラグ」として知られています。
process.env.GUTENBERG_PHASE の導入
process.env.GUTENBERG_PHASE
はフェーズ番号を示す環境変数です。コードをプラグインとしてビルドする際、この変数を 2
にセットします。コアとしてビルドする際には 1
にセットします。
基本的な使用方法
フェーズ2の関数や定数は次の3項構文を使用してエクスポートしてください。
function myPhaseTwoFeature() {
// implementation
}
export const phaseTwoFeature = process.env.GUTENBERG_PHASE === 2 ? myPhaseTwoFeature : undefined;
フェーズ1の環境で phaseTwoFeature
のエクスポートは undefined
になります。
フェーズ2の機能をインポートし呼び出す場合はエラーを避けるため、関数呼び出しを if 文でラップしてください。
import { phaseTwoFeature } from '@wordpress/foo';
if ( process.env.GUTENBERG_PHASE === 2) {
phaseTwoFeature();
}
動作原理
webpack のビルド時、すべての process.env.GUTENBERG_PHASE
は webpack の define プラグイン を使用して置き換えられます。
次のようなコードがある場合
if ( process.env.GUTENBERG_PHASE === 2 ) {
phaseTwoFeature();
}
コードベースをプラグインとしてビルドすると、変数は数値リテラル 2
で置き換えられます。
if ( 2 === 2 ) {
phaseTwoFeature();
}
if 文内部のコードは、2 === 2
が true
と評価されるため、Gutenberg プラグイン内部で実行されます。
コアでは、process.env.GUTENBERG_PHASE
変数は 1
で置換されるため、ビルドされたコードは以下のようになります。
if ( 1 === 2 ) {
phaseTwoFeature();
}
1 === 2
は false
と評価されるため、フェーズ2の機能はコア内部では実行されません。
呼ばれないコードの削除
本番リリース用にコードをビルドする場合、webpack はコードをミニファイ (縮小化) し、可能な限り不要な JavaScript のコードを削除しようとします。その中の1つが「呼ばれないコードの削除」です。
次のコードに出会うと webpack は周りの if
文は不要と判断します。
if ( 2 === 2 ) {
phaseTwoFeature();
}
条件は常に true
と評価されるため、if 文を削除し、中の実行部分のみを残すことができます。
phaseTwoFeature();
同様にコアのビルドの場合、次の if
文の条件は常に false
と解決されます。
if ( 1 === 2 ) {
phaseTwoFeature();
}
ミニファイプロセスは内容を含む if
文全体を削除します。これでフェーズ2のコードは、コア用にビルドされた JavaScript に含まれません。
FAQ
なぜ process.env.GUTENBERG_PHASE の比較には === や !== のみを使うべきなのですか ? >、>=、<、<= ではいけないのですか ?
これは process.env.GUTENBERG_PHASE
が undefined
の場合の JavaScript 演算子 >
、<
の振る舞いのための制限です。WordPress npm パッケージのサードパーティユーザーも同様です。process.env.GUTENBERG_PHASE < 2
も process.env.GUTENBERG_PHASE > 1
も false
と解決されます。if ( process.env.GUTENBERG_PHASE > 1 )
と書いて、続く if
文内部のフェーズ2のコードの実行を避けるつもりなら、これは false
と評価されるため意図したとおりに動作します。
しかし次のコードは予想したとおりに動作しません。
function myPhaseTwoFeature() {
if ( process.env.GUTENBERG_PHASE < 2 ) {
return;
}
// implementation of phase 2 feature
}
このコードはフェーズ2の機能の実行を避けるため、その前で return
しています。しかし if
の条件は false と解決されるため、その前の return
は通らず、フェーズ2の機能が誤って呼び出されます。
なぜ GUTENBERG_PHASE 関連の評価結果を変数に割り当てるべきではないのですか ? たとえば const isMyFeatureActive = process.env.GUTENBERG_PHASE === 2 ではいけないのですか ?
webpack のミニファイが呼ばれないコードを削除できるよう、コードに複雑性を持ち込まないようにするためです。詳細については上の「呼ばれないコードの削除」セクションを参照してください。
最終更新日: