使用 @ngtools/webpack 在 Angular 11 + Webpack 4 中实现 AOT

Posted

技术标签:

【中文标题】使用 @ngtools/webpack 在 Angular 11 + Webpack 4 中实现 AOT【英文标题】:Implementing AOT in angular 11 + Webpack 4 using @ngtools/webpack 【发布时间】:2021-04-02 15:51:20 【问题描述】:

我正在尝试在不支持 cli 的 angular 项目中实现 AOT。我搜索了一下,发现@ngtools/webpack 是要走的路。我的角度是 11.0.4,Typescript 是 4.0.5,webpack - 4.44.2。我安装了@ngtools/webpack - 11.0.4。

我的 tsconfig.aot.json -


"angularCompilerOptions": 
    "skipMetadataEmit" : true,
    "trace": true,
    "genDir": "aot/"
,
"angularOptions": 
    "annotationsAs": "decorators"
,
"compilerOptions": 
    "target": "es2015",
    "module": "es2020",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [ "es2015", "dom", "es7", "es2017", "es2018", "es2019" ],
    // "noEmit": true,
    "noImplicitAny": false,
    "suppressImplicitAnyIndexErrors": true,
    "baseUrl": ".",
    "allowJs": true,
    "allowUnreachableCode": false,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "incremental": false,
    "resolveJsonModule": true,
    "outDir": "./out-tsc/app",
,
"exclude": [
    "node_modules",
    "aot/",
    "app/Content/js/embed/appBootstrap.ts"
]

我的 Webpack.config -

//dependencies
const path = require('path');
const webpack = require('webpack');
const  AngularCompilerPlugin  = require('@ngtools/webpack');

//paths
const portalPath = path.join(__dirname, 'app');
const portalContentPath = path.join(portalPath, 'Content');
const webpackScriptPath = path.join(portalContentPath, 'js');
const nodeModulesPath = path.join(__dirname, 'node_modules');
const vbNodeModulesPath = path.join(nodeModulesPath, '@vb');
const outputPath = path.join(portalPath, 'dist');

//entry points
const entries = 
    embed: path.join(webpackScriptPath, 'embed', 'EmbedBootstrap.ts')
;

module.exports = 
    mode: 'production',
    entry: entries,
    output: 
        path: outputPath,
        filename: '[name].js',
        publicPath: '/dist/',
        sourceMapFilename: '[file].map'
    ,
    module: 
        rules: [
            
                test: /(\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                use: [
                    '@ngtools/webpack'
                ]
            ,
            
                test: /\.html$/,
                use: [
                    
                        loader:'html-loader',
                        options: 
                            minimize: 
                                caseSensitive: true,
                                keepClosingSlash: true,
                                removeAttributeQuotes: false
                            
                        
                    
                ]
            
        ]
    ,
    plugins: [
        new AngularCompilerPlugin(
            tsConfigPath: path.join(__dirname, 'tsconfig.aot.json'),
            sourceMap: true,
            skipCodeGeneration: true, // AOT toggle
            mainPath: path.join(webpackScriptPath, 'embed', 'appBootstrap.ts'),
            entryModule: path.join(webpackScriptPath, 'embed', 'App.Module#AppModule')
        ),
        ...Object.values(entries).map(entryPath => new webpack.ContextReplacementPlugin(/\@angular(\\|\/)core(\\|\/)fesm2015/, entryPath))
    ],
    resolve: 
        modules: [
            'node_modules',
            vbNodeModulesPath,
            path.join(vbNodeModulesPath, 'vb-player', 'node_modules', '@vb')
        ],
        extensions: ['.tsx', '.ts', '.js']
    
;


appBootstrap.ts


import  enableProdMode  from '@angular/core';
import  platformBrowser  from '@angular/platform-browser';
 // This file not getting generated and giving compilation error
import  AppModuleNgFactory  from './App.Module.ngfactory';
enableProdMode();

platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

App.Module.ts

import  NgModule  from '@angular/core';
import  CommonModule  from '@angular/common';
import  FormsModule  from '@angular/forms';
import  AppComponent  from './App.Component';

@NgModule(
    bootstrap: [AppComponent],
    declarations: [
        AppComponent
    ],
    imports: [
        CommonModule,
        FormsModule
    ]
)
export class AppModule 

我正在使用以下命令运行 webpack.min.config(我将它添加到我的 package.json 并使用 npm run build)

node --max_old_space_size=4096 node_modules/webpack/bin/webpack --config ./webpack.config.min.js

我得到的错误:-

Module not found: Error: Can't resolve './App.Module.ngfactory'.

我不确定 ngfactory 文件将在哪个文件夹中生成。我找不到任何最新版本的@ngtools/webpack 的可靠实现文档。

我还尝试使用 platformBrowserDynamic() 而不是 ngFactory 来引导我的 AppModule。在那种情况下,我会收到错误提示

Module parse failed: Unexpected character '@' (41:0)
> @NgModule(
|       bootstrap: [AppComponent],
|       declarations: [
 @ ./App.Module.ts

我尝试使用 tsconfig 中的选项,但最终没有成功。 任何帮助将不胜感激。提前非常感谢。

【问题讨论】:

您能否查看此 URL 的最新 cmets - github.com/angular/angular/issues/25424 。大家都建议升级来解决这个问题。 @AyonAlfaz 感谢您的调查。我只使用最新版本的 angular,但不使用 angular-cli。我有自己的 webpack.config @learntech 运气不错,你是怎么解决的 @vishnughule 您还在为此寻找解决方案吗? @learntech 是的,我仍在寻找解决方案,我尝试了其他一些替代方案,但最终跳过了 AOT,我的应用程序性能下降 【参考方案1】:

"enableIvy": false 放在“angularCompilerOptions”下会有帮助吗?

【讨论】:

以上是关于使用 @ngtools/webpack 在 Angular 11 + Webpack 4 中实现 AOT的主要内容,如果未能解决你的问题,请参考以下文章

找不到 API 编译器-cli,函数 VERSION

C第三课

C第六课

C第九课

C第五课

ANG-----全方位保障您的数字资产安全