lovedと申します。
Qiitaコントリビューターの皆様、いつも大変ありがとうございます。
TL;DR
Angular7では、Angular6で使用できたng eject
コマンドが廃止されました。
そこで今回はAngular7でAngular-CLI開発をする時のwebpack詳細設定の仕方を紹介します。
angular.jsonを編集した上で、webpack拡張設定ファイルを作成してビルドする方法です。
対象読者
・Angular7でデフォルトのビルド設定でカバーできない要件があり、
Angularの内部で動いているwebpack部分のconfigを調整する必要がある方。
・前準備でAngular7環境での初期構築を行っていますので、Angular7(とag-Grid)をこれから使用する/学ぶ予定がある方にもお楽しみいただけるかと思います。
環境
>> ng version
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 7.3.0
Node: 9.3.0
OS: win32 x64
Angular:
...
Package Version
------------------------------------------------------
@angular-devkit/architect 0.13.0
@angular-devkit/core 7.3.0
@angular-devkit/schematics 7.3.0
@schematics/angular 7.3.0
@schematics/update 0.13.0
rxjs 6.3.3
typescript 3.2.2
・・・Nodeのバージョンが古いですが、気にしないでください。
今回はag-gridのチュートリアルを借りつつ手順を紹介します。
ag-gridはコミュニティエディション無料のgridモジュールです。
https://www.ag-grid.com/angular-getting-started/
手順
ではやっていきましょう。
前準備は上述チュートリアルページとほぼ同一です。
理解度の高い方は飛ばして頂いて問題ありません。
前準備
// インストールとプロジェクトの作成
npm install -g @angular/cli
ng new my-app --style scss --routing false
cd my-app
// ag-gridのインストール
npm install --save ag-grid-community ag-grid-angular
// プロジェクト内 app.module.tsを編集
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AgGridModule } from 'ag-grid-angular';// ←追加
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AgGridModule.withComponents([])],// ←追加
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
// styles.scssを編集
@import "~ag-grid-community/dist/styles/ag-grid.css";
@import "~ag-grid-community/dist/styles/ag-theme-balham.css";
// app.component.ts 編集
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'my-app';
columnDefs = [
{headerName: 'Class', field: 'class' },
{headerName: 'Name', field: 'name' },
{headerName: 'Power', field: 'power'}
];
rowData = [
{ class: 'Berserker', name: 'Nightingale', power: 35000 },
{ class: 'Assassin', name: 'Carmilla', power: 32000 },
{ class: 'Avenger', name: 'Jeanne alter', power: 72000 }
];
}
// app.component.html を以下に置き換え
<ag-grid-angular
style="width: 500px; height: 200px;"
class="ag-theme-balham"
[rowData]="rowData"
[columnDefs]="columnDefs"
>
</ag-grid-angular>
// トップページにgridが表示されていればOK。
本題
上記で作ったwebアプリをビルドしたいとします。
要件の1つに「1つのバンドルファイルのサイズが1MB未満であること」
があったとします。
さっそくng build --prod
しましょう。
>> ng build --prod
Date: 2019-02-07T15:49:28.086Z
Hash: 817914fa2637c6d3b8aa
Time: 66877ms
chunk {0} runtime.a5dd35324ddfd942bef1.js (runtime) 1.41 kB [entry] [rendered]
chunk {1} es2015-polyfills.12eccedba99646c7daca.js (es2015-polyfills) 56.4 kB [initial] [rendered]
chunk {2} main.00849e0d189f184e52e5.js (main) 1.01 MB [initial] [rendered]
chunk {3} polyfills.407a467dedb63cfdd103.js (polyfills) 41 kB [initial] [rendered]
chunk {4} styles.eb752abcca03cc6fe597.css (styles) 115 kB [initial] [rendered]
おやおや。バンドルされたmain.jsのサイズが1MBを超えてしまいました・・・
(ここのサイズを強調したかったがためにag-Gridのimportを挟みました。
実際は多くのベンダーライブラリをimportしますから、さらに大きくなりますね)
じゃあ --vendorChunk
オプションをつけてビジネスロジックとベンダー切り分ければいいだろ!
そうですね。ということでつけてみます。(茶番)
>> ng build --prod --vendorChunk
Date: 2019-02-07T15:58:37.946Z
Hash: 63108113a0539a610fb7
Time: 58052ms
chunk {0} runtime.a5dd35324ddfd942bef1.js (runtime) 1.41 kB [entry] [rendered]
chunk {1} es2015-polyfills.12eccedba99646c7daca.js (es2015-polyfills) 56.4 kB [initial] [rendered]
chunk {2} main.dda08de101eb4da8c253.js (main) 6.04 kB [initial] [rendered]
chunk {3} polyfills.407a467dedb63cfdd103.js (polyfills) 41 kB [initial] [rendered]
chunk {4} styles.eb752abcca03cc6fe597.css (styles) 115 kB [initial] [rendered]
chunk {5} vendor.4d52dd9a82dee508d6a2.js (vendor) 1.01 MB [initial] [rendered]
うーん。結局vendor側が1MBを超えてしまいました。
Angular-CLIの設定だけでどうにかするのは厳しそうです。
そこで今回紹介する方法を試してみましょう。(やっと本題に・・・)
// 使用する拡張モジュールをインストール
npm -D install @angular-builders/custom-webpack
npm -D install ngx-build-plus //←1行目のモジュールだけで動かなかったら入れてみて下さい
npm -D install webpack //←上に同じ。
// angular.json を編集
//"builder": "@angular-devkit/build-angular:browser",
"builder": "@angular-builders/custom-webpack:browser", //←に変更
"options": {
"customWebpackConfig": {//←追加
"path": "./extra-webpack.config.js"//←追加
}, //←追加
"outputPath": "dist/my-app",
"index": "src/index.html",
"main": "src/main.ts",
//....
// 上で指定した場所(今回ならangular.jsonと同階層)にextra-webpack.config.jsを作成し、
// 追加のwebpack詳細設定を記載する。
// 記載した部分のみがangularのbuilderに追加で反映される
// 今回はmaxSizeを1MB未満にすることでチャンクファイルのサイズ上限を調整した。
const webpack = require('webpack');
module.exports = {
output: {
filename: "[name].js" // name of the generated bundle
},
optimization: {
splitChunks: {
chunks: 'async',
minSize: 50000,
maxSize: 900000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '.',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
};
いいですね。再度ビルドしましょう。
>> ng build --prod
Date: 2019-02-07T17:06:48.049Z
Hash: bbabf25c9a51d613d39a
Time: 41291ms
chunk {0} runtime.js (runtime) 1.41 kB [entry] [rendered]
chunk {1} es2015-polyfills.d0ae3f07.js (es2015-polyfills.d0ae3f07) 56.4 kB [initial] [rendered]
chunk {2} main.31ecd969.js (main.31ecd969) 29.7 kB [initial] [rendered]
chunk {3} main.54813583.js (main.54813583) 278 kB [initial] [rendered]
chunk {4} main.65932fe3.js (main.65932fe3) 33.8 kB [initial] [rendered]
chunk {5} main.88436b06.js (main.88436b06) 191 kB [initial] [rendered]
chunk {6} main.8ff27ea1.js (main.8ff27ea1) 238 kB [initial] [rendered]
chunk {7} main.bc2eed23.js (main.bc2eed23) 29.9 kB [initial] [rendered]
chunk {8} main.d0ae3f07.js (main.d0ae3f07) 2.73 kB [initial] [rendered]
chunk {9} main.defd55b6.js (main.defd55b6) 238 kB [initial] [rendered]
chunk {10} polyfills.d0ae3f07.js (polyfills.d0ae3f07) 41 kB [initial] [rendered]
chunk {11} styles.d0ae3f07.eb752abcca03cc6fe597.css, styles.d0ae3f07.js (styles.d0ae3f07) 115 kB [initial] [rendered]
要件達成です!!おめでとうございます~
もちろんバンドルサイズの変更だけでなく、webpackでのみ設定できる項目なら、
先ほどの拡張configファイルに記載することで反映させることができます。
ビルドコマンドが特に変わらずng build --prod
だけで済むのがいいですね。
まとめ
必要なモジュールをインストールした後、しかるべき設定ファイルを編集するだけです。
個人的にはng eject
よりは楽だと思います。
Angularはバージョンアップに伴い、平気で手順変わってくるのでつらいですね。
Angular4での手順が全く役に立たなかったりとかはザラですし。寂しいですね。
Angular7の日本語ドキュメント充実に貢献出来たら幸いです。
御観覧頂きまして、ありがとうございました。