7

It seems that using tsc with compilerOptions.module set to None or CommonJS is producing the same transpiled code. How do these two differ? Why are there two options for producing (apparently) the same transpiled code?

aryzing
  • 4,982
  • 7
  • 39
  • 42

1 Answers1

7

With module set to None, we cannot use imports, exports, or module augmentations (except for the way that @artem notes in the below comments.)

Here is the source of the message.

"Cannot use imports, exports, or module augmentations when '--module' is 'none'.": {
    "category": "Error",
    "code": 1148
},

With module set to CommonJS, if we choose not to use imports, exports, or module augmentations, then our output might look the same as it does when we set module to None.

Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467
  • How strict is the statement "*cannot* use imports"? because I did not know this, and I used them anyway, the compiler did not error out, and the result was identical to setting `module` to `CommonJS` – aryzing Aug 22 '17 at 18:19
  • @aryzing Good point. I tested just now. The ban on `export` seems strict whereas the use of `import` seems allowed. – Shaun Luttin Aug 22 '17 at 18:24
  • 2
    It's actually "can't have any imports or exports at the top level". Imports and exports inside namespaces are fine because they don't export anything from `.ts` file at runtime, and as long as file remains 'not a module' `module=None` works fine. Long explanation here: https://stackoverflow.com/a/38666021/43848 – artem Aug 22 '17 at 19:51
  • @artem In a test using TypeScript 2.4.1, an import inside a namespace gave the error: "Import declarations in a namespace cannot reference a module." Inside `foo.ts` was `namespace test { import "./bar"; }` and inside `bar.ts` was `namespace test { export const x = 10; }`. The error occurred in `foo.ts` even when the `bar.ts` was empty. Can you provide an example of a working import inside a namespace when module is set to none? – Shaun Luttin Aug 27 '17 at 13:52
  • 2
    with `module=none` you can use only import assignment for creating [aliases](https://www.typescriptlang.org/docs/handbook/namespaces.html#aliases), you can't import from modules. Example: file `a.ts`: `namespace A { import b = B.b; console.log(b); ` file `b.ts`: `namespace B { export var b = 'b' }` compile with `tsc --module none --outFile o.js b.ts a.ts` . This part of language predates ES modules and is now mostly of historical interest. Also, when doing this, you are supposed to use `reference` directives to ensure proper initialization order at runtime. – artem Aug 27 '17 at 15:54
  • @artem Perfect. That's what I needed. – Shaun Luttin Aug 27 '17 at 15:56