为模块包

时间:2016-11-30 09:01:15

标签: typescript systemjs typescript-typings systemjs-builder

我有点疑惑,为什么没有其他人有这个问题,或者我只是不用正确的词来描述它。问题是,我有一个模块,我发布到npm必须版本。一个可以通过system-js加载并直接从npm使用,另一个版本是我用system-js-builder创建的selfexecuting bundle。

让我们假设模块名为 @ company / foo 我在根文件夹中有一个index.ts,它只是从src导出所有内容,其中我还有一个index.ts,其中所有子模块都被导出。 所以index.ts看起来像这样。

export * from "./src/";

在我的模块中,我想使用它,我可以简单地使用以下内容。

import { bar } from "@company/foo";

到目前为止这么容易。不,我从索引创建一个自执行包并给它全局名称​​ foo 所以如果我将脚本添加到一个脚本中,我就可以调用 foo.bar()页面或与他人连接。这也很有效。但是现在我遇到了问题,我不知道如何为这个包创建打字。我的想法是做一些像

这样的事情
declare namespace foo {
    export * from "./src/";
}

我认为很好地描述了捆绑的作用。但打字稿并不喜欢这样。我也尝试过模块,但没有任何作用。我如何描述从我的src桶导出的内容以命名空间foo为前缀的事实?

我希望很清楚我想要实现的目标。

2 个答案:

答案 0 :(得分:1)

您需要在package.json中添加两个字段。

  1. main - 告诉模块加载器除了index.js以外模块的入口点是什么。
  2. typings - 为模块设置TypeScript定义文件。
  3. 例如,假设我们有一个模块@company/foo,其中包含package.json中的以下字段,

    {
        "main": "lib/bundle.js",
        "typings": "index.d.ts"
    }
    

    现在,在您的tsconfig.json中,您希望设置moduleResolution

    {
        "moduleResolution": "node"
    }
    

    @company/foo导入时,

    import { bar } from '@company/foo';
    

    index.d.ts中,您应该使用此行声明栏:

    declare function bar();
    

    TypeScript将尝试从bar中的定义中查找导出的符号node_modules/@company/foo/index.d.ts

    <强>更新

    以下是从不同模块重新导出单个函数/对象并导出命名空间的完整示例。该文件应该被称为index.d.tsmain.d.ts等,因此它被TypeScript识别为环境定义。

    import * as another from './src/another';
    declare namespace hello {
      function bar();
    
      interface ProgrammerIntf {
        work();
        walk();
        play();
      }
    
      class Programmer implements ProgrammerIntf {
        work();
        walk();
        play();
      }
    
      export import world = another.world;
    }
    
    export default hello;
    

    要在调用者脚本中使用此命名空间,

    import hello from '@company/foo';
    hello.bar();
    hello.world();
    let programmer = new hello.Programmer();
    

    更新2:

    我在TypeScript's documentation找到了一种方法,我之前没有注意到。

    您可以在global范围内声明所有类型,如下所示:

    import * as another from './src/another';
    
    declare global {
      namespace hello {
        function bar();
    
        interface ProgrammerIntf {
          work();
          walk();
          play();
        }
    
        class Programmer implements ProgrammerIntf {
          work();
          walk();
          play();
        }
    
        export import world = another.world;
      }
    }
    

    然后在调用者脚本中,只需使用:

    import '@company/foo';
    hello.bar();
    hello.world();
    let programmer = new hello.Programmer();
    

    当然,如果您将声明捆绑在捆绑包的开头,则应该能够直接使用hello而不使用import语句。

答案 1 :(得分:0)

如果我理解正确,您需要一个全局变量foo,其中包含module的所有导出成员。

您可以通过declare vartypeof来实现这一目标。

import * as _foo from './src'
declare var foo: typeof _foo
// implement self-executing logic

导入自执行代码后,全局变量foo将可用于正在编译的项目中的所有文件。

对于JavaScript文件,他们没有输入识别信息,因此只要您实现了逻辑,就可以访问foo