【问题标题】:Unhandled promise rejection: Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten未处理的承诺拒绝:Zone.js 检测到 ZoneAwarePromise `(window|global).Promise` 已被覆盖
【发布时间】:2017-08-02 04:05:11
【问题描述】:

我已尝试将 Angular2 快速入门代码合并到我当前的 webpack 构建中,似乎有些东西正在覆盖引发此错误的 zone.js 承诺。根据我看到的大多数 stackoverflow 帖子,zone.js 文件需要在任何可能包含承诺的文件之后加载。

我假设正在发生的事情是,在 webpack 加载其余的 node_module 文件之前,已经加载了带有 <src> 标记和 zone.js 文件的 html。

有什么想法或建议吗?


这是我正在使用的package.json

{
  "name": "site-pinger",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "build:watch": "webpack --colors --progress --watch",
    "build": "webpack --colors --progress",
    "start": "webpack-dev-server --progress --colors --hot --inline --port 3000"
  },
  "author": "",
  "license": "ISC",
  "standard": {
    "parser": "babel-eslint"
  },
  "babel": {
    "presets": [
      "latest",
      "stage-0"
    ]
  },
  "devDependencies": {
    "@types/jasmine": "2.5.36",
    "@types/node": "^6.0.46",
    "babel-core": "^6.17.0",
    "babel-eslint": "^7.0.0",
    "babel-loader": "^6.2.5",
    "babel-polyfill": "^6.16.0",
    "babel-preset-latest": "^6.16.0",
    "babel-preset-stage-0": "^6.16.0",
    "canonical-path": "0.0.2",
    "concurrently": "^3.2.0",
    "extract-text-webpack-plugin": "^2.1.0",
    "file-loader": "^0.9.0",
    "html-loader": "^0.4.5",
    "html-webpack-plugin": "^2.28.0",
    "jasmine-core": "~2.4.1",
    "json-loader": "^0.5.4",
    "karma": "^1.3.0",
    "karma-chrome-launcher": "^2.0.0",
    "karma-cli": "^1.0.1",
    "karma-jasmine": "^1.0.2",
    "karma-jasmine-html-reporter": "^0.2.2",
    "lodash": "^4.16.4",
    "protractor": "~4.0.14",
    "rimraf": "^2.5.4",
    "standard": "^8.4.0",
    "style-loader": "^0.13.2",
    "ts-loader": "^2.0.1",
    "tslint": "^3.15.1",
    "typescript": "~2.0.10",
    "url-loader": "^0.5.8",
    "webpack": "^2.1.0",
    "webpack-dev-server": "^2.4.1"
  },
  "dependencies": {
    "@angular/common": "~2.4.0",
    "@angular/compiler": "~2.4.0",
    "@angular/core": "~2.4.0",
    "@angular/forms": "~2.4.0",
    "@angular/http": "~2.4.0",
    "@angular/platform-browser": "~2.4.0",
    "@angular/platform-browser-dynamic": "~2.4.0",
    "@angular/router": "~3.4.0",
    "angular-in-memory-web-api": "~0.2.4",
    "systemjs": "0.19.40",
    "core-js": "^2.4.1",
    "rxjs": "5.0.1",
    "zone.js": "^0.7.4"
  },
  "repository": {}
}

这是webpack.config.js 文件

'use strict'

const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

const devtool = 'source-map'

const devServer = {
  historyApiFallback: true
}

const entry = {
  main: [
    'babel-polyfill',
    './src/main'
  ],
}

const output = {
  filename: '[name].js',
  path: __dirname + '/dist',
  publicPath: '/'
}

const extensions = [
  '.js',
  '.ts',
  '.css',
  '.html'
]

const modules = [
  'node_modules',
  'lib'
]

const rules = [{
  test: /.ts$/,
  exclude: /node_modules/,
  loaders: ['ts-loader']
}, {
  test: /.js$/,
  exclude: /node_modules/,
  loaders: ['babel-loader']
}, {
  test: /.css$/,
  loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
}, {
  test: /.html$/,
  exclude: /node_modules/,
  include: /static/,
  loader: 'html-loader'
}, {
  test: /.(ico|png|eot|svg|ttf|woff|woff2)$/,
  loader: 'url?limit=10000'
}]

const plugins = [
  new ExtractTextPlugin('[name].css'),
  new HtmlWebpackPlugin({
    hash: true,
    inject: 'head',
    template: 'static/index.html'
  }),
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor',
    minChunks: Infinity
  })
]

module.exports = {
  devtool,
  devServer,
  entry,
  output,
  resolve: {
    extensions,
    modules
  },
  module: {
    rules
  },
  plugins
}

这是我的 index.html,我在其中手动包含了 zone.js 文件,以确保它们的 Promise 不会被覆盖。

<!doctype html>

<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Site Pinger</title>

    <script src="node_modules/core-js/client/shim.min.js"></script>
    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>

    <script src="../src/systemjs.config.js"></script>
  </head>

  <body>
    <app>Loading AppComponent content here ...</app>
  </body>
</html>

【问题讨论】:

  • 没有必要在单独的
  • 当我将它从 html 中删除时,它会抛出完全丢失的错误。 Systemjs 在那里,因为它在 angular2 github 页面上的快速启动应用程序中。我基本上复制粘贴了他们的大部分配置代码,然后尝试查看它是否适用于 webpack。我刚刚用this webpack 配置和项目结构替换了我的配置,现在一切似乎都在工作。他似乎还将 zone.js 文件包含在不同的区域中,我不知道为什么。不知道我是否应该删除这篇文章。
  • 是的,通常情况下polyfills是捆绑在一起的,这里是正确的顺序,zone.js跟随core-js,github.com/preboot/angular2-webpack/blob/master/src/…

标签: javascript angular typescript webpack


【解决方案1】:

我在加载 core-jszone.js 时遇到了类似的错误。 对我来说,诀窍是将zone.js 的导入放在core-js 之后。

改变了这个:

import 'zone.js/dist/zone';
import 'core-js';

到这里:

import 'core-js';
import 'zone.js/dist/zone';

回到你的 webpack 问题,正如 @estus 所说,没有必要将 systemjs 导入那里,因为它将包含在 webpack 生成的 dist/* 文件中(在你的 index.xml 文件中缺少这些文件)。 html)。

“webpacking”后我的 index.html 我的项目看起来像:

<html>
  <head>
    <!-- only some css links here -->
  </head>
  <body>
    <my-app>
    </my-app>

    <script src="dist/vendor.bundle.min.js"></script>
    <script src="dist/app.bundle.min.js"></script>
  </body>
</html>

希望对你有帮助。

【讨论】:

  • 非常感谢,这个错误让我发疯了!
【解决方案2】:

当我通过运行 npm install zone.js@latest --save 将我的 zone.js 包更新到最新版本时,它对我有用。

【讨论】:

    【解决方案3】:

    有同样的问题。有 import 'zone.js/dist/zone';在 polyfill.ts 中。我将其移至 main.ts 并解决了我的问题

    【讨论】:

      【解决方案4】:

      我在 10.3 等旧 Safari 浏览器上遇到了同样的错误 对我来说,这只是 browserslist 文件中缺少的条目。

      ios_saf >= 10
      Safari >= 10
      

      source

      【讨论】:

        【解决方案5】:

        SebraGra 的回答是正确的。但是,如果您是在尝试在 asp.net 网站中运行 Angular(在我的情况下为 4.5.2 版)的情况下来到这里的,那么当您在 app-root 标记之后渲染脚本时,错误就会消失。 您还需要专门针对 dist 文件夹中的 es2015 或 es5 输出

        我还没找到动态切换的方法

            @{
                Layout = null;
            }
        
            <!DOCTYPE html>
            <html>
            <head>
                <meta name="viewport" content="width=device-width" />
                <title></title>
                <base href="/">
            </head>
            <body>
                <app-root></app-root>
                @Scripts.Render("~/Scripts/App-es5")
            </body>
            </html>
        
            public class AngularBundleConfig
            {
                public static void RegisterBundles(BundleCollection bundles)
                {
                    bundles.Add(new ScriptBundle("~/Scripts/App-es2015")
                        .Include(
                            "~/App/dist/App/scripts-es2015*",
                            "~/App/dist/App/vendor-es2015*",
                            "~/App/dist/App/polyfills-es2015*",
                            "~/App/dist/App/runtime-es2015*",
                            "~/App/dist/App/main-es2015*"
                            ));
        
                    bundles.Add(new ScriptBundle("~/Scripts/App-es5")
                        .Include(
                            "~/App/dist/App/scripts-es5*",
                            "~/App/dist/App/vendor-es5*",
                            "~/App/dist/App/polyfills-es5*",
                            "~/App/dist/App/runtime-es5*",
                            "~/App/dist/App/main-es5*"
                        ));
                }
            }
        

        更新

        我找到了一种通过替换脚本标记来动态切换它们的方法,这意味着您可以同时定位两者:

        @Scripts.RenderFormat("<script type=\"module\" src=\"{0}\"></script>", "~/Scripts/App-es2015")
        @Scripts.RenderFormat("<script src=\"{0}\" nomodule defer></script>", "~/Scripts/App-es5")
        

        【讨论】:

          猜你喜欢
          • 2020-03-07
          • 1970-01-01
          • 2023-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-07
          • 1970-01-01
          相关资源
          最近更新 更多