打字稿2 - 使用ES6导入&要求?

时间:2017-03-15 15:47:19

标签: javascript angular typescript module webpack

我在使用ES6模块的Angular2应用程序中导出了class

//File = init.todos.ts

export class Init {
   load() {
      ...
    }
}

我通过以下方式从其他组件导入此类:

//File = todo.service.ts

import { Init } from './init.todos'

它按预期工作。

但是,如果我将加载机制更改为commonjs:

//File = init.todos.ts
export class Init {
    load() {
       ...
    }
}
 module.exports.Init = Init;

要求:

//File = todo.service.ts
var  Init = require("./init.todos");

- 我收到了这些错误:

  

...对myApp / SRC /应用程序/ todo.service.ts   (4,13):找不到姓名'要求'。)   ... myApp / src / app / todo.service.ts(12,14):   财产'负载'在类型' TodoService'。)

上不存在

enter image description here

问题:

如何使用require加载commonjs模块?

Tsconfig.json:

{
    "compileOnSave": false,
    "compilerOptions": {
        "outDir": "./dist/out-tsc",
        "baseUrl": "src",
        "module": "system",
        "sourceMap": true,
        "declaration": false,
        "moduleResolution": "node",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "target": "es5",
        "typeRoots": [
            "node_modules/@types"
        ],
        "lib": [
            "es2016",
            "dom"
        ]
    }
}

以下是配置文件:

tslint.json

tsconfig.json

package.json

angular-cli.json

webpack.config.js

3 个答案:

答案 0 :(得分:1)

TypeScript符合ES6标准。在TypeScript源文件中使用ES6模块加载语法:

import  { SomeType } from './some.module';

当TypeScript编译为常规JavaScript时,您可以定位您选择的模块系统:

"compileOptions": {
    "module": "commonjs" (or system, umd, amd)
}

无论您选择哪种目标模块系统,都需要确保包含必要的脚本和配置以加载模块。即SystemJS,RequireJS等

作为练习,尝试定位不同的模块加载器,并检查.js文件 - 你会明白我的意思。

答案 1 :(得分:1)

version 1.5以来,Typescript采用了ES6的导入方式。

您可以按照"

保留您的代码
//File = init.todos.ts

export class Init {
   load() {
      ...
    }
}

//File = todo.service.ts

import { Init } from './init.todos'

通过将module中的属性tsconfig.json移动到commonjs,转换器将生成commonjs兼容的javascript,这将使您能够从整个nodeJS生态系统中受益并做出贡献。< / p>

"compileOptions": {
    ...
    "module": "commonjs"
    ...
}

如果您希望在打字稿代码中导入现有的NodeJS模块,可能会发生一些事情

  • 该模块附带了嵌入式打字稿定义文件(&#34;打字&#34;输入&#34; package.json&#34;)。在这种情况下,使用ES6语法导入模块,您可以去(import * as blah from 'blah')。 immutable.js是此类库的一个很好的例子

  • 该模块未附带定义文件,但DefinitelyTyped上有一个可用,只是

    • 运行npm install @types/blah以获取项目中的定义
    • 并照常导入模块:import * as blah from 'blah'
  • 模块没有定义文件

    • 您可以制作一个,只需在命名blah.d.ts后将其添加到您的项目中。 DefinitelyTyped在此
    • 上有a guide
    • 您可以决定不使用打字,只需使用NodeJS require()const blah = require('blah')blah将使用any类型(这实际上意味着blah已选择退出打字)

(为了完整起见,我可以添加自1.8以来可用的allowJS compiler option,但这本身就是一个完整的主题)

答案 2 :(得分:0)

你的问题的问题实际上不是require(...)method.it是你引用错误Init.I认为你想通过require lazy load模块。但你加载包含一个实例的类方法load(它不是类方法,如果你希望你必须将它声明为static)。所以你必须在使用它之前创建一个实例。默认情况下,require(...)return任何

declare function require(id: string): any;

如果你想正确推断typecript的类型,你必须声明require()返回类型,例如:let foo:typeof Foo = require('foo')。我发现当ts-jest除了{{1}之外的module测试通过因为它是延迟加载,不立即执行测试定义,所以我确定问题不是模块。这是我的测试代码:

测试

system