You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
+
644
674
### The inferred type of "X" cannot be named without a reference to "Y". This is likely not portable. A type annotation is necessary
645
675
646
676
Let's say you use a package manager with strict dependencies:
0 commit comments