systemjs导入错误

时间:2016-11-08 10:11:00

标签: javascript typescript 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:无法调用类型缺少调用签名的表达式。

我正在使用的.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()
    ...

知道发生了什么以及为什么它在浏览器中以这种方式运行?

1 个答案:

答案 0 :(得分:3)

使用"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进行任何强制转换,而typescript会为default属性生成必要的访问权限,但缺点是它在导入时在节点中根本不起作用那样。