Apakah yang perlu saya lakukan jika mod pembangunan Angular13+ terlalu perlahan? Artikel berikut akan memperkenalkan kepada anda sebab mengapa mod pembangunan Angular 13+ terlalu perlahan dan cara mengoptimumkan prestasi binaan saya harap ia akan membantu anda!
Baru-baru ini, Angular telah berulang pada frekuensi tinggi selama tujuh tahun Selepas projek dinaik taraf kepada Angular 13, mod pembangunannya mempunyai kelajuan pembinaan yang perlahan, penggunaan sumber yang tinggi dan pengalaman pembangunan yang lemah. Apabila saya melancarkan binaan pada Macbook air
yang saya hanya gunakan sekali-sekala untuk mesyuarat (dan baru-baru ini menjadi alat produktiviti utama saya semasa bekerja dari rumah), peminatnya berputar dan CPU dimaksimumkan, dan apabila binaan selesai, A kemas kini panas mengambil masa lebih daripada satu minit. [Tutorial berkaitan yang disyorkan: "tutorial sudut"]
Selepas menganalisis dan menyelesaikan pelbagai punca, masalah itu akhirnya ditemui dalam skema (angular.json
) ./node_modules/@angular/cli/lib/config/schema.json
, dan kemudian Menggabungkan dokumen keluaran Angular 12 , sebab khusus terletak: Perubahan besar dalam Angular 12 adalah untuk menukar parameter seperti aot
, buildOptimizer
dan optimization
daripada nilai lalai false
kepada true
.
Beberapa pilihan penyemak imbas dan pembina pelayan telah ditukar nilai lalainya. Matlamat perubahan ini adalah untuk mengurangkan kerumitan konfigurasi dan menyokong inisiatif "binaan pengeluaran secara lalai".
Anda dapat melihat bahawa mod pengeluaran lalai selepas Angular 12 agak rumit untuk peningkatan versi silang. Kita boleh mengetahui tentang butiran perubahan daripada komit ini: 656f8d7
Penyelesaian berada dalam development
Lumpuhkan item konfigurasi yang berkaitan dengan mod pengeluaran dalam konfigurasi. Contoh:
{ "$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" }
Nota: aot
Apabila ia dihidupkan dan dimatikan, mungkin terdapat beberapa perbezaan dalam prestasi hasil binaan, yang perlu dianalisis berdasarkan masalah khusus.
aot
, pug
menyusun dan melaporkan ralat Dalam projek ini, pug
digunakan untuk membangunkan kandungan html. Apabila aot
dimatikan, binaan adalah normal, tetapi apabila dihidupkan, ralat akan dilaporkan.
Lakukan penyahpepijatan berdasarkan kandungan ralat dan lokasi Anda boleh melihat bahawa hasil kompilasi ialah objek esModule. Ini disebabkan oleh penggunaan raw-loader
, hasil kompilasi lalai kepada mod esModule
, cuma lumpuhkan esModule
item konfigurasi. Contoh (konfigurasi pek web tersuai boleh merujuk kepada contoh berkaitan konfigurasi dll di bawah):
{ test: /\.pug$/, use: [ { loader: 'raw-loader', options: { esModule: false, }, }, { loader: 'pug-html-loader', options: { doctype: 'html', }, }, ], },
projek ini Di sana adalah keperluan untuk konfigurasi webpack
tersuai dalam pembinaan projek, dan pustaka @angular-builders/custom-webpack
digunakan untuk melaksanakannya, tetapi dll tidak dikonfigurasikan.
Angular
menyediakan parameter vendorChunk
Mendayakannya akan mengekstrak sumber awam seperti kebergantungan dalam package.json
ke dalam ketulan bebas Ia boleh menyelesaikan masalah berkas kemas kini panas yang terlalu besar disebabkan saiz yang berlebihan . Walau bagaimanapun, masih terdapat penggunaan memori yang tinggi, dan dalam ujian perbandingan sebenar, dengan kehadiran cache webpack5, kelajuan binaan dan penyusunan serta kelajuan kemas kini panas adalah lebih perlahan daripada yang dalam mod dll. Oleh itu, apabila prestasi mesin pembangunan adalah sederhana, mengkonfigurasi dll dalam mod pembangunan akan membawa faedah tertentu.
Mula-mula anda perlu mengkonfigurasi sokongan binaan untuk konfigurasi pek web tersuai. Jalankan arahan berikut untuk menambah kebergantungan:
npm i -D @angular-builders/custom-webpack
Ubah suai konfigurasi angluar.json
. Rujukan format kandungan:
{ "$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 } } }
Contoh ini melibatkan banyak kandungan konfigurasi tersuai Anda harus memberi perhatian terutamanya kepada bahagian yang berkaitan dengan webpack boleh dibandingkan dan dirujuk berdasarkan situasi khusus projek anda sendiri. Untuk beberapa butiran, sila rujuk pengenalan praktikal dalam artikel sebelumnya ini: lzw.me/a/update-to…
Buat fail webpack.config.js
baharu. Rujukan kandungan:
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; };
Buat fail webpack.dll.mjs
baharu untuk pembinaan dll. Contoh kandungan:
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
中已经可以进行生产级配置尝试了,有兴趣也可作升级配置与尝试。
更多编程相关知识,请访问:编程教学!!
Atas ialah kandungan terperinci Apakah yang perlu saya lakukan jika mod pembangunan Angular13+ terlalu perlahan? Punca dan penyelesaian. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!