- CommonJS
- Uses require to load modules, and this is a regular function that can be used anywhere.
- A CommonJS module can import an ES6 module using the import function.
- JavaScript file names are usually .js, but this can change based on configuraton, and can be .cjs
- Supports __dirname and __filename global variables.
- Functions and data are exported by assigning to module.exports
- CommonJS modules are only supported on Node.js
- ES6 modules
- Uses import to load modules, and this is a statement that can only execute at the top level.
- The import statement supports loading both ES6 and CommonJS modules.
- JavaScript files are usually .mjs, but can be .js depending on configuration.
- Does not support __dirname and __filename, but these values can be computed from module.meta.url
- Functions and data are exported with the export statement.
- The ES6 Module module format is meant to be universal to all ECMAScript environments.
{
"compilerOptions": {
"lib": [ "es6", "es2021", "esnext" ],
"target": "es2021",
"module": "es2022",
"moduleResolution": "Node",
"esModuleInterop": true,
"outDir": "./dist",
"rootDir": "./lib",
"declaration": true,
"declarationMap": true,
"inlineSourceMap": true,
"inlineSources": true
}
}- The lib line describes the JavaScript language features to enable, with these settings saying to turn on all the latest features.
- The target parameter describes the code to generate. With this value, async/await functions are compiled using async/await keywords, rather than using Generator functions and the yield keyword.
- The module line describes the output module format which will be used, where es2022 ensures use of ES6 modules.
- The module line describes the output module format which will be used, where es2022 ensures use of ES6 modules.
- The moduleResolution parameter says to look up modules in node_modules directories just like NodeJS does.
- The outDir parameter says to compile files into the named directory, and the rootDir parameter says to compile the files in the named directory.
- The esModuleInterop fixes a few issues with compatibility between CommonJS and ES6 modules.
- The declaration and declarationMap parameters says to generate declaration files.
- The inlineSourceMap and inlineSources say to generate source-map data inside JavaScript source files.
{
...
"main": "./dist/example.js",
"type": "module",
"types": "./dist/example.d.ts",
"scripts": {
"build": "tsc",
"watch": "tsc --watch"
},
...
}- By default main shows index.js but we're generating dist/example.js instead. Remember that we configured the lib directory to contain TypeScript source, and that the dist directory will contain the compiled source. Notice that we're generating code in ES6 module format, but the file extension is .js rather than .mjs.
- Setting type to module causes Node.js to interpret .js files as ES6 modules.
- The type field makes it clear the JavaScript code is ES6 module format.
- The types field declares to the world that this module contains type definitions. It is good form to automatically generate type definitions, which the tsconfig.json file shown earlier does, and then make sure the world knows that type definitions are included.
- We've included a build script to run the compiler. The watch script starts a persistent process to automatically watch for file changes and recompile.
- Declaration files inform the TypeScript compiler about the types used in a JavaScript module. Otherwise the TypeScript compiler would be unable to offer much help when writing code against a JavaScript module. Therefore it is best for all JavaScript module authors to bundle TypeScript declaration files.
- This applies to cases where we generate a JavaScript module from TypeScript source. Making the resulting module useful to TypeScript requires declaration files.