简体   繁体   English

有关将commonJS和ES6模块系统混合的几个问题

[英]few questions on mixing the commonJS and ES6 module system

My questions are around working with commonJS (node style) and ES6 modules (using typescript). 我的问题是与commonJS(节点样式)和ES6模块(使用打字稿)一起使用。 I have this angular 1.5 app which uses the commonJS module system. 我有这个使用commonJS模块系统的1.5版本应用程序。 I attempted to use typescript for creating just one of the factories in the app. 我试图使用打字稿在应用程序中仅创建工厂之一。 Few questions on the same. 很少有相同的问题。

  1. Can we use typescript import keyword to import a module exported using the commonJS module.exports syntax? 我们可以使用typescript import关键字来导入使用commonJS module.exports语法导出的模块吗? For example, say we have RandomService.js below that we wish to use in our typescript file. 例如,假设下面有我们想要在打字稿文件中使用的RandomService.js。 I noticed that doing an import * as randomservice from '../../services/RandomService.js' threw some errors related to not being able to find the module. 我注意到,从'../../services/RandomService.js'导入*作为randomservice会引发一些与无法找到模块有关的错误。 I got this to work by using a require(), but just wanted to know if this can be done in typescript? 我通过使用require()使其工作,但只是想知道是否可以在打字稿中完成?

     var randomString = require('random-string'); module.exports = { getSuperRandom: function() { var x = 'super-random-' + randomString(); return x; } } 
  2. When we export a module from a typescript file usually the exports object has a property which holds our object. 当我们从打字稿文件中导出模块时,导出对象通常具有保存我们的对象的属性。 Even doing an export default results in the .default property having our exported object. 即使执行导出默认设置,也会导致.default属性具有我们的导出对象。 Is there anyway where we can set the exported object directly to the exports object (just like we can do in commonJS module system where we do module.exports = 'helloservice')? 无论如何,我们可以直接将导出的对象设置为导出对象(就像我们可以在commonJS模块系统中那样执行module.exports ='helloservice'一样)吗?

  1. Yes it's possible to import commonJS modules written in javascript, but only if typescript compiler can find declarations for these modules. 是的,可以导入用javascript编写的commonJS模块,但前提是Typescript编译器可以找到这些模块的声明

For example, if you have this javascript module in module1.js : 例如,如果您在module1.js有此javascript模块:

exports.f = function(s) {
    return s.length
}

you have to provide declaration file that describes the module and defines types for its exports, in file module1.d.ts : 您必须在文件module1.d.ts提供描述模块并定义其导出类型的声明文件:

export declare function f(s: string): number;

Then you can use this module with import . 然后,您可以将此模块与import Typescript will find imported module if you put this code in test.ts file in the same directory as module1.d.ts : 打字稿会发现进口的模块,如果你把这个代码test.ts在同一个目录中的文件module1.d.ts

import * as module1 from './module1';

let n: number = module1.f('z');

If you compile this code with --module=commonjs (which is the default), you will get pretty normal commonjs code as a result: 如果使用--module=commonjs (这是默认设置)编译此代码,结果将得到非常普通的commonjs代码:

"use strict";
var module1 = require('./module1');
var n = module1.f('z');
  1. If your module exports some object, for example like this module2.js : 如果您的模块导出某些对象,例如类似于module2.js

      module.exports = { a: 'a', n: 1 }; 

it's better to avoid importing it using es6 syntax - es6 always assumes that module exports a namespace, not an object. 最好避免使用es6语法导入它-es6始终假定模块导出的是名称空间,而不是对象。 In typescript, there is special syntax called import require for that: 在打字稿中,有一种特殊的语法称为import require

import m2 = require('./module2');

let n1: string = m2.a;

the declaration file, module2.d.ts , must use export assignment syntax: 声明文件module2.d.ts必须使用export assignment语法:

export = {} as {a: string, n: number};

The actual value, {} , does not matter in the declaration file and can be anything - only the type matters (which is given as type cast to unnamed interface). 实际值{}在声明文件中无关紧要,可以是任何东西-仅类型重要(以类型转换为未命名接口的形式给出)。

If a module exports a string, as in your example, the declaration can be as simple as 如果模块输出一个字符串(如您的示例中所示),则声明可以很简单

export = '';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM