2016-11-08 4 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はbecuase 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; 
} 

モジュールは、機能のみをエクスポートし、それがサーバーにうまく動作しますが、この関数を呼び出すとき、クライアントに私が取得:

"use strict"; 
const validate = require("validate.js"); 
... 
Uncaught TypeError: validate is not a function(…) 

コードは、サーバのためのターゲットcommonjsを使用してコンパイルされています

とクライアントのための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は、NodeJSとまったく同じ方法でCommonJSモジュールをロードしません。 '@ node'はありますが、私はこの種の黒い魔法に個人的な経験はありません。 – martin

+0

@martinまあ、ダンディーではありません。私は特に気に入っています:「これは、コードが普遍的ではなく、NodeJSとしか互換性がないため、絶対に必要なときに使用してください。だから私は 'jspm'も使うように強制されているのですか? –

+0

私はそのオプションを自分で使ったことは一度もありませんでしたが、私はそこに言及したことを覚えています... – martin

答えて

3

あなたは"module": "system"でコンパイルすると、ノードと互換性のある輸入

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

は、もはや作品 - あなたがvalidateのためになっている値は、モジュール、関数ではなく。これはタイプスクリプトのバグかもしれませんし、設計上のバグかもしれません - わかりません。 (アップデート:JsonFreeman here宛てのgithubコメントから、それは設計上のようです:you get the module object with a set of properties including one named default)。

これを回避する方法はいくつかあります。

まず、あなたは簡単に変換を自分で行うことができます - あなたが必要とする機能は、モジュールのdefaultプロパティとして提供されているので、この行は、それを修正します。あなたものため"module": "commonjs"してコンパイルすることができます

validate = validate.default ? validate.default : validate; 

かを、ブラウザではtypescriptが作業コードを生成し、systemjsはモジュールのフォーマットを自動的に検出します。

それとも最後に、あなたはまだ"module": "system"でコンパイルしたが、それは、そのタイピングに意図されていますようvalidate.jsをインポートすることもできます

import validate from 'validate.js'; 

あなたがanyに任意のキャストを行う必要はありません、とtypescriptですが、必要に応じて生成されます。その方法defaultプロパティへのアクセスがありますが、欠点は、そのようにインポートされたときにノード内で全く機能しないことです。

+0

ありがとう!私は 'validate.default'オプションを使用して終了しました。最後に指定したオプションのようにインポートするのはすばらしいことですが、残念ながら同じコードをブラウザとノードの両方で実行する必要があります。 –

関連する問題