2016-11-08 3 views
3

Я пытаюсь использовать существующую библиотеку js (validate.js) как на клиенте, так и на сервере.импорт идет не так с systemjs

Я установил его с помощью npm, и все скомпилировано как для сервера, так и для клиента.
При использовании его на сервере он отлично работает, но когда я его запускаю в браузере, он выдает сообщение об ошибке.

тот же файл используется в обоих случаях:

import validate = require("validate.js"); 

export function RequestValidator(data: any): any { 
    return (validate as any)(data, constraints, { allowEmpty: true }); 
} 

validate Утверждают any becuase иначе я получаю:

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

См. Последнее предложение в этом пункте на CommonJS: https://github.com/systemjs/systemjs/blob/master/docs/module-formats.md#commonjs. SystemJS не загружает модули CommonJS точно так же, как и NodeJS. Там '@ node', однако у меня нет личного опыта с этой черной магией. – martin

+0

@martin хорошо, разве это не денди. Мне особенно нравится: «это должно использоваться только тогда, когда оно абсолютно необходимо, поскольку оно перестает быть универсальным и делает его совместимым только с NodeJS». Итак, теперь я вынужден использовать 'jspm' также? –

+0

Я никогда не использовал этот вариант сам, я просто помню, видел, что он упоминается там ... – martin

ответ

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" даже для браузер, поэтому машинописный текст будет генерировать рабочий код, а systemjs автоматически определит формат для ваших модулей.

Или, наконец, еще можно было компилировать с "module": "system", но импортировать validate.js, как он предназначен в его типизации:

import validate from 'validate.js'; 

Таким образом, вы не должны делать никаких приведений в any и машинопись сгенерирует необходимо доступ для свойства default, но недостатком является то, что он не будет работать вообще в узле при импорте таким образом.

+0

Спасибо! Я закончил использование опции 'validate.default'. Было бы здорово импортировать его, как последний вариант, который вы дали, но, к сожалению, тот же код должен запускаться как в браузере, так и в узле. –

 Смежные вопросы

  • Нет связанных вопросов^_^