I am trying to understand the typescript module compiler option.
I went through typescript documentation - docs
It says module option is to Specify module code generation
.
What does that mean?
Does it mean if I put module option as commonjs
, then the compiler compiles the code to commonjs? But then we have options like esnext, es16
. After I went through Docs: Difference between esnext, es6, es2015 module targets, I understood that import() expressions are understood in esnext
. Anyway the purpose of compiler is to compile the code into browser understandable syntax(commonjs). So compiling code to the module type given doesn't make sense.
So does it mean the module type you give tells the compiler in what syntax the code is written? Meaning from which code it has to compile it to commonjs? But then we have module type commonjs
which is frequently used but we almost never write code in pure commonjs syntax.
what is the purpose of tsconfig.json? stackoverflow answer says module specifies module manager
. I don't understand what that means.
I also went through Understanding “target” and “module” in tsconfig and tsconfig module options - does 'System' refer to SystemJS?.
None of these seem to answer my question properly.
tsconfig.json
{
"compilerOptions: {
"module": "esnext"
}
}
CommonJS is a module formatting system. It is a standard for structuring and organizing JavaScript code. CJS assists in the server-side development of apps and it's format has heavily influenced NodeJS's module management.
In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).
ESNext import(...) statements are a transpiled into the output module format just like other module syntax such as ES2015 import and export statements. When you specify --module esnext , you are telling TypeScript not to transpile any module syntax at all.
The tsconfig. json file specifies the root files and the compiler options required to compile the project. JavaScript projects can use a jsconfig. json file instead, which acts almost the same but has some JavaScript-related compiler flags enabled by default.
TLDR; module
in tsconfig.json tells the compiler what syntax to use for the modules in the emitted .js files. Frequently used values are "commonjs"
(require/module.exports) or "ES2015"
(import/export keywords), but there are other module systems. module
affects the module syntax of emitted code while target
affects the rest.
Specify module code generation
mean?"module"
in tsconfig.json tells the Typescript (TS) compiler what module syntax
to use when the files are compiled to Javascript (JS).
When you set "module"
to "commonjs"
in tsconfig.json, this means that the modules in the compiled .js files will use the commonJS (CJS) syntax, so var x = require(...)
and module.exports = {...}
to import and export.
If you changed "module"
to "ES2015"
for example, the compiled code would use the import
and export
keywords used in ES2015 module syntax. For an overview of the other syntaxes you can take a look here.
There are several different module systems with CJS and the native ES Module (ESM) format probably being the ones most widely used. What to choose depends on your requirements. If it's for a server-side project that uses Node.js then probably CJS, if it's for an Angular front-end application than perhaps ESM (or their own NgModules but that's going beyond scope here). A somewhat similar situation is library and package designs and how you would like to expose them to consumers. This depends on what sort of users are going to consume the code, what are they working with (browser, Node) and which of the module systems is best suited for the job?
ES Modules are now the built-in standard for importing/exporting modules in JS but back when there was no native solution other module systems were designed: This is why we also have CJS, AMD and UMD modules around. They are not all obsolete, CJS is still used a lot in Node.js and the AMD module loader for example allows non-JS imports which can be useful in some cases. Nowadays, all the modern browsers and Node 13.2.0+ support the ESM format (see this page for compatibility data and more background on modules).
But then we have options like esnext
Newer JS versions sometimes contain more features for module import/export.
setting "module"
to "ESNext"
enables support for these features which often are not added to official specifications yet. Such as the import(...)
expression which is a dynamic import.
Does it mean if I put module option as commonjs, then the compiler compiles the code to commonjs?
The "module"
setting does not affect the rest of the code, "target"
is used for that instead and specifies what JS version the outputs should be compatible with.
This has been explained in other threads, I'm just adding it here for clarity.
Say you want to use require(...)
and module.exports = {...}
in a Node project but also want the code to utilise ES2015 features like let
and const
in the code (for readability/performance/other reasons).
In this case you would set "module"
to "commonjs"
and "target"
to "ES2015"
in tsconfig.
Anyway the purpose of compiler is to compile the code into browser understandable syntax(commonjs).
Yes, the compiler has to turn TS code into JS that a browser understands. However, JS is no longer limited to browsers, Node runs in other environments (servers) for example. CJS was in fact intended as a server-side module format while AMD modules were/are used for browser imports/exports.
So does it mean the module type you give tells the compiler in what syntax the code is written?
It tells the compiler in what syntax to write the modules in the output .js files
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With