Systemjs Bundle 全局导入配置
Systemjs Bundle Global Import Config
我正在使用 Typescript、ES6 模块语法和 SystemJS / builder。
我尝试做的基本要求是:
- 使用@types 包启用 typescript 代码补全(也适用于全局 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 导入,我不断收到诸如“_.clone 不是函数”之类的错误
{default: _ } //_ is the actual lodash export
我已成功将导入更改为 import _ from 'lodash'
但后来我得到 IDE 错误,因为 lodash(也没有任何其他全局脚本,如 angular)不导出默认值,我失去了代码完成。
这里用systemjs/builder满足需求的正确方法是什么?
附带说明一下,如果使用脚本标签加载而不是 systemjs CDN 导入效果更好的话,我很满意。
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 互操作提案,如果您像 _([1, 2]).map(x => x ** 2)
中那样调用它,也违反了禁止调用模块命名空间对象的 ES 规范。利用 --allowSyntheticDefaultImports
标志和 SystemJS 提供的互操作性。
我正在使用 Typescript、ES6 模块语法和 SystemJS / builder。
我尝试做的基本要求是:
- 使用@types 包启用 typescript 代码补全(也适用于全局 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 导入,我不断收到诸如“_.clone 不是函数”之类的错误{default: _ } //_ is the actual lodash export
我已成功将导入更改为 import _ from 'lodash'
但后来我得到 IDE 错误,因为 lodash(也没有任何其他全局脚本,如 angular)不导出默认值,我失去了代码完成。
这里用systemjs/builder满足需求的正确方法是什么?
附带说明一下,如果使用脚本标签加载而不是 systemjs CDN 导入效果更好的话,我很满意。
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 互操作提案,如果您像 _([1, 2]).map(x => x ** 2)
中那样调用它,也违反了禁止调用模块命名空间对象的 ES 规范。利用 --allowSyntheticDefaultImports
标志和 SystemJS 提供的互操作性。