久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網
最全最豐富的資訊網站

Angular13+ 開發模式太慢怎么辦?原因與解決方法介紹

Angular13+ 開發模式太慢怎么辦?下面本篇文章給大家介紹一下Angular 13+ 開發模式太慢的原因與構建性能優化的方法,希望對大家有所幫助!

Angular13+ 開發模式太慢怎么辦?原因與解決方法介紹

1 Angular 13+ 開發模式太慢的原因與解決

近期在某個高頻迭代七年的 Angular 項目升級至 Angular 13 后,其開發模式的構建速度慢、資源占用高,開發體驗相當差。在一臺僅在開會時偶爾使用的 Macbook air(近期居家辦公期間轉換為了主要生產力工具) 中啟動構建時,它的風扇會呼呼作響,CPU 負荷被打滿,而在構建完成后,熱更新一次的時間在一分鐘以上?!鞠嚓P教程推薦:《angular教程》】

在經過各種原因分析與排查后,最終在 angular.json 的 schema(./node_modules/@angular/cli/lib/config/schema.json) 中發現了問題,再結合 Angular 12 release 文檔定位到了具體原因: Angular 12 一個主要的改動是將 aot、buildOptimizer、optimization 等參數由默認值 false 改為了 true

A number of browser and server builder options have had their default values changed. The aim of these changes is to reduce the configuration complexity and support the new "production builds by default" initiative.

可以看到 Angular 12 后的默認生產模式,對于跨版本升級來說是比較坑爹的。我們可以從這個提交中了解變動細節:656f8d7

1.1 解決 Angular 12+ 開發模式慢的問題

解決辦法則是在 development 配置中禁用生產模式相關的配置項。示例:

{   "$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" }
登錄后復制

需注意 aot 開啟與關閉時,在構建結果表現上可能會有一些差異,需視具體問題而分析。

1.2 問題:開啟 aotpug 編譯報錯

該項目中使用 pug 開發 html 內容。關閉 aot 時構建正常,開啟后則會報錯。

根據報錯內容及位置進行 debugger 調試,可以看到其編譯結果為一個 esModule 的對象。這是由于使用了 raw-loader,其編譯結果默認為 esModule 模式,禁用 esModule 配置項即可。示例(自定義 webpack 配置可參考下文的 dll 配置相關示例):

{   test: /.pug$/,   use: [     {       loader: 'raw-loader',       options: {         esModule: false,       },     },     {       loader: 'pug-html-loader',       options: {         doctype: 'html',       },     },   ], },
登錄后復制

2 進一步優化:Angular 自定義 webpack 配置 dll 支持

該項目項目構建上有自定義 webpack 配置的需求,使用了 @angular-builders/custom-webpack 庫實現,但是沒有配置 dll。

Angular 提供了 vendorChunk 參數,開啟它會提取在 package.json 中的依賴等公共資源至獨立 chunk 中,其可以很好的解決熱更新 bundles 過大導致熱更新太慢等的問題,但仍然存在較高的內存占用,而且實際的對比測試中,在存在 webpack5 緩存的情況下,其相比 dll 模式的構建編譯速度以及熱更新速度都稍微慢一些。故對于開發機器性能一般的情況下,給開發模式配置 dll 是會帶來一定的收益的。

2.1 Angular 支持自定義 webpack 配置

首先需要配置自定義 webpack 配置的構建支持。執行如下命令添加依賴:

npm i -D @angular-builders/custom-webpack
登錄后復制

修改 angluar.json 配置。內容格式參考:

{   "$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 支持

新建 webpack.config.js 文件。內容參考:

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; };
登錄后復制

新建 webpack.dll.mjs 文件,用于 dll 構建。內容示例:

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 測試效果是否符合預期。

3 小結

angular-cli 在升級至 webpack 5 以后,基于 webpack 5 的緩存能力做了許多編譯優化,一般情況下開發模式二次構建速度相比之前會有大幅的提升。但是相比 snowpackvite 一類的 esm no bundles 方案仍有較大的差距。其從 Angular 13 開始已經在嘗試引入 esbuild,但由于其高度定制化的構建邏輯適配等問題,對一些配置參數的兼容支持相對較為復雜。在 Angular 15 中已經可以進行生產級配置嘗試了,有興趣也可作升級配置與嘗試。

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
欧美国产视频| 日韩av午夜在线观看| 麻豆国产一区| 免费在线观看一区| 国产精品嫩模av在线| 国产亚洲久久| 精品美女久久| 欧产日产国产精品视频| 99久久亚洲精品蜜臀| 免费久久精品| 丝袜脚交一区二区| 日韩欧美中文字幕一区二区三区 | 国产日韩电影| 成人免费电影网址| 国户精品久久久久久久久久久不卡| 91精品蜜臀一区二区三区在线 | 久久免费国产| 99国产精品久久久久久久成人热| 久久国产精品久久w女人spa| 日韩精品一级| 国产精品xvideos88| 日韩伦理福利| 国产精品女主播一区二区三区| 久久亚洲国产精品一区二区| 亚洲人亚洲人色久| 久久这里只有| 欧美成人午夜| 亚洲精品麻豆| 久久久久九九精品影院| 欧美成a人国产精品高清乱码在线观看片在线观看久| 久久婷婷亚洲| 蜜桃av一区二区三区电影| 欧美一区二区三区久久| 成午夜精品一区二区三区软件| 欧美va天堂在线| 日韩高清欧美激情| 国产中文字幕一区二区三区| 蜜桃视频欧美| 欧美一区二区三区久久| 日韩精品不卡一区二区| 丝袜a∨在线一区二区三区不卡| 久久国产三级精品| 日韩精品欧美激情一区二区| 亚洲一区二区日韩| 捆绑调教美女网站视频一区| 亚洲经典在线| 久久免费福利| 蜜臀精品久久久久久蜜臀 | 日本一区二区三区中文字幕| 高清在线一区| 视频一区视频二区中文字幕| 老司机免费视频一区二区三区| 欧美日韩中文字幕一区二区三区| 一本综合精品| 麻豆理论在线观看| 中文不卡在线| 性欧美videohd高精| 一二三区精品| 日韩一区电影| 国产乱码精品一区二区三区四区 | 亚洲精品成人| 精品一区二区三区中文字幕在线| 美日韩精品视频| 久久久久九九精品影院| 99亚洲视频| 岛国av免费在线观看| 亚洲三区欧美一区国产二区| 日本综合字幕| 久久精品72免费观看| 婷婷亚洲五月色综合| 国产精品99久久免费观看| 99国产精品久久久久久久成人热 | 91视频精品| 欧美精品中文字幕亚洲专区| 欧美日韩国产在线观看网站 | 精品视频高潮| 日韩精品第二页| 欧美不卡高清| 四季av一区二区凹凸精品| 日韩av午夜在线观看| 国产一级久久| 九一国产精品| 91亚洲人成网污www| 国产欧美日韩一区二区三区在线| 在线亚洲自拍| 久久精品91| 都市激情国产精品| 国产毛片久久久| 热久久久久久久| 亚洲小说欧美另类婷婷| zzzwww在线看片免费| 国产精品国码视频| 日韩高清电影一区| 一二三区精品| 久久xxxx| 性欧美长视频| 欧美成人高清| 亚洲成人av观看| 国产一区二区三区四区五区传媒| 91精品福利观看| 亚洲影视一区二区三区| 国产一区二区精品| 伊人影院久久| 国产麻豆久久| 日韩欧美国产精品综合嫩v| 老牛国内精品亚洲成av人片| 国产欧美一区二区色老头| 日韩欧美久久| 午夜精品福利影院| 亚洲三级精品| 亚洲精品观看| 日韩一区二区三免费高清在线观看| 香蕉久久夜色精品国产| 日韩一级精品| 国产精品毛片| 久久成人国产| 久久国产66| 亚洲区欧美区| 少妇高潮一区二区三区99| 喷白浆一区二区| 亚洲视频国产精品| 综合干狼人综合首页| 日韩精品一区第一页| 蜜桃久久久久久久| 香蕉久久久久久| 日韩激情中文字幕| 婷婷五月色综合香五月| 日本久久一区| 国产乱码精品一区二区三区亚洲人| 国产精品久久久久久模特| 欧美国产亚洲精品| 高清av不卡| 亚洲天堂黄色| 亚洲激情黄色| 亚洲欧洲专区| 日韩av不卡一区二区| 久久国产尿小便嘘嘘| 国产精品传媒麻豆hd| 精品欧美视频| 日韩三区免费| 最新日韩欧美| 婷婷精品久久久久久久久久不卡| 日韩av影院| 丁香婷婷久久| 免费国产自久久久久三四区久久 | 热三久草你在线| 国产一在线精品一区在线观看| 夜夜嗨一区二区| 日本aⅴ免费视频一区二区三区| 青草av.久久免费一区| 麻豆精品久久| 亚洲第一区色| 日韩精品一区二区三区av | 欧美日韩99| 国产精品久久久久久久久久10秀 | 久久福利精品| 国产精品自拍区| 成人精品亚洲| 亚洲精品大全| 久久精品日韩欧美| 国产一区二区三区自拍| 免费成人在线影院| 国产精品一区二区三区av麻| 成人欧美一区二区三区的电影| 欧美日韩国产一区精品一区| 日韩动漫一区| 久久天堂成人| 日本不卡一二三区黄网| 国产精品nxnn| 香蕉精品久久| 一区二区高清| 久久久久久一区二区| 石原莉奈一区二区三区在线观看| 国产精品尤物| 国内精品福利| 国产欧美丝祙| 伊人久久亚洲美女图片| 欧美精品99| 在线亚洲激情| 精品国产亚洲一区二区在线观看| 在线视频精品| 捆绑调教美女网站视频一区| 免费av一区| 国产欧美一区二区精品久久久| 日韩高清不卡| 国产午夜精品一区在线观看| 99精品国产一区二区三区| 深夜福利亚洲| 成人久久一区| 国产精一区二区| 99国产精品自拍| 高清av一区| 日韩精品一区二区三区免费视频 | 综合精品一区| 在线天堂资源www在线污| 日本在线一区二区三区| 999国产精品视频| 欧美aⅴ一区二区三区视频| 亚洲一区免费| 国产精品专区免费|