【问题标题】:Using es6-promise with TypeScript 2.1 ES5 Webpack (async/await)使用 es6-promise 和 TypeScript 2.1 ES5 Webpack (async/await)
【发布时间】:2017-07-14 02:08:01
【问题描述】:

我尝试将es6-promise 与针对 ES5 和 webpack 的 TypeScript 2.1.1 一起使用。

app.ts

import "es6-promise/auto";

export class Foo {
    bar() : Promise<string>{
        return Promise.resolve("baz");
    }
}

webpack.common.js

const path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: {
        'app': './app.ts',
    },

    output: {
        path: 'dist/ie',
        filename: '[name].js'
    },

    resolve: {
        extensions: ['', '.ts', '.js']
    },

    devtool: 'source-map',

    module: {
        loaders: [
            {
                test: /\.ts$/,
                loaders: ['awesome-typescript-loader']
            },
        ]
    },
    plugins: [  
        new webpack.ProvidePlugin({
            Promise: 'imports?this=>global!exports?global.Promise!es6-promises'
        }),

    ]
};

package.json

{
  "name": "foo",
  "ieArtifactName": "foo",
  "version": "3.0.0-1",
  "description": "...",
  "main": "src/app.ts",
  "author": {
    "name": "...",
    "email": "...",
    "url": "..."
  },
  "dependencies": {
    "@types/es6-promise": "0.0.32",
    "@types/jquery": "^2.0.34",
    "@types/underscore": "^1.7.34",
    "es6-promise": "^4.0.5",
    "es6-promise-promise": "^1.0.0",
    "es6-promises": "^1.0.10",
    "rxjs": "5.0.0-beta.12",
    "zone.js": "^0.6.23"
  },
  "devDependencies": {
    "awesome-typescript-loader": "=2.2.4",
    "clean-webpack-plugin": "^0.1.14",
    "css-loader": "^0.26.0",
    "exports-loader": "^0.6.3",
    "http": "0.0.0",
    "https": "^1.0.0",
    "imports-loader": "^0.6.5",
    "load-grunt-tasks": "^3.5.2",
    "node-static": "^0.7.9",
    "pug": "^2.0.0-beta6",
    "pug-html-loader": "^1.0.9",
    "raw-loader": "^0.5.1",
    "sass-loader": "^4.0.2",
    "style-loader": "^0.13.1",
    "typescript": "^2.1.1",
    "webpack": "^1.13.3",
    "webpack-dev-server": "^1.14.1",
    "webpack-merge": "^0.14.0"
  }
}

我使用命令行启动 webpack

webpack --config config/webpack.common.js

行为如下:

  • Webstorm 2016.3.1 突出显示一切正常。
  • 编译器运行
  • 编译器显示 2 个错误

    [默认] D:...\app.ts:4:16 中的错误 找不到名称“Promise”。

我尝试了es6-promisees6-promiseses6-promise-promise和一堆导入表达式。

当我添加 import {Promise} from "es6-promise" webstorm 时将其突出显示为未使用的导入,但错误消失了。是否可以在不导入的情况下使用针对 ES5 的 Promises?因为在将目标更改为 ES6 后,我必须触摸每个文件并删除导入。

异步问题

我的目标是能够使用 async/await,因为我在 C# 中已经习惯了它,而且我讨厌回调地狱。如果我将代码更改为

export class Foo {
    async bar() : Promise<string>{
        return "baz";
    }
}

编译器又报错了

找不到名称“Promise”。

添加导入 import {Promise} from "es6-promise"; 会使情况变得更糟。

重复的标识符“承诺”。编译器在包含异步函数的模块的顶级范围内保留名称“Promise”。

【问题讨论】:

  • 这应该回答你的问题:stackoverflow.com/questions/27573365/…
  • 嗯,答案的一条评论有帮助。添加对 app.ts 中输入的引用有所帮助。 ///&lt;reference path="../node_modules/@types/es6-promise/index.d.ts" /&gt;。我不必在任何文件中导入它。
  • 你也应该这样做: entry: { 'es6-promise', 'app': './app.ts', },

标签: typescript promise webpack async-await ecmascript-5


【解决方案1】:

您可以通过将 "es2015.promise" 添加到要包含在 tsconfig.json 中的库文件列表中,使 TypeScript 编译器了解 ES2015 承诺:

{
    "compilerOptions": {
        "lib": [
            "dom",
            "es5",
            "scripthost",
            "es2015.promise"
        ]
    }
}

Native Promise 仅在 ES2015 中引入,并且在您所针对的 ES5 中不可用。这就是 TypeScript 编译器说它找不到名称 Promise 的原因。由于您提供了一个 polyfill,因此在运行时会有一个 Promise。上面的解决方案让 TypeScript 意识到了这一点。

编辑斯文-迈克尔

您甚至不需要通过提供插件提供Promise。你只需要import "es6-promise/auto";

【讨论】:

  • 我认为这是一个不正确的解决方案。真正的打字稿会意识到 ES6 的承诺。但编译器目标仍然是 ES5。当我们在 ES5 浏览器上使用编译好的脚本时,会报错Promise not found。
  • 这里的关键部分是 “既然你提供了一个 polyfill,那么运行时就会有一个 Promise。” TypeScript 本身不会填充 Promise;因此,you 需要提供一个 polyfill,以便 Promise 即使在旧版浏览器中也能在运行时可用。 lib 编译器选项只告诉 TypeScript 它可以期望在运行时有一个工作的Promise
【解决方案2】:

你也可以使用 es6-promise polyfill。您可以通过以下方式引用它(Typescript + Webpack2):

entry: {
    'es6-promise',    
    'app': './app.ts',
}

【讨论】:

    猜你喜欢
    • 2017-03-22
    • 1970-01-01
    • 2017-04-26
    • 2020-05-19
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2021-05-13
    相关资源
    最近更新 更多