0

我正在使用 Typescript、ES6 模块语法和 SystemJS / builder。

我想要做的基本要求是:

  • 使用 @types 包启用打字稿代码完成(也适用于全局 npm 安装)
  • 使用 ES6 模块导入语法(例如import * as _ from 'lodash'
  • 让构建器从构建中排除全局变量,并在开发/生产中使用 CDN url 正确导入它们。

我用于构建和开发/生产环境的配置只是为了让它运行起来:

System.config({
  meta: {
    "lodash": {
      "format": "global",
      "build": false,
      "exports": "_"
    }
    // ...more meta
  }, 
  map: {
    "lodash": "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js",
     // ...more maps
  }
});

从这里我有一个 npm 任务,它转译为 ES6,然后通过 babel 插件将所有内容捆绑到一个文件中。该脚本直接加载到生产页面上并加载。问题是,一旦全局依赖项导入,由于 systemjs 将 CDN 导入与像

{default: _ } //_ is the actual lodash export

我已经成功地将导入更改为,import _ from 'lodash' 但随后出现 IDE 错误,因为 lodash(也没有任何其他全局脚本,如 angular)没有导出默认值,并且我失去了代码完成。

在这里使用 systemjs / builder 满足要求的正确方法是什么?

作为旁注,如果效果更好,我可以使用脚本标签加载而不是 systemjs CDN 导入。

4

1 回答 1

1

TypeScript 仅针对这种情况有一个标志--allowSyntheticDefaultImports。具体来说,它通知类型检查器另一个转译器、加载器或捆绑器在稍后的步骤中提供module.exports映射exports.default

您可以在tsconfig.json的编译器选项下指定此标志

{
  "compilerOptions": {
    "target": "esnext",
    "module": "es2015",
    "allowSyntheticDefaultImports": true,
    "moduleResolution": "node",
    "baseUrl": "."
  }

请注意,当模块格式设置为 时"system",会隐式设置此标志。

现在你可以写

import _ from "lodash";

TypeScript 会理解它,对它进行类型检查,并验证它是否被正确使用。但是,这只影响类型检查。您仍然需要并且在这种情况下已经拥有提供运行时综合的加载器或中间转译器。

import * as _ from "lodash";

违反了提议的 NodeJS -> ESM 互操作提议,并且,如果您将其称为 in_([1, 2]).map(x => x ** 2)也违反了禁止调用模块命名空间对象的 ES 规范。因此,您可以很好地利用--allowSyntheticDefaultImportsSystemJS 提供的标志和互操作.

于 2017-05-14T04:13:23.797 回答