Angular 2、@ngtools/webpack、AOT

2024-01-10

我正在尝试使用 webpack 和 @ngtools/webpack 在 Angular 2 中使用 AOT。

我的编译没有任何错误,但是当我在浏览器上打开该网站时,出现控制台错误:

No NgModule metadata found for 'AppModule'

我的 AotPlugin 在 webpack 上的配置是这样的:

new AotPlugin({
    tsConfigPath: 'tsconfig.json',
    entryModule: helpers.root('src/app/app.module.ts#AppModule')
})

我的 app.module.ts 是:

@NgModule({
bootstrap: [ App ],
imports: [ // import Angular's modules
    BrowserModule,
    RouterModule.forRoot(ROUTES),
    SharedModule
],
declarations: [
    App,
    HomeComponent,
],
providers: providers
})
export class AppModule {}

和我的 main.browser.ts:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from "./app/app.module";

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

我的 tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "noEmitHelpers": true,
    "removeComments": true,
    "lib": ["es6", "dom"],
    "strictNullChecks": false,
    "baseUrl": "./src",
    "paths": [],
    "types": [
      "hammerjs",
      "jasmine",
      "node",
      "protractor",
      "selenium-webdriver",
      "source-map",
      "webpack"
    ]
  },
  "exclude": [
    "node_modules",
    "dist"
  ],
  "awesomeTypescriptLoaderOptions": {
    "forkChecker": true,
    "useWebpackText": true
  },
  "compileOnSave": false,
  "buildOnSave": false,
  "atom": { "rewriteTsconfig": false },
    "angularCompilerOptions": {
    "genDir": "dist",
    "entryModule": "src/app/app.module#AppModule"
  }
}

Webpack.config.js:

switch (process.env.NODE_ENV) {
  case 'prod':
  case 'production':
    module.exports = require('./config/webpack.prod')({env: 'production'});
    break;
  case 'test':
  case 'testing':
    module.exports = require('./config/webpack.test')({env: 'test'});
    break;
  case 'dev':
  case 'development':
  default:
    module.exports = require('./config/webpack.dev')({env: 'development'});
}

我的/config/webpack.prod.js:

const webpack = require('webpack');
const helpers = require('./helpers');
const webpackMerge = require('webpack-merge'); // used to merge webpack configs
    const commonConfig = require('./webpack.common.js').config; // the settings that are common to prod and dev
const hashName = require('./random-hash.js')(); // the settings that are common to prod and dev

    /**
     * Webpack Plugins
     */
    const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const NormalModuleReplacementPlugin = require('webpack/lib/NormalModuleReplacementPlugin');
const IgnorePlugin = require('webpack/lib/IgnorePlugin');
const DedupePlugin = require('webpack/lib/optimize/DedupePlugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');

/**
 * Webpack Constants
 */
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
const HOST = process.env.HOST || 'localhost';
const PORT = process.env.PORT || 8080;
const METADATA = webpackMerge(require('./webpack.common.js').metadata, {
    host: HOST,
    port: PORT,
    ENV: ENV
});

module.exports = function (env) {
    return webpackMerge(commonConfig({ env: ENV }), {

        devtool: 'hidden-source-map',

        output:{
            path: helpers.root('dist'),
            filename: '[name].bundle.js?ver='+ hashName,
            sourceMapFilename: '../maps/' + '[name].map?ver='+ hashName,
            chunkFilename: '[id].chunk.js?ver='+ hashName
        },


        plugins: [
            // NOTE: when adding more properties make sure you include them in custom-typings.d.ts
            new DefinePlugin({
                'ENV': JSON.stringify(METADATA.ENV),
                'process.env': {
                    'ENV': JSON.stringify(METADATA.ENV),
                    'NODE_ENV': JSON.stringify(METADATA.ENV)
                }
            }),
            new webpack.LoaderOptionsPlugin({
                optons: {
                    debug: false,
                    htmlLoader: {
                        minimize: true,
                        removeAttributeQuotes: false,
                        caseSensitive: true,
                        customAttrSurround: [
                            [/#/, /(?:)/],
                            [/\*/, /(?:)/],
                            [/\[?\(?/, /(?:)/]
                            ],
                            customAttrAssign: [/\)?\]?=/]
                    },
                    tslint: {
                        emitErrors: true,
                        failOnHint: true,
                        resourcePath: 'src'
                    },
                    postLoaders: [
                        {
                            test: /\.js$/,
                            loader: 'string-replace-loader',
                            query: {
                                search: 'var sourceMappingUrl = extractSourceMappingUrl\\(cssText\\);',
                                    replace: 'var sourceMappingUrl = "";',
                                        flags: 'g'
                            }
                        }
                    ],
                    preLoaders: [
                    {
                        test: /\.ts$/,
                        loader: 'string-replace-loader',
                        query: {
                            search: '(System|SystemJS)(.*[\\n\\r]\\s*\\.|\\.)import\\((.+)\\)',
                            replace: '$1.import($3).then(mod => (mod.__esModule && mod.default) ? mod.default : mod)',
                            flags: 'g'
                        },
                        include: [helpers.root('src')]
                    },
                    {
                        test: /\.ts$/,
                        loader: 'tslint-loader',
                        options: {
                            configFile: 'tslint.json'
                        },
                        exclude: [/\.(spec|e2e)\.ts$/]
                    }

                ]
                }
            })
        ],

        node: {
            global: true,
            crypto: 'empty',
            process: false,
            module: false,
            clearImmediate: false,
            setImmediate: false
        }

    });
};

和 config/webpack.common.js:

const webpack = require('webpack');
const helpers = require('./helpers');

/*
 * Webpack Plugins
 */
// problem with copy-webpack-plugin
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
const HtmlElementsPlugin = require('./html-elements-plugin');
const AssetsPlugin = require('assets-webpack-plugin');
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
const AotPlugin = require('@ngtools/webpack').AotPlugin;

/*
 * Webpack Constants
 */
/*
 * Static metadata for index.html
 *
 * See: (custom attribute)
 */
const METADATA = {
    title: '',
    baseUrl: '/',
    isDevServer: helpers.isWebpackDevServer()
};

/*
 * Webpack configuration
 *
 * See: http://webpack.github.io/docs/configuration.html#cli
 */
module.exports = {
    metadata: METADATA,
    config: function(options) {
        isProd = options.env === 'production';
        return {

            /*
             * Cache generated modules and chunks to improve performance for multiple incremental builds.
             * This is enabled by default in watch mode.
             * You can pass false to disable it.
             *
             * See: http://webpack.github.io/docs/configuration.html#cache
             */
            //cache: false,

            /*
             * The entry point for the bundle
             * Our Angular.js app
             *
             * See: http://webpack.github.io/docs/configuration.html#entry
             */
            entry: {

                'polyfills': './src/polyfills.browser.ts',
                'vendor':    './src/vendor.browser.ts',
                'main':      './src/main.browser.ts'

            },
            // output: {
            //   // Make sure to use [name] or [id] in output.filename
            //   //  when using multiple entry points
            //   //    filename: "[name].bundle.js",
            //   //  chunkFilename: "[id].bundle.js"
            //   publicPath: "https://d3ohoc4mai6ihm.cloudfront.net"
            // },

            /*
             * Options affecting the resolving of modules.
             *
             * See: http://webpack.github.io/docs/configuration.html#resolve
             */
            resolve: {

                /*
                 * An array of extensions that should be used to resolve modules.
                 *
                 * See: http://webpack.github.io/docs/configuration.html#resolve-extensions
                 */
                extensions: ['.ts', '.js', '.json'],

                // An array of directory names to be resolved to the current directory
                modules: [helpers.root('src'), 'node_modules'],

            },

            /*
             * Options affecting the normal modules.
             *
             * See: http://webpack.github.io/docs/configuration.html#module
             */
            module: {

                /*
                 * An array of automatically applied loaders.
                 *
                 * IMPORTANT: The loaders here are resolved relative to the resource which they are applied to.
                 * This means they are not resolved relative to the configuration file.
                 *
                 * See: http://webpack.github.io/docs/configuration.html#module-loaders
                 */
                loaders: [

                    /* Ahead of time plugin */
                    {
                        test: /\.ts$/,
                        loader: '@ngtools/webpack',
                    },

                    /*
                     * Json loader support for *.json files.
                     *
                     * See: https://github.com/webpack/json-loader
                     */
                    {
                        test: /\.json$/,
                        loader: 'json-loader'
                    },

                    /*
                     * to string and css loader support for *.css files
                     * Returns file content as string
                     *
                     */
                    {
                        test: /\.css$/,
                        loaders: ['to-string-loader', 'css-loader']
                    },

                    /* Raw loader support for *.html
                     * Returns file content as string
                     *
                     * See: https://github.com/webpack/raw-loader
                     */
                    {
                        test: /\.html$/,
                        loader: 'raw-loader',
                        exclude: [helpers.root('src/index.html')]
                    },

                    /* File loader for supporting images, for example, in CSS files.
                     */
                    {
                        test: /\.(jpg|png|gif)$/,
                        loader: 'url-loader?limit=100000000000'
                    },

                    // Support for SCSS as raw text
                    {
                        test: /\.scss$/,
                        loaders: ['raw-loader', 'sass-loader']
                    },

                    //{ test: /\.scss$/, loaders: ['style', 'css', 'postcss', 'sass'] },

                    {test: /\.(woff2?|ttf|eot|svg)$/, loader: 'url-loader?limit=100000000000'}

                ],


            },

            /*
             * Add additional plugins to the compiler.
             *
             * See: http://webpack.github.io/docs/configuration.html#plugins
             */
            plugins: [
                new AssetsPlugin({
                    path: helpers.root('dist'),
                    filename: 'webpack-assets.json',
                    prettyPrint: true
                }),

                /*
                 * Plugin: ForkCheckerPlugin
                 * Description: Do type checking in a separate process, so webpack don't need to wait.
                 *
                 * See: https://github.com/s-panferov/awesome-typescript-loader#forkchecker-boolean-defaultfalse
                 */
                new ForkCheckerPlugin(),
                /*
                 * Plugin: CommonsChunkPlugin
                 * Description: Shares common code between the pages.
                 * It identifies common modules and put them into a commons chunk.
                 *
                 * See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
                 * See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
                 */
                new webpack.optimize.CommonsChunkPlugin({
                    name: ['polyfills', 'vendor'].reverse()
                }),

                /**
                 * Plugin: ContextReplacementPlugin
                 * Description: Provides context to Angular's use of System.import
                 *
                 * See: https://webpack.github.io/docs/list-of-plugins.html#contextreplacementplugin
                 * See: https://github.com/angular/angular/issues/11580
                 */
                new ContextReplacementPlugin(
                    // The (\\|\/) piece accounts for path separators in *nix and Windows
                    /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
                    helpers.root('src') // location of your src
                ),
                new ContextReplacementPlugin(
                    // The (\\|\/) piece accounts for path separators in *nix and Windows
                    /moment[\/\\]locale$/, /en-gb/
                ),

                /*
                 * Plugin: CopyWebpackPlugin
                 * Description: Copy files and directories in webpack.
                 *
                 * Copies project static assets.
                 *
                 * See: https://www.npmjs.com/package/copy-webpack-plugin
                 */
                new CopyWebpackPlugin([{
                    from: 'src/assets',
                    to: 'assets'
                }]),

                /*
                 * Plugin: HtmlWebpackPlugin
                 * Description: Simplifies creation of HTML files to serve your webpack bundles.
                 * This is especially useful for webpack bundles that include a hash in the filename
                 * which changes every compilation.
                 *
                 * See: https://github.com/ampedandwired/html-webpack-plugin
                 */
                new HtmlWebpackPlugin({
                    template: 'src/index.html',
                    chunksSortMode: 'dependency'
                }),

                /*
                 * Plugin: HtmlHeadConfigPlugin
                 * Description: Generate html tags based on javascript maps.
                 *
                 * If a publicPath is set in the webpack output configuration, it will be automatically added to
                 * href attributes, you can disable that by adding a "=href": false property.
                 * You can also enable it to other attribute by settings "=attName": true.
                 *
                 * The configuration supplied is map between a location (key) and an element definition object (value)
                 * The location (key) is then exported to the template under then htmlElements property in webpack configuration.
                 *
                 * Example:
                 *  Adding this plugin configuration
                 *  new HtmlElementsPlugin({
                     *    headTags: { ... }
                     *  })
                 *
                 *  Means we can use it in the template like this:
                 *  <%= webpackConfig.htmlElements.headTags %>
                 *
                 * Dependencies: HtmlWebpackPlugin
                 */
                new HtmlElementsPlugin({
                    headTags: require('./head-config.common')
                }),

                /* Ahead of time compilation plugin */
                new AotPlugin({
                    tsConfigPath: 'tsconfig.json',
                    entryModule: helpers.root('src', 'app', 'app.module.ts#AppModule')
                })
            ],

            /*
             * Include polyfills or mocks for various node stuff
             * Description: Node configuration
             *
             * See: https://webpack.github.io/docs/configuration.html#node
             */
            node: {
                global: 'window',
                crypto: 'empty',
                process: true,
                module: false,
                clearImmediate: false,
                setImmediate: false
            }

        };
    }
}

完整的错误跟踪:

Uncaught Error: No NgModule metadata found for 'AppModule'.
    at NgModuleResolver.resolve (vendor.bundle.js?ver=d1084b5…:18969) [<root>]
    at CompileMetadataResolver.getNgModuleMetadata (vendor.bundle.js?ver=d1084b5…:18172) [<root>]
    at JitCompiler._loadModules (vendor.bundle.js?ver=d1084b5…:50582) [<root>]
    at JitCompiler._compileModuleAndComponents (vendor.bundle.js?ver=d1084b5…:50542) [<root>]
    at JitCompiler.compileModuleAsync (vendor.bundle.js?ver=d1084b5…:50508) [<root>]
    at PlatformRef_._bootstrapModuleWithZone (vendor.bundle.js?ver=d1084b5…:39236) [<root>]
    at PlatformRef_.bootstrapModule (vendor.bundle.js?ver=d1084b5…:39211) [<root>]
    at Object.<anonymous> (main.bundle.js?ver=d1084b5…:34315) [<root>]
    at __webpack_require__ (polyfills.bundle.js?ver=d1084b5…:53) [<root>]
    at webpackJsonpCallback (polyfills.bundle.js?ver=d1084b5…:24) [<root>]
    at :8080/main.bundle.js?ver=d1084b5dbd73943cc778978401608960:1:1 [<root>]

我真的不知道发生了什么事。我真的很感谢你的时间和你的帮助。


我真的不知道这是否有帮助,但我也遇到了类似的问题。我猜你正在使用某种样板,因为你有这个helpers.root功能。

首先尝试改变这部分:

new AotPlugin({
    tsConfigPath: 'tsconfig.json',
    entryModule: helpers.root('src/app/app.module.ts#AppModule')
})

对此(adding helpers.root部分到tsconfig.json file):

new AotPlugin({
    tsConfigPath: helpers.root('tsconfig.json'),
    entryModule: helpers.root('src/app/app.module.ts#AppModule')
})

其次仔细检查你的tsconfig.json配置为 AoT 编译。这是我的tsconfig-aot.json我正在我的 Angular 2 项目之一中使用它:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": ["es2015", "dom"],
    "noImplicitAny": false,
    "sourceRoot": ".",
    "suppressImplicitAnyIndexErrors": true,
    "typeRoots": [
      "node_modules/@types"
    ]
  },

  "awesomeTypescriptLoaderOptions": {
    "useWebpackText": true,
    "forkChecker": true,
    "useCache": true
  },

  "angularCompilerOptions": {
    "genDir": "aot",
    "skipMetadataEmit" : true
  }
}

希望这会有所帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular 2、@ngtools/webpack、AOT 的相关文章

随机推荐

  • Android 的 FragmentTabs 示例中的两个框架布局 Support4Demos

    我对 Android 中的片段不熟悉 我指的是为 supportv4 兼容性库提供的片段演示示例 谁能解释一下为什么有两种框架布局 android id realtabcontent android id tabcontent Androi
  • iPad Safari 视口的高度

    iPad 的视口宽度为 980 像素 高度是多少 在 Safari 中 我们必须添加地址和新的水龙头 Safari 横向模式下的高度是多少 有一个媒体查询可以使网页适合宽度 有没有办法使网页适合高度 以下是答案 你是对的 iPhone iP
  • PostgreSQL 权限授予不可见

    在 PostgreSQL 10 上 我有一个名为tn schema和一个名为tn beta db 我认为是的 尽管我确实必须连接到相关数据库才能查看架构 T jeff nantes 4 sudo su postgres c psql psq
  • lombok对jpa有副作用吗

    我正在努力将 jpa 实体转换为使用 lombok 结果代码如下 Entity Table name TEST Data NoArgsConstructor AllArgsConstructor class Test Column name
  • 如何在javascript中禁用输入文本框上的键盘事件

    我有一个图像 我使用键盘对其进行一些操作 翻译 缩放 在图像上方 我有一个输入文本框 显示数据集中图像的编号 当光标位于文本框上时如何禁用图像操作 即禁用我分配给每个键盘的行为 我还希望仍然能够编辑文本框 例如移动到图像编号 xx 从我在这
  • 如何在WPF中正确刷新自定义形状?

    我创建了一条自定义行 旁边有一些文本 形状是一个子类System Windows Shapes Shape 由于某种原因 当我更改线的坐标时 文本不会刷新 我知道关于InvalidateVisual 方法 但每次我移动元素时 我都必须调用它
  • Xcode 调试:查看 NSNumber 的值?

    是否可以在变量监视窗口中的调试器数据提示中看到 NSNumber 的数值 我在 NSNumber 中存储一个整数值 并希望在调试期间看到该值 我已经在调试器中尝试了一些数据格式化程序 但没有太大帮助 打开调试器视图并在摘要列中输入 int
  • 尝试在 python 中创建 virtualenv 并激活它

    我很难在 Python 中创建 virtualenv 并激活它 我正在研究Windows操作系统 在命令提示符下 我通过输入以下命令安装了 virtualenv pip install virtualenv 然后 为了在其中创建虚拟环境 我
  • 从 Javascript 中的对象列表中提取对象属性

    我从 API 接收到以下对象 2012 12 12 id 1234 type A id 1235 type A id 1236 type B 2012 12 13 id 1237 type A id 1238 type C id 1239
  • 需要一个策略将 Intellij IDEA 项目文件放入 Git 中

    需要一个将 Intellij IDEA 项目文件放入 Git 的策略 主要问题是如果idea项目文件在git中 如何避免分支之间的合并冲突 另一个问题是把它们保存在git中方便吗 如何避免合并 您可以保护某些文件不被合并合并管理器 http
  • SQL Server中的SQL group_concat函数[重复]

    这个问题在这里已经有答案了 如果有一张名为employee的表 EmpID EmpName 1 Mary 1 John 1 Sam 2 Alaina 2 Edward 我需要这种格式的结果 EmpID EmpName 1 Mary John
  • 如何使用 Alpaca 创建必需的条件字段?

    有谁知道如何定义依赖于另一个字段的必填字段 例如如果field1被标记true then field2必须为必填项 否则不应填写字段 2 这是我目前的尝试 field1 title Field1 type string enum true
  • Google Play 商店中的 Android 版本:选择加入 URL 在哪里?

    我正在努力在 Google Play 商店中发布我们的应用程序的私人内部版本 我收到一条消息 显示 当您发布应用程序时 此处将提供选择加入链接 但我不知道还需要做什么来发布我的 alpha 测试 apk 发布状态显示 全面推出 这向我表明一
  • 如何在 Windows 上为 python 3.7 正确设置 pyarrow

    我一直在尝试通过 pip 安装 pyarrow pip install pyarrow 并且 正如 Yagav 所建议的 py 3 7 m pip install user pyarrow 和康达 conda install c conda
  • UIControl 未接收触摸

    我有一个 UIControl 它实现了 Touchs Begin 方法 如下所示 void touchesBegan NSSet touches withEvent UIEvent event super touchesBegan touc
  • ASP.NET MVC 3 对嵌套对象的验证未按预期工作 - 验证子对象两次而不是父对象

    我正在尝试让 ASP NET MVC 3 从复杂的嵌套对象生成表单 我发现了一种意外的验证行为 我不确定这是否是 DefaultModelBinder 中的错误 如果我有两个对象 我们将 父对象 称为 OuterObject 并且它具有 I
  • 具有现有样式表的应用程序的 CSS 框架

    我正在构建一个 chrome 扩展 它将一个小部件之类的东西附加到 Gmail 消息 当用户访问 gmail com 网站时 它会出现在每封电子邮件的下方 类似于 gmail 上下文小工具 我研究了一些在我的应用程序中使用的 css 框架
  • ReferenceError:模块未定义 - Karma/Jasmine 配置与 Angular/Laravel 应用程序

    我有一个现有的 Angular Laravel 应用程序 其中 Laravel 充当仅提供 JSON 数据的 Angular 前端的 API 加载角度应用程序的页面 index php 目前由 Laravel 提供服务 从那时起 Angul
  • 哪种 TypeScript 配置会产生最接近 Node.js 14 功能的输出?

    随着 Node js 更新对 ES2020 的支持并添加对 ES 模块的支持 如何配置 TypeScript 来输出利用所有这些新功能的 JavaScript 代码 从 Node js 开始14 0 0 100 支持ES2020 对ES M
  • Angular 2、@ngtools/webpack、AOT

    我正在尝试使用 webpack 和 ngtools webpack 在 Angular 2 中使用 AOT 我的编译没有任何错误 但是当我在浏览器上打开该网站时 出现控制台错误 No NgModule metadata found for