Angular AOT - UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: #): TypeError: Cannot read property 'request' of undefined

Angular AOT - UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: #): TypeError: Cannot read property 'request' of undefined

我正在使用 @ngtools/webpack 作为我的 Angular CLI,用于将 AOT 编译添加到我的 Angular 5 应用程序。对任何人来说都不足为奇,这对我来说已经

我已经让 AOT 在 3 个环境中工作,本地主机、开发和暂存。当然,昨天部署到生产环境时,我发现我的 Webpack 构建崩溃了。

虽然我确定问题的根源是 @ngtools/webpack.AngularCompilerPlugin.

,但我无法获得有意义的错误消息

我的错误信息是几百条:

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: #): TypeError: Cannot read property 'request' of undefined

WebpackAOT Plugin 步骤发出数百个此类 UnhandledPromiseRejectionWarnings 之后,它继续构建 node_module 代码,然后未能创建 dist 输出:

> tsl-frontend@0.1.0 build-production /app
> webpack --mode production -p --progress --colors --env.env production

env configuration production
***AOT Compilation***
WebpackDelPlugin::Successfully deleted /app/dist/*.* assets.

[91m  0% compiling[0m[91m[0m[91m 10% building modules 0/1 modules 1 active multi babel-polyfill ./src/main.ts[0m[91m                                    10% building modules 1/1 modules 0 active[0m[91m(node:15) DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead
[0m[91m(node:15) DeprecationWarning: Tapable.apply is deprecated. Call apply on the plugin directly instead
[0m[91m(node:15) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'request' of undefined
(node:15) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: Cannot read property 'request' of undefined
[0m[91m(node:15) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): TypeError: Cannot read property 'request' of undefined
(node:15) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 4): TypeError: Cannot read property 'request' of undefined
(node:15) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 5): TypeError: Cannot read property 'request' of undefined
///----removed for brevity
(node:15) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 202): TypeError: Cannot read property 'request' of undefined
[0m[91m 10% building modules 1/2 modules 1 active ?ode_modules/babel-polyfill/lib/index.js
//removed for brevity
 70% building modules 2087/2087 modules 0 active[0mRemoving intermediate container b082f2548cbe
 ---> 098c4df274ad
Step 14/17 : RUN cd /app && cp -a dist/* /usr/share/nginx/html
 ---> Running in e179a7482da7
[91mcp: cannot stat 'dist/*': No such file or directory
[0mRemoving intermediate container e179a7482da7
Service 'frontendproduction' failed to build: The command '/bin/sh -c cd /app && cp -a dist/* /usr/share/nginx/html' returned a non-zero code: 1

我研究了一段时间,找到了几个我认为可能相关的网络链接,尝试了很多修复方法,尤其是 this article 但没有成功。这是我认为可能相关但没有帮助的其他几篇文章:

这是我的 Webpack.config.js:

var merge = require('webpack-merge'),
htmlPlugin = require('html-webpack-plugin'),
revPlugin = require('webpack-rev-replace-plugin'),
config = require('./build.config.json'),
path = require('path'),
extendedDefinePlugin = require('extended-define-webpack-plugin'),
webpackDelPlugin = require('webpack-del-plugin'),
openBrowserPlugin = require('open-browser-webpack-plugin'),
uglifyJSPlugin = require('uglifyjs-webpack-plugin');
const AotPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
//import {AngularCompilerPlugin} from '@ngtools/webpack';

//Note : in package.json the last variable (dev) is the param delivered to this function { env: 'dev' }. 
module.exports = function (env) {
    console.log('env configuration', env.env);
    /**
     * configPerTarget is merged with build.config.json based on the env passed
     * currently no configuration properties, this configPerTarget not in use per se, keeping just in case - Ogden 4-12-2018
     */
    var configPerTarget = {
        localhost: {
        },
        development: {
        },
        test: {
        },
        staging: {
        },
        production: {
        },
        maintenance: {
        }
    };

    // Note : '__dirname' is the root file path.
    const ROOT_DIR = path.resolve(__dirname);
    const DIST_DIR = path.join(ROOT_DIR, config.dist);

    // If no env make it dev
    if (!env) {
        env = {};
        env.env = config.envDevelopment;
    }

    //merge config with env specific configPerTarget
    config = merge(config, configPerTarget[env.env]);

    // this takes path variables from build.config.json and builds it with given env
    var appConfigPath = config.envs + config.appConfig.replace('{env}', env.env);


    var webPackConfig = {
        entry: ['babel-polyfill', config.src + config.entry],//main.ts
        output: {
            path: path.resolve(__dirname, config.dist),
            filename: config.buildjs,
            sourceMapFilename: config.buildjsmap,
            chunkFilename: config.buildchunk
        },
        module: {
            rules: [
                { test: /\.html$/, use: 'raw-loader' },
                { test: /\.css$/, use: 'raw-loader' },
                {
                    test: /\.scss$/,
                    exclude: /node_modules/,
                    loaders: ['style-loader', 'css-loader', 'sass-loader'],
                },
                //For images. 
                { test: /\.(jpe?g|png|gif|svg)$/i, loader: 'file-loader?name=app/assets/images/[name].[ext]' },
                {
                    test: /\.(ttf|eot|woff|woff2)$/,
                    loader: 'file-loader'
                },
            ]
        },
        //https://webpack.js.org/configuration/devtool/
        //Webpack 4.4 has its own mode development and production, which are environment modes
        //do Webpack 4.4 is handling the devtool sourcemap config where in the past it was not
        //looks like we no longer have to worry about setting devtool
        //https://github.com/damianobarbati/yarsk/blob/50b6f352a13ec2e778fa8b252f915550b6132964/config/webpack.config.js#L110
        //devtool: config.devtool,
        resolve: {
            modules: [__dirname + path.sep + 'src', __dirname, 'node_modules'],
            extensions: ['.js', '.ts', '.scss', '.css', '.html']
        },
        plugins: [
            new htmlPlugin({
                template: config.src + config.index
            }),
            new revPlugin({
                cwd: config.src,
                files: '**/*.html',
                outputPageName: function (filename) {
                    return filename;
                },
                modifyReved: function (filename) {
                    return filename.replace(/(\/style\/|\/script\/)/, '')
                }
            }),
            //Makes AppConfig variable available in the application code. 
            new extendedDefinePlugin({
                AppConfig: require(appConfigPath)
            }),
            //Usefull if you need remove some files or folders before compilation processes. 
            //currently not used (no dist file).
            new webpackDelPlugin({ match: path.join(DIST_DIR, '*.*') }),
            //opens browser after compilation.
            new openBrowserPlugin({ url: 'http://localhost:8080' })
        ],
        optimization: {
            minimizer: [
                new uglifyJSPlugin({
                    uglifyOptions: {
                        output: {
                            comments: false,
                            ascii_only: true //must be on to fix this issue https://github.com/angular/angular/issues/19475
                        }
                    }
                })
            ]
        }
    }

    if (env.env === config.envLocalhost) {
        webPackConfig.module.rules.push(
            {
                test: /\.ts$/,
                loaders: [
                    'ts-loader',
                    'angular2-template-loader',
                    'angular-router-loader']
            }
        );

        return webPackConfig;
    } 

    //********************************AOT Compilation*************************************** */
    //-- AOT Compilation from this point on, currently AOT runs in all environments
    //this seems helpful because you get to see AOT build errors before pushing to build server
    //the downside might be more mangled code and harder to debug source code...
    console.log('***AOT Compilation***');

    webPackConfig.module.rules.push(
        {
            test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
            loaders: ['@ngtools/webpack']
        }
    );

    webPackConfig.plugins.push(new AotPlugin({
        tsConfigPath: './tsconfig-aot.json',
        entryModule: path.join(config.src, 'app/app.module#AppModule'),
        sourceMap: true
    }));

    return webPackConfig;
}

这是我的 package.json:

{
  "name": "tsl-frontend",
  "version": "0.1.0",
  "scripts": {
    "test": "karma start",
    "build-localhost": "webpack --mode development --progress --colors --env.env localhost",
    "build-development": "webpack --mode development --progress --colors --env.env development",
    "build-staging": "webpack --mode production --progress --colors --env.env staging",
    "build-production": "webpack --mode production -p --progress --colors --env.env production",
    "build-maintenance": "webpack --mode production -p --progress --colors --env.env maintenance",
    "serve": "webpack-dev-server --mode development --inline --progress --colors --env.env development",
    "serve-production": "webpack-dev-server --mode production --inline --progress --colors --env.env development",
    "serve-localhost": "webpack-dev-server --mode development --inline --progress --colors --env.env localhost",
    "serve-host": "webpack-dev-server --host 0.0.0.0 --port 80 --disable-host-check --mode development --inline --progress --colors --env.env localhost",
    "serve-maintenance": "webpack-dev-server --mode development --inline --progress --colors --env.env maintenance"
  },
  "dependencies": {
    "@angular/animations": "^5.2.11",
    "@angular/cdk": "^2.0.0-beta.12",
    "@angular/common": "^5.2.11",
    "@angular/compiler": "^5.2.11",
    "@angular/compiler-cli": "^5.2.11",
    "@angular/core": "^5.2.11",
    "@angular/forms": "^5.2.11",
    "@angular/http": "^5.2.11",
    "@angular/material": "^2.0.0-beta.12",
    "@angular/platform-browser": "^5.2.11",
    "@angular/platform-browser-dynamic": "^5.2.11",
    "@angular/platform-server": "^5.2.11",
    "@angular/router": "^5.2.11",
    "@ng-bootstrap/ng-bootstrap": "^1.1.2",
    "@types/file-saver": "^1.3.0",
    "angular2-jwt": "^0.2.3",
    "angular2-text-mask": "^8.0.5",
    "bootstrap": "^4.1.2",
    "chart.js": "^2.7.2",
    "devextreme": "^18.1.4",
    "devextreme-angular": "^18.1.4",
    "file-saver": "^1.3.8",
    "font-awesome": "^4.7.0",
    "moment": "2.18.1",
    "moment-timezone": "0.5.13",
    "ng2-bootstrap-modal": "1.0.1",
    "ng2-charts": "^1.6.0",
    "ng2-drag-drop": "^2.9.2",
    "ng2-page-scroll": "^4.0.0-beta.12",
    "ng2-toastr": "^4.1.2",
    "popper.js": "^1.14.3",
    "reflect-metadata": "0.1.8",
    "rxjs": "5.5.5",
    "systemjs": "0.19.40",
    "typescript": "^2.9.2",
    "xlsx": "^0.11.19",
    "zone.js": "^0.8.26"
  },
  "devDependencies": {
    "@ngtools/webpack": "^6.0.8",
    "@servicestack/client": "^1.0.14",
    "@types/file-saver": "^1.3.0",
    "@types/jasmine": "^2.8.8",
    "@types/node": "7.0.7",
    "angular-router-loader": "^0.6.0",
    "angular2-router-loader": "^0.3.5",
    "angular2-template-loader": "^0.6.2",
    "babel-polyfill": "^6.26.0",
    "css-loader": "^0.28.11",
    "extended-define-webpack-plugin": "^0.1.3",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^1.1.11",
    "file-saver": "^1.3.8",
    "html-webpack-plugin": "^4.0.0-alpha",
    "jasmine": "^2.99.0",
    "karma": "^1.7.0",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-webpack": "^2.0.13",
    "ng-intercom": "^1.0.0-beta.5-2",
    "ng2-tree": "^2.0.0-rc.11",
    "node-sass": "^4.9.2",
    "open-browser-webpack-plugin": "0.0.5",
    "path": "^0.12.7",
    "raw-loader": "^0.5.1",
    "sass-loader": "^6.0.7",
    "style-loader": "^0.13.2",
    "text-mask-addons": "^3.7.2",
    "toposort": "^1.0.7",
    "ts-loader": "^4.4.2",
    "webpack": "^4.16.1",
    "webpack-cli": "^2.1.5",
    "webpack-del-plugin": "0.0.1",
    "webpack-dev-server": "^3.1.4",
    "webpack-merge": "^4.1.3",
    "webpack-rev-replace-plugin": "^0.1.1"
  }
}

我相信这个错误是因为我为我的项目安装了两个版本的 Webpack。从错误发生在一个环境而不是其他环境中的角度来看,这是有道理的。也许 npm 依赖关系树不同,并且出于某种原因正在使用旧版本的 Webpack。

有一个 npm 包:webpack-rev-replace-plugin 具有 Webpack v1.5 依赖项。我使用的是 Webpack v4.16。一旦我删除了 webpack-rev-replace-plugin 并因此删除了旧版本的 Webpack,我开始收到与 uglifyjs-webpack-plugin 相关的不同错误,一旦我删除了 uglifyjs-webpack-plugin 并且只是使用 Webpacks 默认值进行缩小等,一切都很好。