在 TypeScript 2.1 ES5 Webpack 中使用 es6-promise (async/await)
Using es6-promise with TypeScript 2.1 ES5 Webpack (async/await)
我尝试将 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 个错误
ERROR in [default] D:...\app.ts:4:16
Cannot find name 'Promise'.
我尝试了es6-promise
、es6-promises
、es6-promise-promise
和一堆导入表达式。
当我添加 import {Promise} from "es6-promise"
时,webstorm 将其突出显示为未使用的导入,但错误消失了。是否可以在不导入的情况下使用针对 ES5 的 Promises?因为在将目标更改为 ES6 之后,我必须触摸每个文件并删除导入。
异步问题
我的目标是能够使用 async/await,因为我从 C# 就习惯了它,而且我讨厌回调地狱。如果我将代码更改为
export class Foo {
async bar() : Promise<string>{
return "baz";
}
}
编译器再次报错
Cannot find name 'Promise'.
添加导入 import {Promise} from "es6-promise";
会使情况变得更糟。
Duplicate identifier 'Promise'. Compiler reserves name 'Promise' in top level scope of a module containing async functions.
您可以通过将 "es2015.promise"
添加到要包含在您的 tsconfig.json 中的库文件列表来让 TypeScript 编译器了解 ES2015 承诺:
{
"compilerOptions": {
"lib": [
"dom",
"es5",
"scripthost",
"es2015.promise"
]
}
}
本机承诺仅在 ES2015 中引入,在您的目标 ES5 中不可用。这就是 TypeScript 编译器说找不到名称 Promise
的原因。由于您提供了一个 polyfill,因此在运行时会有一个 Promise
。上面的解决方案让 TypeScript 意识到这一点。
编辑 Sven-Michael
您甚至不需要通过提供插件提供 Promise
。你只需要 import "es6-promise/auto";
你也可以使用 es6-promise polyfill。您可以通过以下方式(Typescript + Webpack2)引用它:
entry: {
'es6-promise',
'app': './app.ts',
}
我尝试将 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 个错误
ERROR in [default] D:...\app.ts:4:16 Cannot find name 'Promise'.
我尝试了es6-promise
、es6-promises
、es6-promise-promise
和一堆导入表达式。
当我添加 import {Promise} from "es6-promise"
时,webstorm 将其突出显示为未使用的导入,但错误消失了。是否可以在不导入的情况下使用针对 ES5 的 Promises?因为在将目标更改为 ES6 之后,我必须触摸每个文件并删除导入。
异步问题
我的目标是能够使用 async/await,因为我从 C# 就习惯了它,而且我讨厌回调地狱。如果我将代码更改为
export class Foo {
async bar() : Promise<string>{
return "baz";
}
}
编译器再次报错
Cannot find name 'Promise'.
添加导入 import {Promise} from "es6-promise";
会使情况变得更糟。
Duplicate identifier 'Promise'. Compiler reserves name 'Promise' in top level scope of a module containing async functions.
您可以通过将 "es2015.promise"
添加到要包含在您的 tsconfig.json 中的库文件列表来让 TypeScript 编译器了解 ES2015 承诺:
{
"compilerOptions": {
"lib": [
"dom",
"es5",
"scripthost",
"es2015.promise"
]
}
}
本机承诺仅在 ES2015 中引入,在您的目标 ES5 中不可用。这就是 TypeScript 编译器说找不到名称 Promise
的原因。由于您提供了一个 polyfill,因此在运行时会有一个 Promise
。上面的解决方案让 TypeScript 意识到这一点。
编辑 Sven-Michael
您甚至不需要通过提供插件提供 Promise
。你只需要 import "es6-promise/auto";
你也可以使用 es6-promise polyfill。您可以通过以下方式(Typescript + Webpack2)引用它:
entry: {
'es6-promise',
'app': './app.ts',
}