├── .gitignore
├── README.md
├── dist
├── anotherFile.js
├── anotherFile.js.map
├── index.js
└── index.js.map
├── package.json
├── renovate.json
├── src
├── anotherFile.ts
└── index.ts
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | yarn.lock
3 | .vscode
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Node ES Modules with TypeScript
2 |
3 | Latest Typescript and Node - as bare-bone as possible example app
4 |
5 | I wanted to start a simple Node project where I can install the latest things I want and using as little compilation from Typescript as possible.
6 |
7 | I remembered Node announced [Node 13 support ESModules without experimental flags](https://medium.com/@nodejs/announcing-core-node-js-support-for-ecmascript-modules-c5d6dc29b663), checked out the [official documentation](https://nodejs.org/api/esm.html) but couldn't find a simple bare bone example, so maybe that would help someone.
8 |
9 | I've committed the dist folder as well to see how the output from Typescript.
10 |
11 | Would love suggestions on how to make it better or to point to a better example!
12 |
13 | ## What I've done (so you can tell me what I should have done...)
14 |
15 | ### Node (package.json)
16 |
17 | - `type: module`: Tell Node that `.js` files are ES Modules. (When file extensions are .mjs then `type=module` is not required in package.json)
18 | - `----experimental-specifier-resolution=node`: Tell Node to enable the automatic extension resolution and importing from directories without specify the `.js` extension.
**Note:** By default, Node wants file extensions in import see: [TypeScript doesn't include file extension in it's output](https://github.com/microsoft/TypeScript/issues/16577)
19 |
20 | ### TypeScript (tsconfig.json)
21 |
22 | - `"module": "esnext"`: Make Typescript output ES Modules
23 | - `"target": "es2020"`: Highest target (from `3.8.0`)
24 |
25 | ## Run app
26 |
27 | 1. Install latest Node (Notice that I've placed the `engines` field on `package.json` so try to make sure you have the exact version or simply delete it from `package.json`
28 | 2. Install dependencies - `yarn`
29 | 3. Compile with `tsc -w` and run Node with `nodemon` - `yarn dev`
30 | 4. You can also use `yarn compile` and `yarn start` separately
31 |
32 | ## Want to import from a commonjs package?
33 |
34 | Here is a branch of the example with including a commonjs pacakge (`pg`):
35 |
36 | https://github.com/Urigo/typescript-node-es-modules-example/commit/98304173e964713955be3a92b4e355a857376dca
37 |
38 | > The [renovate.json](https://github.com/Urigo/typescript-node-es-modules-example/blob/master/renovate.json) file has nothing to do with the project itself. It's a file to activate [RenovateBot](https://github.com/renovatebot/renovate) to automatically PR this repository when a new version of any dependency of that project has been published
39 |
--------------------------------------------------------------------------------
/dist/anotherFile.js:
--------------------------------------------------------------------------------
1 | export const printSomething = async (textToPrint) => {
2 | console.log(`Inside ${textToPrint}`);
3 | };
4 | //# sourceMappingURL=anotherFile.js.map
--------------------------------------------------------------------------------
/dist/anotherFile.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"anotherFile.js","sourceRoot":"","sources":["../src/anotherFile.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,WAAmB,EAAE,EAAE;IACxD,OAAO,CAAC,GAAG,CAAC,UAAU,WAAW,EAAE,CAAC,CAAC;AACzC,CAAC,CAAC"}
--------------------------------------------------------------------------------
/dist/index.js:
--------------------------------------------------------------------------------
1 | import { printSomething } from './anotherFile';
2 | console.log('hello world');
3 | printSomething('new string from function in another file');
4 | //# sourceMappingURL=index.js.map
--------------------------------------------------------------------------------
/dist/index.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAE3B,cAAc,CAAC,0CAA0C,CAAC,CAAC"}
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "module",
3 | "scripts": {
4 | "start": "node --experimental-specifier-resolution=node dist/index.js",
5 | "dev": "tsc && concurrently \"tsc -w\" \"nodemon --experimental-specifier-resolution=node dist/index.js\"",
6 | "build": "tsc"
7 | },
8 | "dependencies": {},
9 | "devDependencies": {
10 | "@types/node": "14.0.4",
11 | "concurrently": "5.2.0",
12 | "nodemon": "2.0.4",
13 | "typescript": "3.9.3"
14 | },
15 | "engines": {
16 | "node": "14.3.0"
17 | },
18 | "license": "MIT"
19 | }
20 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/src/anotherFile.ts:
--------------------------------------------------------------------------------
1 | export const printSomething = async (textToPrint: string) => {
2 | console.log(`Inside ${textToPrint}`);
3 | };
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { printSomething } from './anotherFile';
2 |
3 | console.log('hello world');
4 |
5 | printSomething('new string from function in another file');
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "esnext",
4 | "target": "es2020",
5 | "strict": true,
6 | "sourceMap": true,
7 | "outDir": "dist"
8 | },
9 | "include": ["src/**/*"]
10 | }
11 |
--------------------------------------------------------------------------------