SharePoint Framework ツールチェーンでの Webpack の拡張
webpack は、JavaScript ファイルとその依存関係を処理して 1 つまたは複数の JavaScript ファイルを生成する JavaScript モジュール バンドラーです。さまざまなシナリオについて異なるコードの部分を読み込むことができます。
開発ツール チェーンは CommonJS を使用してバンドルします。これにより、モジュール、およびそれらを使用する場所を定義することができます。また、ツール チェーンを使用してユニバーサル モジュール ローダーである SystemJS を使用し、モジュールをロードします。これにより、各 Web パーツが独自の名前空間で実行されることを確実にすることによって、Web パーツのスコープをすることができます。
SharePoint Framework のツールチェーンに追加できる一般的なタスクの 1 つは、カスタム ローダーとプラグインを使って Webpack 構成を拡張することです。
Webpack ローダーの使用
開発時に JavaScript 以外のリソースをインポートして利用する機会は数多くあります。この場合、通常はイメージやテンプレートを使用します。 Webpack ローダーは、JavaScript アプリケーションで利用できるものにリソースを変換するか、JavaScript アプリケーションで認識できる単純な参照を提供します。
たとえば、Markdown テンプレートがコンパイルされてテキスト文字列に変換され、イメージ リソースがインライン Base64 イメージに変換されることもあれば、URL として参照されて、dist ディレクトリにコピーされ展開されることもあります。
いくつかの便利なローダーが用意されており、その中のいくつかは標準の SharePoint Framework Webpack 構成で既に使用されています。たとえば、次のローダーがあります。
- html-loader
- json-loader
- loader-load-themed-styles
カスタム ローダーを使用してフレームワークの Webpack 構成を拡張する作業は、簡単なプロセスです。この説明は、「Webpack Loaders (Webpack のローダー)」にあります。
例:markdown-loader パッケージの使い方
一例として、markdown-loader パッケージを使ってみましょう。このローダーでは、.md ファイルを参照し、それを HTML 文字列として出力します。
完成したサンプルは、samples/js-extend-webpack からダウンロードできます。
手順 1 - パッケージをインストールする
プロジェクトで、markdown-loader ローダーを参照します。
npm i --save markdown-loader
手順 2 - webpack を構成する
これでパッケージをインストールできました。次に、SharePoint Framework Webpack の構成に markdown-loader を組み込みます。
markdown-loader のドキュメントには、Webpack 構成を拡張してローダーを組み込む方法が記載されています。
{
module: {
rules: [
{
test: /\.md$/,
use: [
{
loader: 'html-loader'
},
{
loader: 'markdown-loader',
options: {
/* options for markdown-loader here */
}
}
]
}
]
}
}
この構成で行われる処理の内容を概観してみましょう。
- Webpack 構成内の
rules
配列は、ファイル パス テスト、およびそのテストと一致するリソースが見つかったときに使用されるローダーのセットを定義します。この場合、test
プロパティは、.md で終わるファイル パスをチェックします。 use
配列には、リソースに順番に適用されるローダーのリストが記述されます。 最後から最初への順番で適用されます。 ここでは、最初に適用されるローダーがmarkdown-loader
、最後に適用されるローダーがhtml-loader
になります。- 複数のローダーが指定されている場合、各ローダーの結果は、次のものにパイプでつながれます。
ここでは、この情報を使用してプロジェクト内で Webpack 構成を構成します。
SharePoint フレームワーク Webpack 構成にこのカスタム ローダーを追加するには、Webpack を構成するようにビルド タスクに指示を与える必要があります。 ビルド タスクは gulpfile.js で定義します。これはプロジェクトのルートにあります。
gulpfile.js を編集し、次のコードを build.initialize(gulp);
の直前に追加します。
build.configureWebpack.mergeConfig({
additionalConfiguration: (generatedConfiguration) => {
generatedConfiguration.module.rules.push(
{
test: /\.md$/,
use: [
{
loader: 'html-loader'
},
{
loader: 'markdown-loader'
}
]
}
);
return generatedConfiguration;
}
});
このコード スニペットで発生する処理の内容を概観してみましょう。
- (
build.configureWebpack
としてインスタンス化された)ConfigureWebpackTask
は、Webpack を構成します。SPFx プロジェクトのビルドでは特別な構成が大量に発生するため、このタスクには重要なロジックがいくつかあります。 ConfigureWebpackTask
は、オプションのadditionalConfiguration
プロパティを取ります。 このプロパティを関数に設定します。この関数は生成される構成を取り、変更を加え、更新された構成を返します。 この関数は、Webpack 構成をツールチェーンに返す必要があります。そうしないと、Webpack は正しく構成されません。additionalConfiguration
に設定する関数の本体内で、構成内の既存のルール セットに新しいルールを単にプッシュします。 この新しいルールは、手順 2 の最初に出てくる構成スニペットの例に似ています。
注意
この方法を使ってツールチェーンの既定の Webpack 構成を完全に置き換えることもできますが、パフォーマンスと最適化のメリットを最大限に活用するために、ドキュメントに明記されていない限り、そのようにすることはお勧めしません。
手順 3 - コードを更新する
これでローダーの構成が終わりました。次に、コードを更新し、いくつかのファイルを追加してシナリオをテストします。
./src/my-markdown.md というファイルを作成し、その中にいくつかのマークダウン テキストを入力します。
#Hello Markdown *Markdown* is a simple markup format to write content. You can also format text as **bold** or *italics* or ***bold italics***
プロジェクトをビルドすると、Webpack markdown-loader によってこのマークダウン テキストが HTML 文字列に変換されます。
ソース .ts ファイルのいずれかでこの HTML 文字列を使用するには、次の
require()
行を、ファイル先頭の imports の後に追加します。たとえば、次のとおりです。const markdownString: string = require<string>('./../../../../src/my-markdown.md');
Webpack は既定では
lib
フォルダーからファイルを探しますが、既定では.md
ファイルがlib
フォルダーにコピーされません。したがって、かなり長い相対パスを作成する必要があります。この設定を制御するには、ツールチェーンがmd
ファイルを lib フォルダーにコピーするように構成ファイルを定義します。ファイル ./config/copy-static-assets.json を作成し、いくつかの追加ファイルを src から lib にコピーするようにビルド システムに指示を与えます。このビルド タスクは、既定のツールチェーン Webpack 構成に認識される拡張子 (png や json など) を持つファイルをコピーします。したがって、md ファイルもコピーするようにビルドタスクに指示を与える必要があります。
{ "includeExtensions": [ "md" ] }
これで、
require
ステートメントで、相対パスを使う代わりに、ファイル パスを使用できるようになります。たとえば、次のとおりです。const markdownString: string = require<string>('./../../readme.md');
その後、この文字列をコードで参照することができます。たとえば、次のとおりです。
public render(): void { this.domElement.innerHTML = markdownString; }
手順 4 - コードをビルドしてテストする
コードをビルドしてテストするために、コンソールから、プロジェクト ディレクトリのルートで、次のコマンドを実行します。
gulp serve