首页 文章

如何使用JSPM导入带有Typescript声明的外部NPM模块

提问于
浏览
3
  • 'test-module'是使用index.d.ts定义文件在Typescript中编写的外部模块 . 它在package.json中具有tsd / tsc的属性:

“typings”:“dist / index.d.ts”,“typescript”:{“definition”:“dist / index.d.ts”}

  • 'test-module'随JSPM一起安装在jspm_packages / npm / test-module中,用于使用SystemJS进行动态加载

  • 'app'是要导入'test-module'的Typescript应用程序,如下所示:

从'test-module'导入;

问题是'test-module'模块在两个位置都有:

node_modules _for_in文件编译器中的

  • (否则它找不到'test-module'并在从'test-module'编译导入时出错)

jspm_packages

  • 中,SystemJS在运行时加载它

所以,我需要在package.json'dependencies'和'jspm / dependencies'中插入它

有没有黑客:

A)强制JSPM / SystemJS只使用标准的 node_modules 文件夹? (我知道我可以使用原始的SystemJS并映射node_modules,但这意味着我必须为依赖的每个依赖关系和依赖关系映射它,这是很多手工工作)

OR

B)使用某种路径映射强制使用Typescript搜索模块(我猜版本1.8将具有此功能)

有任何想法吗?

1 回答

  • 1

    这是我不喜欢的答案,但这是一个解决方法 . 事实上,在搜索我的案例答案时,我遇到了你的问题,它们是相似的 .

    在我的例子中,我也创建了一个外部库,该库使用typescript编译,生成的模块将在外部jspm项目中使用 .

    对我有用的是使用与javascript es6相同的语法导入库 . 假设该库名为myLib并且具有myLib = blabla的config.js映射,并且您有一个名为notify.js的文件(从typescript生成) . 进口是

    import Notify from 'myLib/notify'
    

    在运行时它可以工作,但问题是项目的编译器找不到'myLib/notify' . typescript生成的定义(库的文件 jspm_package/github/myLib/myLib@version/notify.d.ts 类似于:

    export declare enum NotifyStatus {
        INFO = 0,
        SUCCESS = 1,
        WARNING = 2,
        DANGER = 3,
    }
    export declare enum NotifyPosition {
        TOP_CENTER = 0,
        TOP_LEFT = 1,
        TOP_RIGHT = 2,
        BOTTOM_CENTER = 3,
        BOTTOM_LEFT = 4,
        BOTTOM_RIGHT = 5,
    }
    /**
     * Class for notifications
     */
    export declare class Notify {
        /**
         * Show a default Notification in the page
         * @param  {string}            message      The message
         * @param  {NotifyStatus   =            NotifyStatus.INFO} status   Status to style the message
         * @param  {[type]}            timeout=5000 Timeout
         * @param  {NotifyPosition =                                NotifyPosition.TOP_CENTER} pos        Position to display the message
         * @return {NotifyMessage}                  A object representing the message on the DOM
         */
        static show(message: string, status?: NotifyStatus, timeout?: number, pos?: NotifyPosition): NotifyMessage;
        private static getStatusString(status);
        private static getPositionString(position);
    }
    export interface DialogModal {
        show(): any;
        hide(): any;
    }
    

    为了解决这个问题,我手动修改了库声明中的定义包装:

    declare module 'myLib/notify' {
    export declare enum NotifyStatus {
        INFO = 0,
        SUCCESS = 1,
        WARNING = 2,
        DANGER = 3,
    }
    export declare enum NotifyPosition {
        TOP_CENTER = 0,
        TOP_LEFT = 1,
        TOP_RIGHT = 2,
        BOTTOM_CENTER = 3,
        BOTTOM_LEFT = 4,
        BOTTOM_RIGHT = 5,
    }
    /**
     * Class for notifications
     */
    export declare class Notify {
        /**
         * Show a default Notification in the page
         * @param  {string}            message      The message
         * @param  {NotifyStatus   =            NotifyStatus.INFO} status   Status to style the message
         * @param  {[type]}            timeout=5000 Timeout
         * @param  {NotifyPosition =                                NotifyPosition.TOP_CENTER} pos        Position to display the message
         * @return {NotifyMessage}                  A object representing the message on the DOM
         */
        static show(message: string, status?: NotifyStatus, timeout?: number, pos?: NotifyPosition): NotifyMessage;
        private static getStatusString(status);
        private static getPositionString(position);
    }
    export interface DialogModal {
        show(): any;
        hide(): any;
    }
    }
    

    我的 tsconfig.json 文件配置为在jspm_packages中查找定义

    然后编译停止警告,Atom编辑器提供intellisense .

    这种方法存在两个问题:

    • 手动制作包装(这很烦人)

    • myLib 在定义中是手写的,并且可以通过SystemJS和jspm覆盖't be changed for other location, we must use import ' myLib / bla ' and in reality ' myLib'到其他引用 .

    我正在搜索的是一种使用模块声明自动生成打字稿定义的方法 .

    我遇到了这个https://www.npmjs.com/package/autodts但是我不完全理解它是如何工作的,但它可以用来以这种方式自动生成定义文件 .

    编辑:

    我创建了一个gulp任务来编辑typescript定义文件并添加自动添加声明模块 . 方法如下:

    var gulp = require('gulp');
    var runSequence = require('run-sequence');
    var ts = require('gulp-typescript');
    var paths = require('../paths');
    var through2 = require('through2');
    var concat = require('gulp-concat');
    var insert = require('gulp-insert');
    var rename = require('gulp-rename');
    var merge = require('merge2');
    var modify = require('gulp-modify');
    
    var tsProjectAmd = ts.createProject('tsconfig.json', {module: 'amd'});
    var tsProjectES6 = ts.createProject('tsconfig.json', {module: 'es6'});
    var tsProjectCOMMONJS = ts.createProject('tsconfig.json', {module: 'commonjs'});
    var tsProjectSystem = ts.createProject('tsconfig.json', {module: 'system'});
    
     var makeBuild = function(project, format, path, output){
      return function(){
        var tsResult =  gulp.src(path)
          .pipe(ts(project));
        return merge([
          tsResult.js.pipe(gulp.dest(output + format)),
          tsResult.dts.pipe(modify({
            fileModifier: function(file, content){
              // Split at /dist/ caracter
              var regex = new RegExp("/" + paths.dist);
              var split = file.path.split(regex);
              // Remove ".d.ts";
              var fileNameAndPath = split[1].slice(0, split[1].length - 5);
              if(fileNameAndPath != paths.packageName){
                return  'declare module "' + paths.packageName + "/" + fileNameAndPath + '" {\n' + content + '\n}';
              }else {
                return content;
              }
    
            }
          })).pipe(gulp.dest(output + format))
        ]);
      }
    }
    
    
    gulp.task('build-amd', makeBuild(tsProjectAmd, '', paths.source, paths.output));
    

    paths.js

    var path = require('path');
    var fs = require('fs');
    
    var appRoot = 'src/';
    var outputRoot = 'dist/src/';
    var pkg = JSON.parse(fs.readFileSync('./package.json', 'utf-8'));
    
    module.exports = {
      root: appRoot,
      source: [appRoot + '**/*.ts','typings/**/*.ts'],
      html: appRoot + '**/*.html',
      style: outputRoot + 'css/**/*.css',
      styles: outputRoot + 'css/',
      less: ['less/theme/**/*.less','!less/theme/_variables.less'],
      fonts: 'less/uikit/src/fonts/*',
      images: 'images/**/*',
      output: outputRoot,
      doc:'./docs',
      apiDoc: './api-doc',
      dist: 'dist/',
      testsFixtures: 'test/fixtures/*',
      specsSrc: 'test/**/*.ts',
      specsOutput: 'dist/',
      packageName: pkg.name
    };
    

相关问题