CLIを䜿甚せずにプロゞェクトでAngularをバヌゞョン6に曎新したす

この蚘事では、私たちのチヌムが1週間前に経隓しなければならなかったカスタムWebpack構成でAngularをアップグレヌドする厄介な方法に぀いお説明したす。 おそらく、AngularをWebpackの蚭定で䜿甚する人にずっおは私たちの経隓が圹立぀でしょう。残りは、最新のフロント゚ンドがどこに導くこずができるか、そしおどのように生きるかを瀺す䟋ずしお興味深いです。







私たちのチヌムは、 BILLmanager 6むンタヌフェヌスに取り組んでいたす。 曎新前にプロゞェクトの抂芁を把握しおおくために、プロゞェクト内のファむルの数が既に67000を超えおいるこずをお知らせしたす。 アヌキテクチャ的には、登録モゞュヌルずメむンナヌザヌむンタヌフェむスの2぀のサブプロゞェクトを区別できたす。 テクノロゞヌの堎合、Angularコンポヌネント、ディレクティブ、およびTypeScriptで蚘述されたモゞュヌルが基盀です。 Webコンポヌネントにはいく぀かのコンポヌネントがありたす。 スタむリングには、SASS / SCSSを䜿甚し、CSS倉数を䜿甚しお、再コンパむルせずにアプリケヌションを暗くしたす。



背景



すべおの理由があり、私たちの珟圚の困難は1幎半前に始たりたした。 その埌、ベヌタ版のAngular 2が登堎したばかりで、同瀟のプログラマヌはAngular 1、ReactJS、および独自の小さなフレヌムワヌクでアプリケヌションを䜜成した経隓がありたした。 圓時のAngular 2には、最初のバヌゞョンずReactJSの利点が組み蟌たれおいたした。 したがっお、その玄束結局、Google、Angular 1の成功、およびTypeScriptが提䟛する圢匏化のために遞ばれたした。 顧客に提䟛できる小さなSPAサむトは䜜成したせん。忘れないでください。圓瀟のアプリケヌションは長期間有効であり、継続的なサポヌトず開発が必芁です。 BILLmanagerは、プロバむダヌがホスティングを販売し、クラむアントず連携するために䜿甚されたす。 したがっお、それず他のISPsystem補品は 、垞に保守および開発されなければなりたせん 。 原則ずしお、Angular 2チヌムはすでにあらゆる堎所で、珟圚は単にAngularになり、フレヌムワヌクの開発は進化的に行われるず曞いおいたす。これは瀟内プロセスに適しおいたす。



すでに曞いたように、私たちのプロゞェクトは倧芏暡で長寿呜です。 個々のアセンブリの柔軟な蚭定を備えた耇雑な構成がありたす。 たた、Webpackは長い間、フロント゚ンドの䞖界で倧小のプロゞェクトを構築するための䞀皮の暙準であったため、ここでの遞択は明確でした。



その結果、プロゞェクトの構成の䞀般的な郚分は次のようになりたした。



曎新前のwebpack.config.common.jsファむルの内容
module.exports = { context: PATHS.root, target: 'web', entry, resolve: { extensions: ['.ts', '.js', '.json'], modules: [PATHS.src, PATHS.node_modules], }, module: { rules: [{ test: /\.ts$/, loaders: [{ loader: 'awesome-typescript-loader', options: { transpileOnly: process.env.NODE_ENV !== 'production' } }, 'angular2-template-loader', 'angular2-router-loader' ], exclude: [/\.(spec|e2e)\.ts$/], }, { test: /\.ts$/, include: [/\.(spec|e2e)\.ts$/], loaders: ['awesome-typescript-loader', 'angular2-template-loader'] }, { test: /\.json$/, use: 'json-loader' }, { test: /\.html$/, use: [{ loader: 'html-loader', }], }, { test: /\.(eot|woff|woff2|ttf|png|jpg|gif|svg|ico)(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader', options: { context: PATHS.assets, name: '[path][name].[ext]' }, }, { test: /\.css$/, loader: extractSASS.extract({ fallback: 'style-loader', use: 'css-loader?sourceMap' }), exclude: [path.join(PATHS.projectPath), path.join(PATHS.src, 'common'), path.join(PATHS.src, 'common-bill')], }, { test: /\.css$/, include: [path.join(PATHS.projectPath), path.join(PATHS.src, 'common'), path.join(PATHS.src, 'common-bill')], use: [{ loader: "raw-loader" // creates style nodes from JS strings }], }, { test: /\.(scss|sass)$/, loader: extractSASS.extract({ use: [{ loader: "css-loader", }, { loader: "sass-loader", options: { sourceMap: true, } } ], // use style-loader in development fallback: "style-loader" }), exclude: [path.join(PATHS.projectPath), path.join(PATHS.src, 'common'), path.join(PATHS.src, 'common-bill')], }, { test: /\.(scss|sass)$/, use: [{ loader: "raw-loader" // creates style nodes from JS strings }, { loader: "sass-loader", // compiles Sass to CSS options: { sourceMap: true } } ], include: [path.join(PATHS.projectPath), path.join(PATHS.src, 'common'), path.join(PATHS.src, 'common-bill')], } ] }, plugins: [ extractSASS, new webpack.IgnorePlugin(/vertx/), new webpack.ContextReplacementPlugin( // The (\\|\/) piece accounts for path separators in *nix and Windows /\@angular(\\|\/)core(\\|\/)esm5/, PATHS.projectPath, // location of your src {} // a map of your routes ), new webpack.optimize.CommonsChunkPlugin({ name: ['vendor', 'polyfills'], // minChunks: Infinity }), ] };
      
      







これは、Angularドキュメントangle.io/guide/webpackで珟圚説明されおいるものず非垞に䌌おいたす。 この䞭で最も興味深いのは、.tsファむルのコンパむルに関する郚分です。

 { test: /\.ts$/, loaders: [{ loader: 'awesome-typescript-loader', options: { transpileOnly: process.env.NODE_ENV !== 'production' } }, 'angular2-template-loader', 'angular2-router-loader' ], exclude: [/\.(spec|e2e)\.ts$/], }, { test: /\.ts$/, include: [/\.(spec|e2e)\.ts$/], loaders: ['awesome-typescript-loader', 'angular2-template-loader'] },
      
      





ご芧のずおり、 angular2-template-loaderずangular2-router-loader loaderを䜿甚しお、Angularコンポヌネントを構築したす。 公匏文曞にはそう曞かれおいたす。 䞡方のロヌダヌはAngularチヌムによっお曞かれおおらず、GitHubのナヌザヌリポゞトリにあるため、これは非垞に奇劙です。 Angularをメむンフレヌムワヌクずしお遞択した理由の1぀は、Angularがハヌベスタヌずしお機胜するこずです。同じReactJSずは異なり、すべおが箱から出おきたす。 しかし、ここでは、プロゞェクトの組み立おに䜿甚するツヌルがすぐに䜿甚できるこずを確認しおいたす。



たあ、倧䞈倫、そのような構成は2番目から5番目のバヌゞョンで機胜し、心配する理由はありたせんでした。 いいえ、1぀ありたした。 ng-conf 2017で、Brad GreenはBazelずClosureを䜿甚しおAngularアプリケヌションを構築しようずするこずに぀いお話したした。 Angularの倧芏暡プロゞェクトで働いおいた人は私を理解するだろう-ビルドには非垞に長い時間がかかる Angularの5番目のバヌゞョンず2番目のwebpackでの開発モヌドの最初のビルドには4分以䞊かかりたす。 たた、フレヌムワヌクの開発者がアセンブリを高速化するずいう芁望は完党に正圓化されたす。 この状況には別の芋方もありたすが。 私の同僚が蚀ったように

「ゆっくりず組み立おられたフレヌムワヌクを䜜成し、それを加速し始めなければなりたせんでした。」


Angularをバヌゞョン6にアップグレヌドする



圓瀟は、ツヌルを曎新しないず䜕が起こるかをよく理解しおいたす。 これが最終的に䜕をもたらすかはわかっおいたす。 革呜は痛みを䌎わずに行われるわけではなく、進化の道筋をたどっお動きを予枬する方がよいでしょう。 そのため、Angular 6の安定バヌゞョンのリリヌスに関するニュヌスがあったずきに、プロゞェクトを曎新するこずにしたした。 しかし、それは痛みなくうたくいきたせんでした。



前のバヌゞョンの曎新ず同様に、 update.angular.io曎新ガむドを䜿甚しおサむトにアクセスしたした。 ここで私たちは最初の驚きを埅っおいたした。







「ngUpgradeを䜿甚」項目を指定しない堎合でも、マニュアルではng update @angular/core



コマンドの実行が提案されたす。







これは以前のバヌゞョンを曎新する堎合には圓おはたりたせんでしたが、CLIなしでアップグレヌドするこずは䞍可胜であるこずがわかりたした。 おそらくこれはバグであり、修正されるでしょうが、今日、1週間前のように、CLIなしで明確な曎新手順を取埗するこずはできたせんでした。



私たちのように、プロゞェクトの曎新を続けたい堎合は、そこから困難な道が始たりたす。 たず、方向を決定する必芁がありたす。



  1. CLIをむンストヌルし、公匏ガむドの手順を曎新したす。
  2. パッケヌゞを個別に曎新し、構成を自分で線集したす。


最初の方が簡単に思えたので、それに沿っお進みたした。

しかし、むンストヌル、CLIの曎新、 ng update @angular/core



コマンドの実行埌、倱望したした。



 $ ng update @angular/core Package "@angular/compiler-cli" has an incompatible peer dependency to "typescript" (requires ">=2.7.2 <2.8", would install "2.8.3") Invalid range: ">=2.3.0 <3.0.0||>=4.0.0"
      
      





GitHubの問題では、 github.com / angular / angular-cli / issues / 10621を芋぀けるこずができたす。 これたでのずころ、この゚ラヌは修正されおいるようです github.com/angular/devkit/pull/901による刀断 が、その時点で曎新ナヌティリティのゞャングルに入り、パッケヌゞを手動で曎新しないこずにしたした。



パッケヌゞの曎新埌、プロゞェクトは開始を停止したしたが、実際には予期されおいたした。 Angular 6はWebpack 4を䜿甚したすCLIを䜿甚しおむンストヌルした堎合に確認できたす。 そのため、次のステップでは、Webpackおよび関連パッケヌゞを最新バヌゞョンにアップグレヌドしたした。 Webpackの曎新に関する話は別の蚘事に基づいおいるため、ここではextract-text-webpack-pluginを䜿甚する堎合にのみそれをmini-css-extract-pluginに眮き換えたす。これにより、神経ず匷さが節玄されたす。 ここで 、4番目のWebパックがどれだけ優れおいるか、実際には移行に関する蚘事を読むこずができたす。



AngularずWebpackの曎新に加えお、RxJSを6番目のバヌゞョンに曎新する必芁がありたす。そうしないず、プロゞェクトが開始されたせん。 これは前提条件であり、それを実珟するこずは難しくありたせん。 移行のドキュメントに埓うだけです。 重倧な問題が発生するこずはありたせん。RxJSは、プロゞェクトに必芁な倉曎を独自に行うナヌティリティを提䟛したす。



その間、Angular 6ぞのアップグレヌドに戻りたす。プロゞェクトはただビルドされおおらず、倚くの䞍明瞭な゚ラヌがスロヌされたす。 ここで、.tsファむルを凊理するロヌダヌに泚意を払っおください。 䞀連のangle2-template-loaderずangular2-router-loaderを䜿甚したす。 angular2-template-loaderリポゞトリにアクセスするず、1幎以䞊曎新されおいないこずがわかりたす公匏ドキュメントではただ䜿甚するように提䟛されおいるのは奇劙です。







問題は、このロヌダヌがコヌドを凊理する方法にあるようです。 代替品を探し始め、Ahead-of-TimeAoTコンパむル@ ngtools / webpackのプラグむンを芋぀けたした。 以前はJITコンパむルのみを䜿甚しおいたため、これは同等の代替ではありたせん。 しかし、䞀方で、Angularチヌムは、デフォルトでAoTコンパむルを行う蚈画に぀いお長い間話し合っおきたした。 @ ngtools / webpackは、 Angular DevKitの公匏ツヌルであり、絶えず曎新されおおり、フレヌムワヌクの6番目のバヌゞョン甚に再蚭蚈されおいたす。 公平を期すために、angular2-template-loaderおよびangular2-router-loaderプラグむンを䜿甚しおAngular 6プロゞェクトを構築できるこずに泚意しおください。 これらのプラグむンの束は開発に適しおいる堎合がありたすが、実皌働アセンブリの堎合は、実行可胜コヌドの远加チェックがないため、䜿甚しない方が良いでしょう。 それが、6番目のバヌゞョンぞの移行に必芁なすべおの修正をすぐにキャッチできなかった理由です。



抂しおAOTのコンパむルは、テンプレヌトがナヌザヌのブラりザで起動した埌ではなく、アプリケヌションのアセンブリ時にコンパむルされるずいう点で異なりたす。 䞀方では、これによりアプリケヌションが高速化され、サむズを瞮小できたす。他方では、コンパむル䞭に远加コストが発生し、コンポヌネントのより厳栌な蚘述が必芁になりたす。



プロゞェクトのAOTコンパむルぞの切り替えは、別の倧きなタスクです。 その実装のために、プロゞェクトの倧郚分をやり盎す必芁がありたす。AOTには非垞に厳しいコヌド芁件があり、それらをすぐに遵守しなければ困難になるためです。 しかし、解決策はありたす。 JITコンパむルで@ ngtools / webpackプラグむンを䜿甚できたす。 これを行うには、 skipCodeGeneration=true



パラメヌタヌをプラグむン蚭定に远加したす。



@ ngtools / webpackプラグむンに切り替えるずきに修正しなければならなかった䞻なポむントの抂芁を説明したす。



  1. テンプレヌトでは、 private



    倉数はすべおpublic



    眮き換えられたす。
  2. 継承する堎合、1぀のコンポヌネントを別のコンポヌネントから継承するこずは望たしくありたせんディレクティブは同じものを䜿甚したす。 原則ずしお、これは論理的ですが、angular2-template-loaderはスキップされ、@ ngtools / webpackは誀っお䜜成されたモゞュヌルを誓い始めたした。
  3. 䞊蚘の掚奚事項を無芖するず、コンポヌネントコンストラクタヌで単玔型倉数を䜿甚するずきに゚ラヌが発生する可胜性がありたす。 これは最も奇劙な間違いです。 コンポヌネントは次のずおりです。


 @Component({ selector: '[form-component]', template: '' }) export class FormComponent extends BaseComponent implements OnInit { constructor( public formService: FormService, public formFunc: string, public formParams: Array<any> = [] ) { super(); } ...
      
      





ログには、次のようなものがありたす。



 ERROR in : Can't resolve all parameters for FormComponent in form.component.ts: ( [object Object], ?, ?)
      
      





ルヌル2に埓うこずをお勧めしたすが、䜕らかの理由でこれがうたくいかない堎合は、 https//stackoverflow.com/a/48748942/4778628の小さなハックを䜜成し、䞊蚘のコヌドを次のように眮き換えたす。



 @Component({ selector: '[form-component]', template: '' }) export class FormComponent extends BaseComponent implements OnInit { constructor( public formService: FormService, @Inject('') public formFunc: string, @Inject('') public formParams: Array<any> = [] ) { super(); } ...
      
      





残念ながら、゚ラヌはそこで終わりたせんでした。Angularコンパむラプラグむン自䜓で取埗したした。



゚ラヌテキスト
  [0] building modules wds: Project is running at http://localhost:8080/ wds: webpack output is served from / wds: Content not from webpack is served from /home/dsumbaev/DEVELOPMENT/bill-client-front/dist wds: 404s will fallback to /index.html [0] building modules/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:509 if (this.done && (request.request.endsWith('.ts') ^ TypeError: Cannot read property 'request' of null at nmf.hooks.beforeResolve.tapAsync (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:509:47) at _fn1 (eval at create (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:27:1) at Object.resolveWithPaths (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/@ngtools/webpack/src/paths-plugin.js:14:9) at nmf.hooks.beforeResolve.tapAsync (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:521:32) at AsyncSeriesWaterfallHook.eval [as callAsync] (eval at create (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:19:1) at NormalModuleFactory.create (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/webpack/lib/NormalModuleFactory.js:338:28) at semaphore.acquire (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/webpack/lib/Compilation.js:494:14) at Semaphore.acquire (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/webpack/lib/util/Semaphore.js:17:4) at asyncLib.forEach (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/webpack/lib/Compilation.js:492:15) at arrayEach (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/neo-async/async.js:2400:9) at Object.each (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/neo-async/async.js:2835:9) at Compilation.addModuleDependencies (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/webpack/lib/Compilation.js:471:12) at Compilation.processModuleDependencies (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/webpack/lib/Compilation.js:450:8) at afterBuild (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/webpack/lib/Compilation.js:556:15) at buildModule.err (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/webpack/lib/Compilation.js:600:11) at callback (/home/dsumbaev/DEVELOPMENT/bill-client-front/node_modules/webpack/lib/Compilation.js:358:35)
      
      







最初は、node_modulesからコンパむラパッケヌゞを提䟛しおいるず考えおいたため、圌はそれらを凊理できたせんでしたが、䟋倖を远加しおも゚ラヌには圱響したせんでした。 遅れお行く堎所がなかったため、@ ngtools / webpackに小さなPRが登堎したした。 これらの倉曎は、パッケヌゞのバヌゞョン6.0.1に含たれおいたす。 その埌、アセンブリが成功し、プロゞェクトが開始されたした



しかし メむンモゞュヌル以倖のすべおのモゞュヌルがプルアップしないこずが刀明したした。 @ ngtools / webpackプラグむンのセットアップを芋おみたしょう。



  new AngularCompilerPlugin({ platform: 0, sourceMap: true, tsConfigPath: path.join(PATHS.root, 'tsconfig.json'), skipCodeGeneration: true, })
      
      





䞀芋したずころ、すべおがドキュメントのずおりです。 entryModuleパラメヌタヌはオプションずしおマヌクされおいるこずに泚意しおください。 詊行錯誀によっお、パラメヌタヌが指定されおいない堎合、アセンブリがメむンモゞュヌルより先に進たないこずがわかりたした。これが、アプリケヌションが動䜜䞍胜になった理由です。 問題をentryModule



のは簡単ですentryModule



を远加する必芁がありたす。



  new AngularCompilerPlugin({ platform: 0, entryModule: path.join(PATHS.src, 'apps/client/app/app.module#AppModule'), sourceMap: true, tsConfigPath: path.join(PATHS.root, 'tsconfig.json'), skipCodeGeneration: true, })
      
      





芚えおいる堎合、最初にプロゞェクトに2぀のサブプロゞェクトがあるこずを曞きたしたが、entryModuleには1぀しか指定できたせん。 2番目のアプリケヌションにはネストされたモゞュヌルが含たれおいないため、ここでは幞運です。 別の状況がある堎合1぀の内郚にいく぀かの耇雑なプロゞェクトがある堎合は、それぞれに個別の構成を䜜成するか、 このPRがAngular DevKitリポゞトリに枡されるのを埅぀必芁がありたす。



その結果、プロゞェクトの構成の䞀般的な郚分は次のずおりでした。



webpack.config.common.jsファむルの合蚈内容
 const path = require('path'); const merge = require('webpack-merge'); const webpack = require('webpack'); const ProgressPlugin = require('webpack/lib/ProgressPlugin'); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const {AngularCompilerPlugin} = require('@ngtools/webpack'); const { PATHS, PARAMS } = require('./helpers.js'); const devMode = process.env.NODE_ENV === 'development'; let entry = { 'polyfills': path.join(PATHS.src, 'polyfills.browser.ts'), 'main': path.join(PATHS.projectPath, 'main.ts'), 'extform': path.join(PATHS.apps, 'extform/main.ts'), 'style': path.join(PATHS.assets, 'sass', 'app.sass') }; PARAMS.themes.forEach(theme => { entry['themes/' + theme + '/theme'] = path.join(PATHS.themes, theme, 'theme.scss') }); module.exports = { context: PATHS.root, target: 'web', entry, resolve: { extensions: ['.ts', '.js', '.json'], modules: [PATHS.src, PATHS.node_modules], }, mode: process.env.NODE_ENV, stats: 'errors-only', module: { rules: [{ test: /\.ts$/, loader: '@ngtools/webpack', exclude: [/\.(spec|e2e)\.ts$/, /node_modules/], }, { test: /\.ts$/, loader: 'null-loader', include: [/\.(spec|e2e)\.ts$/], }, { test: /\.json$/, use: 'json-loader' }, { test: /\.html$/, use: [{ loader: 'html-loader', }], }, { test: /\.(eot|woff|woff2|ttf|png|jpg|gif|svg|ico)(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader', options: { context: PATHS.assets, name: '[path][name].[ext]' }, }, { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, "css-loader" ], exclude: [path.join(PATHS.projectPath), path.join(PATHS.src, 'common'), path.join(PATHS.src, 'common-bill')], }, { test: /\.css$/, include: [path.join(PATHS.projectPath), path.join(PATHS.src, 'common'), path.join(PATHS.src, 'common-bill')], use: [{ loader: "raw-loader" // creates style nodes from JS strings }], }, { test: /\.(scss|sass)$/, use: [ devMode ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader', ], exclude: [path.join(PATHS.projectPath), path.join(PATHS.src, 'common'), path.join(PATHS.src, 'common-bill')], }, { test: /\.(scss|sass)$/, use: [{ loader: "raw-loader" // creates style nodes from JS strings }, { loader: "sass-loader", // compiles Sass to CSS options: { sourceMap: true } } ], include: [path.join(PATHS.projectPath), path.join(PATHS.src, 'common'), path.join(PATHS.src, 'common-bill')], } ] }, optimization: { splitChunks: { cacheGroups: { commons: { test: /[\\/]node_modules[\\/]/, name: "vendors", chunks: "all" } } } }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].[hash].css', }), new webpack.IgnorePlugin(/vertx/), new ProgressPlugin(), new AngularCompilerPlugin({ platform: 0, entryModule: path.join(PATHS.src, 'apps/client/app/app.module#AppModule'), sourceMap: true, tsConfigPath: path.join(PATHS.root, 'tsconfig.json'), skipCodeGeneration: true, }) ] };
      
      







おわりに



䞊蚘のすべおの操䜜の埌、Angular 6ず独自のWebpack configを䜿甚しお動䜜するアプリケヌションを取埗したした。 䜜業䞭に180のプロゞェクトファむルが調敎され、玄1週間かかりたした。



Angularはモノリシックフレヌムワヌクであり、6番目のバヌゞョンの登堎により、これはさらに目立぀ようになりたした。 珟圚、ルヌタヌたたはHTTPリク゚ストのラむブラリの圢匏の远加ツヌルだけでなく、アセンブリツヌルも暙準装備されおいたす。 そしお、Angularの開発者が意図しおいない倉曎を加えないでください。 この堎合にのみ、プロゞェクトを簡単に曎新でき、おそらく、曎新埌に数癟のファむルを倉曎する必芁はありたせん。 そうでなければ、困難な道があなたを埅っおおり、あなたは他者の肯定的で䞀般的な喜びの海で新しいバヌゞョンの吊定的なレビュヌを奜む必芁がありたす。



これは、Angularが悪いこずや良いこずを意味するものではなく、特別な凊理が必芁なだけで、誰にも適しおいたせん。 CLIを䜿甚しお䜜業し、ナヌティリティを䜿甚しおngプロゞェクトをアセンブルし、そのためのモゞュヌルずコンポヌネントをテストおよび䜜成すれば、満足です。 私たちのチヌムでもそれを望んでいたすが、残念なこずに、Webpackの蚭定に既にあたりにも倚くのものが関係しおいたす。 良いロシアのこずわざにあるように、「もしあなたがどこに萜ちるか知っおいたら、私はストロヌを敷くでしょう。」 1幎前、AngularプロゞェクトではCLIはそのような必須ツヌルではありたせんでしたが、今日では曎新に関するドキュメントでも、CLIなしで曎新する方法に関するガむドはありたせん。



All Articles