systemjs导入出错
importing goes wrong with systemjs
我正在尝试在客户端和服务器中使用现有的 js 库 (validate.js)。
我使用 npm 安装它,所有内容都可以为服务器和客户端编译。
在服务器上使用它时效果很好,但是当我在浏览器中执行它时它会抛出错误。
两种情况下使用相同的文件:
import validate = require("validate.js");
export function RequestValidator(data: any): any {
return (validate as any)(data, constraints, { allowEmpty: true });
}
validate
被断言为 any
因为否则我得到:
TS2349: Cannot invoke an expression whose type lacks a call signature.
我使用的.d.ts
是:
declare module "validate.js" {
export interface ValidateJS {
(attributes: any, constraints: any, options?: any): any;
async(attributes: any, constraints: any, options?: any): Promise<any>;
single(value: any, constraints: any, options?: any): any;
}
export const validate: ValidateJS;
export default validate;
}
该模块仅导出一个函数,在服务器端运行良好,但在客户端调用此函数时我得到:
Uncaught TypeError: validate is not a function(…)
代码是使用目标 commonjs
为服务器编译的:
"use strict";
const validate = require("validate.js");
...
和system
客户:
System.register(["validate.js"], function(exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var validate;
...
return {
setters:[
function (validate_1) {
validate = validate_1;
}],
...
调试时,validate
确实不是一个函数,它是:
validate: r
EMPTY_STRING_REGEXP: (...)
get EMPTY_STRING_REGEXP: function()
set EMPTY_STRING_REGEXP: function()
Promise: (...)
get Promise: function()
set Promise: function()
__useDefault: (...)
get __useDefault: function()
set __useDefault: function()
async: (...)
get async: function()
set async: function()
capitalize: (...)
get capitalize: function()
set capitalize: function()
cleanAttributes: (...)
get cleanAttributes: function()
set cleanAttributes: function()
...
知道发生了什么以及为什么它在浏览器中以这种方式运行吗?
使用 "module": "system"
编译时,节点兼容导入
import validate = require("validate.js");
不再有效 - 您为 validate
获得的值是一个模块,而不是一个函数。这可能是打字稿中的错误,也可能是设计使然 - 我不知道。 (更新:来自 github 发给 JsonFreeman here 的评论,看起来像是设计使然:you get the module object with a set of properties including one named default
)。
有几种解决方法。
首先,您可以自己进行简单的转换 - 您需要的功能已作为模块的 default
属性 提供,因此这一行将修复它:
validate = validate.default ? validate.default : validate;
或者,您甚至可以使用 "module": "commonjs"
编译浏览器,这样 typescript 将生成工作代码,而 systemjs 将自动检测您的模块的格式。
或者最后,您仍然可以使用 "module": "system"
进行编译,但按照其输入中的预期导入 validate.js
:
import validate from 'validate.js';
这样你就不必对 any
进行任何转换,打字稿将为 default
属性 生成必要的访问权限,但缺点是它不起作用以这种方式导入时完全在节点中。
我正在尝试在客户端和服务器中使用现有的 js 库 (validate.js)。
我使用 npm 安装它,所有内容都可以为服务器和客户端编译。
在服务器上使用它时效果很好,但是当我在浏览器中执行它时它会抛出错误。
两种情况下使用相同的文件:
import validate = require("validate.js");
export function RequestValidator(data: any): any {
return (validate as any)(data, constraints, { allowEmpty: true });
}
validate
被断言为 any
因为否则我得到:
TS2349: Cannot invoke an expression whose type lacks a call signature.
我使用的.d.ts
是:
declare module "validate.js" {
export interface ValidateJS {
(attributes: any, constraints: any, options?: any): any;
async(attributes: any, constraints: any, options?: any): Promise<any>;
single(value: any, constraints: any, options?: any): any;
}
export const validate: ValidateJS;
export default validate;
}
该模块仅导出一个函数,在服务器端运行良好,但在客户端调用此函数时我得到:
Uncaught TypeError: validate is not a function(…)
代码是使用目标 commonjs
为服务器编译的:
"use strict";
const validate = require("validate.js");
...
和system
客户:
System.register(["validate.js"], function(exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var validate;
...
return {
setters:[
function (validate_1) {
validate = validate_1;
}],
...
调试时,validate
确实不是一个函数,它是:
validate: r
EMPTY_STRING_REGEXP: (...)
get EMPTY_STRING_REGEXP: function()
set EMPTY_STRING_REGEXP: function()
Promise: (...)
get Promise: function()
set Promise: function()
__useDefault: (...)
get __useDefault: function()
set __useDefault: function()
async: (...)
get async: function()
set async: function()
capitalize: (...)
get capitalize: function()
set capitalize: function()
cleanAttributes: (...)
get cleanAttributes: function()
set cleanAttributes: function()
...
知道发生了什么以及为什么它在浏览器中以这种方式运行吗?
使用 "module": "system"
编译时,节点兼容导入
import validate = require("validate.js");
不再有效 - 您为 validate
获得的值是一个模块,而不是一个函数。这可能是打字稿中的错误,也可能是设计使然 - 我不知道。 (更新:来自 github 发给 JsonFreeman here 的评论,看起来像是设计使然:you get the module object with a set of properties including one named default
)。
有几种解决方法。
首先,您可以自己进行简单的转换 - 您需要的功能已作为模块的 default
属性 提供,因此这一行将修复它:
validate = validate.default ? validate.default : validate;
或者,您甚至可以使用 "module": "commonjs"
编译浏览器,这样 typescript 将生成工作代码,而 systemjs 将自动检测您的模块的格式。
或者最后,您仍然可以使用 "module": "system"
进行编译,但按照其输入中的预期导入 validate.js
:
import validate from 'validate.js';
这样你就不必对 any
进行任何转换,打字稿将为 default
属性 生成必要的访问权限,但缺点是它不起作用以这种方式导入时完全在节点中。