ホームページ > 記事 > ウェブフロントエンド > Angular13+ 開発モードが遅すぎる場合はどうすればよいですか?原因と解決策
Angular13 開発モードが遅すぎる場合はどうすればよいですか?以下の記事では、Angular 13 開発モードが遅すぎる原因とビルド パフォーマンスを最適化する方法を紹介しますので、お役に立てれば幸いです。
最近、7 人で高頻度の Angular プロジェクトに取り組みましたAngular 13 にアップグレードした後、その開発モードでは構築速度が遅く、リソースの使用量が多く、開発経験が貧弱です。会議で時々しか使用しない Macbook air
でビルドを起動すると (最近、在宅勤務期間中の主な生産性向上ツールになっています)、ファンがうなり声を上げ、CPU が最大値に達し、ビルドが完了した後、ホット アップデートには 1 分以上かかります。 [関連チュートリアルの推奨事項: "angular チュートリアル "]
さまざまな理由を分析してトラブルシューティングした結果、最終的にスキーマ (. /node_modules/@angular/cli/lib/config) が見つかりました。 /schema.json
) を参照し、Angular 12 リリース ドキュメント
と組み合わせると、特定の原因が特定されました。Angular 12 の大きな変更点は aot、buildOptimizer# です。 ##、
optimization およびその他のパラメーターは、デフォルト値
false から
true に変更されました。
多くのブラウザおよびサーバー ビルダー オプションのデフォルト値が変更されました。これらの変更の目的は、構成の複雑さを軽減し、新しい「デフォルトで実稼働ビルド」イニシアチブをサポートすることです。
##Angular 12 以降のデフォルトの実稼働モードは、バージョンをまたがるアップグレードにとって非常に難しいことがわかります。変更の詳細は、この提出から学ぶことができます:656f8d7
1.1 Angular 12 の遅い開発モードの問題を解決する
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "projects": { "front": { "architect": { "build": { "configurations": { "development": { "tsConfig": "./tsconfig.dev.json", "aot": false, "buildOptimizer": false, "optimization": false, "extractLicenses": false, "sourceMap": true, "vendorChunk": true, "namedChunks": true } } }, } }, "defaultProject": "front" }
Note aot
これをオンにした場合とオフにした場合、ビルド結果のパフォーマンスに多少の違いが生じる可能性があるため、特定の問題に基づいて分析する必要があります。
1.2 問題:
aot
pugこのプロジェクトでは HTML コンテンツを開発します。 がオフの場合、ビルドは正常に行われますが、オンにするとエラーが報告されます。 エラー内容と発生箇所を基にデバッガデバッグを実行すると、コンパイル結果が esModule オブジェクトになっていることがわかります。これは、
raw-loader
の使用によるもので、そのコンパイル結果はデフォルトで
モードになります。esModule
構成項目を無効にするだけです。例 (カスタム Webpack 構成については、以下の DLL 構成関連の例を参照してください): <pre class="brush:js;toolbar:false;">{
test: /\.pug$/,
use: [
{
loader: &#39;raw-loader&#39;,
options: {
esModule: false,
},
},
{
loader: &#39;pug-html-loader&#39;,
options: {
doctype: &#39;html&#39;,
},
},
],
},</pre>
2 さらなる最適化: Angular カスタム Webpack 構成 DLL は、
ライブラリを使用して実装されますが、DLL は構成されていません。 Angular
は
パラメータを提供します。これをオンにすると、package.json
内の依存関係などのパブリック リソースが独立したチャンクに抽出されます。ホット アップデート バンドルが大きすぎる、ホット アップデートが遅すぎるなどの問題は解決されましたが、依然としてメモリ使用量が高く、実際の比較テストでは webpack5 キャッシュが存在する場合、 dll モードのビルド コンパイル速度とホット アップデート速度はわずかに遅くなります。したがって、開発マシンのパフォーマンスが平均的な場合、dll を開発モードで構成すると一定のメリットが得られます。 2.1 Angular はカスタム Webpack 構成をサポートします
npm i -D @angular-builders/custom-webpackModify
構成。コンテンツ形式のリファレンス:
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "cli": { "analytics": false, "cache": { "path": "node_modules/.cache/ng" } }, "version": 1, "newProjectRoot": "projects", "projects": { "front": { "root": "", "sourceRoot": "src", "projectType": "application", "prefix": "app", "schematics": { "@schematics/angular:component": { "style": "less" } }, "architect": { "build": { "builder": "@angular-builders/custom-webpack:browser", "options": { "customWebpackConfig": { "path": "./webpack.config.js" }, "indexTransform": "scripts/index-html-transform.js", "outputHashing": "media", "deleteOutputPath": true, "watch": true, "sourceMap": false, "outputPath": "dist/dev", "index": "src/index.html", "main": "src/app-main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "./tsconfig.app.json", "baseHref": "./", "assets": [ "src/assets/", { "glob": "**/*", "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/", "output": "/assets/" } ], "styles": [ "node_modules/angular-tree-component/dist/angular-tree-component.css", "src/css/index.less" ], "scripts": [] }, "configurations": { "development": { "tsConfig": "./tsconfig.dev.json", "buildOptimizer": false, "optimization": false, "aot": false, "extractLicenses": false, "sourceMap": true, "vendorChunk": true, "namedChunks": true, "scripts": [ { "inject": true, "input": "./dist/dll/dll.js", "bundleName": "dll_library" } ] }, "production": { "outputPath": "dist/prod", "baseHref": "./", "watch": false, "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" } ], "optimization": { "scripts": true, "styles": { "minify": true, "inlineCritical": false }, "fonts": true }, "outputHashing": "all", "sourceMap": false, "namedChunks": false, "aot": true, "extractLicenses": false, "vendorChunk": false, "buildOptimizer": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular-builders/custom-webpack:dev-server", "options": { "browserTarget": "front:build", "liveReload": false, "open": false, "host": "0.0.0.0", "port": 3002, "servePath": "/", "publicHost": "localhost.gf.com.cn", "proxyConfig": "config/ngcli-proxy-config.js", "disableHostCheck": true }, "configurations": { "production": { "browserTarget": "front:build:production" }, "development": { "browserTarget": "front:build:development" } }, "defaultConfiguration": "development" }, "test": { "builder": "@angular-builders/custom-webpack:karma", "options": { "customWebpackConfig": { "path": "./webpack.test.config.js" }, "indexTransform": "scripts/index-html-transform.js", "main": "src/ngtest.ts", "polyfills": "src/polyfills.ts", "tsConfig": "./tsconfig.spec.json", "karmaConfig": "./karma.conf.js", "assets": [ "src/assets/", { "glob": "**/*", "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/", "output": "/assets/" } ], "styles": [ "node_modules/angular-tree-component/dist/angular-tree-component.css", "src/css/index.less" ], "scripts": [] } } } } }, "defaultProject": "front", "schematics": { "@schematics/angular:module": { "routing": true, "spec": false }, "@schematics/angular:component": { "flat": false, "inlineStyle": true, "inlineTemplate": false } } }
この例には多くのカスタム構成コンテンツが含まれています。主に webpack 関連の部分に注目してください。他のコンテンツは、独自のプロジェクトの特定の状況に基づいて比較および参照できます。詳細については、以前の記事の実践的な紹介も参照してください: lzw.me/a/update-to…
2.2 Angular 用の webpack dll サポートの構成
const { existsSync } = require('node:fs'); const { resolve } = require('node:path'); const webpack = require('webpack'); // require('events').EventEmitter.defaultMaxListeners = 0; /** * @param {import('webpack').Configuration} config * @param {import('@angular-builders/custom-webpack').CustomWebpackBrowserSchema} options * @param {import('@angular-builders/custom-webpack').TargetOptions} targetOptions */ module.exports = (config, options, targetOptions) => { if (!config.devServer) config.devServer = {}; config.plugins.push( new webpack.DefinePlugin({ LZWME_DEV: config.mode === 'development' }), ); const dllDir = resolve(__dirname, './dist/dll'); if ( existsSync(dllDir) && config.mode === 'development' && options.scripts?.some((d) => d.bundleName === 'dll_library') ) { console.log('use dll:', dllDir); config.plugins.unshift( new webpack.DllReferencePlugin({ manifest: require(resolve(dllDir, 'dll-manifest.json')), context: __dirname, }) ); } config.module.rules = config.module.rules.filter((d) => { if (d.test instanceof RegExp) { // 使用 less,移除 sass/stylus loader return !(d.test.test('x.sass') || d.test.test('x.scss') || d.test.test('x.styl')); } return true; }); config.module.rules.unshift( { test: /\.pug$/, use: [ { loader: 'raw-loader', options: { esModule: false, }, }, { loader: 'pug-html-loader', options: { doctype: 'html', }, }, ], }, { test: /\.html$/, loader: 'raw-loader', exclude: [helpers.root('src/index.html')], }, { test: /\.svg$/, loader: 'raw-loader', }, { test: /\.(t|les)s/, loader: require.resolve('@lzwme/strip-loader'), exclude: /node_modules/, options: { disabled: config.mode !== 'production', }, } ); // AngularWebpackPlugin,用于自定义 index.html 处理插件 const awPlugin = config.plugins.find((p) => p.options?.hasOwnProperty('directTemplateLoading')); if (awPlugin) awPlugin.pluginOptions.directTemplateLoading = false; // 兼容上古遗传逻辑,禁用部分插件 config.plugins = config.plugins.filter((plugin) => { const pluginName = plugin.constructor.name; if (/CircularDependency|CommonJsUsageWarnPlugin/.test(pluginName)) { console.log('[webpack][plugin] disabled: ', pluginName); return false; } return true; }); // console.log('[webpack][config]', config.mode, config, options, targetOptions); return config; };
DLL ビルド用の新しい webpack.dll.mjs
ファイルを作成します。内容例:
import { join } from 'node:path'; import webpack from 'webpack'; const rootDir = process.cwd(); const isDev = process.argv.slice(2).includes('--dev') || process.env.NODE_ENV === 'development'; /** @type {import('webpack').Configuration} */ const config = { context: rootDir, mode: isDev ? 'development' : 'production', entry: { dll: [ '@angular/common', '@angular/core', '@angular/forms', '@angular/platform-browser', '@angular/platform-browser-dynamic', '@angular/router', '@lzwme/asmd-calc', // more... ], }, output: { path: join(rootDir, 'dist/dll'), filename: 'dll.js', library: '[name]_library', }, plugins: [ new webpack.DllPlugin({ path: join(rootDir, 'dist/dll/[name]-manifest.json'), name: '[name]_library', }), new webpack.IgnorePlugin({ resourceRegExp: /^\.\/locale$/, contextRegExp: /moment$/, }), ], cache: { type: 'filesystem' }, }; webpack(config).run((err, result) => { console.log(err ? `Failed!` : `Success!`, err || `${result.endTime - result.startTime}ms`); });
在 angular.json
中添加 dll.js 文件的注入配置,可参考前文示例中 development.scripts
中的配置内容格式。
在 package.json
中增加启动脚本配置。示例:
{ "scripts": { "ng:serve": "node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng serve", "dll": "node config/webpack.dll.mjs", "dev": "npm run dll -- --dev && npm run ng:serve -- -c development", } }
最后,可执行 npm run dev
测试效果是否符合预期。
angular-cli
在升级至 webpack 5 以后,基于 webpack 5 的缓存能力做了许多编译优化,一般情况下开发模式二次构建速度相比之前会有大幅的提升。但是相比 snowpack
和 vite
一类的 esm no bundles 方案仍有较大的差距。其从 Angular 13
开始已经在尝试引入 esbuild
,但由于其高度定制化的构建逻辑适配等问题,对一些配置参数的兼容支持相对较为复杂。在 Angular 15
中已经可以进行生产级配置尝试了,有兴趣也可作升级配置与尝试。
更多编程相关知识,请访问:编程教学!!
以上がAngular13+ 開発モードが遅すぎる場合はどうすればよいですか?原因と解決策の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。