Skip to content

Commit ad67359

Browse files
committed
Updated FAQ (markdown)
1 parent 756ece4 commit ad67359

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

FAQ.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,36 @@ node_modules/@types/node/child_process.d.ts:73:15 - error TS2430: Interface 'Chi
641641
~~~~~~~~~~~~
642642
```
643643

644+
### What does error TS1287 mean?
645+
646+
Search Terms: "A top-level 'export' modifier cannot be used on value declarations in a CommonJS module when 'verbatimModuleSyntax' is enabled.";
647+
TypeScript 5.9: "A CommonJS module cannot use ESM syntax when 'verbatimModuleSyntax' is enabled. Consider adding "type": "module" to package.json"
648+
649+
**TL;DR**
650+
* If you're writing an ESM NodeJS app, add `"type": "module"` to `package.json`
651+
* If you're not sure what to do, start by trying this
652+
* If you're writing a CommonJS NodeJS app, either write `import fs = require("fs");` or disable `verbatimModuleSyntax`
653+
* If you're using a bundler, change `module` to `preserve` in `tsconfig.json`
654+
* If you're writing ESM directly for web, change `module` to `esnext` in `tsconfig.json`
655+
656+
The `verbatimModuleSyntax` flag enforces that CommonJS (CJS) modules use CJS syntax (`import fs = require('fs');`), and ES Modules (ESM) use ESM syntax (`import * as fs from 'fs';`).
657+
This is generally a good flag to enable, because some packages expose different API to CJS and ESM.
658+
By enabling `verbatimModuleSyntax`, you can be sure that when you see CJS syntax you're getting the CJS version of the module, and likewise for ESM.
659+
660+
However, two things interact in a way that can be surprising.
661+
662+
The first fact is that most people tend to write ESM syntax these days.
663+
664+
The second is that NodeJS has a complex set of rules for determining when a file with a .js extension is CJS or ESM:
665+
666+
* If package.json doesn't exist, files are CJS unless they have a top-level import or export statement, in which case they're silently re-interpreted as ESM
667+
* If package.json exists but has no `type` field, the same rule applies, except you'll see a warning on stdout
668+
* Note that older versions of `npm init` do not set a `type` field
669+
* If package.json exists and set `type`, the file is always of that type
670+
* Newer versions of `npm init` set the `type` field to `"commonjs"` by default
671+
672+
This means that unless you've explicitly taken some step to opt into ESM modules (either by setting `"type": "module" or naming your file `.mts`), Node.js will treat your files as CommonJS modules.
673+
644674
### The inferred type of "X" cannot be named without a reference to "Y". This is likely not portable. A type annotation is necessary
645675

646676
Let's say you use a package manager with strict dependencies:

0 commit comments

Comments
 (0)