コンパイラの "emit" のフックを使ってすべてのチャンクに対して JSDefender を実行する webpack プラグインです。
サポートされる webpack のバージョン: ^3.0.0
、^4.0.0
、^5.0.0
インストール
このプラグインをプロジェクトにインストールします。
npm install <package-directory>/preemptive-jsdefender-core-{version}.tgz <package-directory>/preemptive-jsdefender-webpack-plugin-{version}.tgz --save-dev
または
yarn add file:<package-directory>/preemptive-jsdefender-core-{version}.tgz file:<package-directory>/preemptive-jsdefender-webpack-plugin-{version}.tgz --dev
@preemptive/jsdefender-core
もインストールする必要があります。使用法
本番モードと縮小ツール
既定では、本番モードで webpack を実行すると、コードから JSDefender インライン保護ディレクティブを削除する最適化が適用されます。結果として、JSDefender はインライン保護設定を使用できなくなります。webpack にディレクティブを除去させないようにするには、webpack の最適化設定を変更する必要があります。最適化を完全に無効にすることができますが、それはお勧めしません。代わりに、既定の縮小ツールからディレクティブを保持する縮小ツールに変更します。
次の webpack.config.js
コード スニペットでは、terser-webpack-plugin
を利用しています。
const TerserPlugin = require("terser-webpack-plugin");
//...
module.exports = {
// 他の設定を使用する際と同じように使用します
// ...
// 最適化の設定を変更します
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({ // 縮小ツールとして TerserPlugin を使用します
terserOptions: {
compress: { // ディレクティブを保持します
directives: false,
},
},
}),
],
},
// ...
// その他の設定
}
プレーンな Webpack
jsdefender-webpack-plugin
を webpack 構成(既定では webpack.config.js
と呼ばれます)にインポートし、plugins
配列に追加します。
const { JSDefenderWebpackPlugin } = require('@preemptive/jsdefender-webpack-plugin');
// --その他の構成
plugins: [
// --その他のプラグイン
new JSDefenderWebpackPlugin({
configurationFile: 'jsdefender.config.json', // 構成ファイルがある場合は、そのファイルへの任意のパス。既定では `jsdefender.config.json` となります
quietMode: false, // false の場合はすべてのログ メッセージが表示され、そうでない場合はエラーと警告のみが表示されます。既定値は false です
enableInDevelopmentMode: false, // false の場合は非本番モードでは保護がスキップされ、そうでない場合はすべてのモードで保護が実行されます。既定値は false です
includeChunks: [ 'app', 'util' ], // 保護するチャンク名。既定では、すべてのチャンクが保護対象となります
excludeChunks: [ 'vendor', 'util' ], // 保護しないチャンク名。既定では何も除外されません
/* その他の JSDefender オプション(`settings: { booleanLiterals: true, stringLiterals: true }` など)もここで指定できます */
})
]
enableInDevelopmentMode
オプションを true
に設定します。booleanLiterals: true
を指定し、プラグインのコンストラクターに booleanLiterals: false
を直接指定した場合、最終的な値は booleanLiterals: false
となります。includeChunks
と excludeChunks
の両方に指定されている場合は、後者(つまり、除外)が優先されます。Angular
Angular は既定で開発者から webpack 構成を隠し、Angular のバージョンごとに異なる方法で変更できます。
JSDefender Webpack プラグインの Webpack 構成は、どの Angular バージョンでも同じです。
const { JSDefenderWebpackPlugin } = require('@preemptive/jsdefender-webpack-plugin');
...
module.exports = {
...
plugins: [
new JSDefenderWebpackPlugin({
/* 上記の例のすべての構成をここで使用できます。: */
excludeChunks: [ 'vendor', 'scripts', 'common', 'runtime', 'polyfills', 'polyfills-es5', 'styles', 'inline' ] // vendor チャンクは常に対象から除外されますが、それ以外のシステム チャンク(特に polyfills)にも問題があります
})
]
...
}
vendor
チャンクは、JSDefender では保護できない廃止されたコードを含んでいるため、含めないように注意してください。vendor
チャンクを除外した後も問題が発生する場合は、polyfills
と polyfills-es5
で始まる他のシステム チャンクも除外する必要があります。ただし、パフォーマンスを最大限に高めたい場合は、上記の構成例に指定されているすべてのシステム チャンクを除外する必要があります。除外を行うには、当該アプリのチャンクを 1 つずつに含めるか、該当するチャンクを除外します。その他のチャンクを含めたり除外したりすることももちろん可能です。
提供されている構成は、Angular または Angular Universal(サーバー サイド レンダリング)で動作する必要があります。
テストした Angular バージョン:^5.0.0
、^8.0.0
、^9.0.0
、^11.0.0
、^14.0.0
Angular 2 ~ 5
Angular 2 ~ 5 プロジェクトで webpack.config.js
を編集できるようにするには、既定で非表示になっているため、最初にイジェクトする必要があります。イジェクトするには、次のコマンドを実行します。
ng eject
イジェクト後、Angular セクションに示すように、JSDefenderWebpackPlugin
を webpack.config.js
の plugins 配列に追加します。
次に、--prod
モードで --vendor-chunk=true
フラグを使用してプロジェクトを build または serve し、別の vendor バンドルを生成して保護から除外できるようにします。開発ビルドでは、vendor チャンクが自動的に生成されます。
ng build --prod --vendor-chunk=true
ng serve --prod --vendor-chunk=true
これで、保護されたチャンクが表示されます。
Angular 6 以降
Angular 6 以降では、webpack.config.js
は編集できず、イジェクトすることもできませんが、カスタム Angular ビルダーを使用して webpack 構成を変更することができます。
Angular プロジェクトに webpack.partial.js
というファイルを作成し、Angular セクションに示すように構成を追加します。
angular.json
の本番ビルド構成で "vendorChunk": true
を設定するか、ビルド スクリプトに --vendorChunk=true
フラグを追加して、本番ビルドへの個別の vendor
チャンクの作成を有効にします。詳細については、ng build に関する説明を参照してください。
custom-webpack
ビルダーの使用
@angular-builders/custom-webpack ビルダーを使用すると、angular.json
ファイルでカスタム webpack 構成へのパスを提供できます。ほかにも Angular の Webpack 構成の拡張に使用できるビルダーはありますが、custom-webpack
をお勧めします。Angular バージョンと互換性のあるバージョンを使用してください。
パッケージをインストールする:
npm install --save-dev @angular-builders/custom-webpack@{version}
または
yarn add --dev @angular-builders/custom-webpack@{version}
プロジェクトの angular.json
構成を変更する:
"architect": {
...
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./webpack.partial.js"
},
...
}
},
"serve": {
"builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"browserTarget": "{project-name}:build" // {project-name} をプロジェクトの名前に変更します
}
}
次に、Angular プロジェクトを build または serve し、保護されたチャンクを確認します。
ngx-build-plus
ビルダーの使用
ngx-build-plus ビルダーにより、Angular CLI(ng
)で --extra-webpack-config
フラグを使用してカスタム webpack 構成を提供できます。Angular バージョンと互換性のあるバージョンを使用してください。
Angular CLI 経由でパッケージをインストールする:
ng add ngx-build-plus@^{your-angular-major-version}.0.0
次のステップは、ビルドに webpack 構成の一部を追加するか、package.json
内に --extra-webpack-config
フラグを指定してスクリプトを実行することです。
"scripts": {
"build:prod": "ng build --extra-webpack-config webpack.partial.js --prod",
"serve:prod": "ng serve --extra-webpack-config webpack.partial.js --prod",
}
次に、Angular プロジェクトを build または serve し、保護されたチャンクを確認します。
Ionic
Ionic は既定で開発者から webpack 構成を隠しますが、フレームワークの異なるバージョンに対して異なる方法で変更できます。
検証済みの Ionic とフロントエンド フレームワーク バージョンの組み合わせ:
- Ionic
^3.0.0
と Angular^5.0.0
- Ionic
^5.0.0
と Angular^8.0.0
- Ionic
^5.0.0
と React^16.0.0
Ionic 2 ~ 3
Ionic 2 ~ 3 では、Ionic 独自の構成を拡張できるユーザー独自の webpack 構成を提供できます。
まず、プロジェクトの package.json
の "config"
セクションに "ionic_webpack"
構成を追加します。
{
...
"config": {
"ionic_webpack": "./webpack.partial.js"
}
...
}
次に、webpack.partial.js
というファイルをプロジェクト ルートに追加し、次の構成を追加します。ファイルを保存してから、上記の Angular セクションのように JSDefenderWebpackPlugin
を構成します。
const { dev, prod } = require('@ionic/app-scripts/config/webpack.config');
const webpackMerge = require('webpack-merge');
const { JSDefenderWebpackPlugin } = require('@preemptive/jsdefender-webpack-plugin');
const webpackJSDefenderConfig = {
plugins: [
new JSDefenderWebpackPlugin({
/* 上記の Angular セクションと同じ構成で、vendor チャンクを必ず除外してください */
})
]
};
module.exports = {
dev: webpackMerge(dev, webpackJSDefenderConfig),
prod: webpackMerge(prod, webpackJSDefenderConfig)
};
vendor
チャンクは常に Ionic 2 ~ 3 プロジェクト用に生成されるため、JSDefenderWebpackPlugin
構成で除外する以外に追加の構成は必要ありません。
Ionic 4 以降
lsonic 4 以降、Ionic によって作成されたカスタム webpack 構成はありません。代わりに、内部フロントエンド フレームワーク(Angular、React、Vue)独自のソリューションが使用されます。
Angular 6 以降
既出の Angular 6 以降セクションの構成は、Ionic 4 以降および Angular 6 以降のプロジェクトに使用できます。既定の webpack 構成を拡張するには、カスタム ビルダーを追加する必要があります。
React 16 以降
カスタム webpack 構成が利用できないという苦しい状況を回避するために、Ionic-React プロジェクトをこの webpack プラグインで機能させる方法は 2 つあります(どちらか一方を使用し、両方を使用しないでください)。
1. イジェクト
npm run eject
または npx react-scripts eject
を使用して、管理対象の React 環境からイジェクトします。
前述の「使用法」->「プレーンな Webpack」セクションで説明したプラグインのインストールを実行します。
2. react-app-rewired の使用
webpack 構成オプション(リンク)へのアクセスに役立つサードパーティ製パッケージがあります。これは追加の依存関係ですが、それでも必要なものです。
- プロジェクトにパッケージをインストールします:
npm install react-app-rewired --save-dev
- 以下を package.json スクリプトに追加します(必要に応じて既存のスクリプト キーを変更します)。
"start": "react-app-rewired start",
"build": "react-app-rewired build",
- プロジェクトのルート ディレクトリに
config-overrides.js
を作成し、以下の行を追加します。
const { JSDefenderWebpackPlugin } = require('@preemptive/jsdefender-webpack-plugin');
module.exports = function override(config, env) {
if (!config.plugins) {
config.plugins = [];
}
config.plugins.push(
new JSDefenderWebpackPlugin({
configurationFile: './jsdefender.config.json',
excludeChunks: [ 'vendor', 'scripts', 'common', 'runtime', 'polyfills', 'polyfills-es5', 'styles' ]
})
);
return config;
}
- 以下の構成ガイドに従って JSDefender 構成をセットアップします。
- 最後に、
npm run build
またはyarn build
を実行し、webpack プラグインでコードを保護します。
構成
JSDefender の webpack プラグインは、JSDefender の構成ファイルと同じ構成オブジェクトを受け付けます。詳細については、このドキュメントのホームを参照してください。プラグインは JSDefender CLI と同様、既定の構成を使用します。これは、プラグインに明示的に構成を指定することによって上書きできます。
configurationFile
を指定している場合、その個々の構成行は、webpack.config.js
または webpack.partial.js
Webpack 構成ファイル内の new JSDefenderWebpackPlugin()
コンストラクターに直接渡された JSDefender 構成によって上書きされます。たとえば、JSDefenderWebpackPlugin
コンストラクターに booleanLiterals: true
を設定したが、configurationFile
には booleanLiterals: false
が設定されていた場合、前者が優先されます。つまり、最終的な値は booleanLiterals: true
になります。