Automatic Import behavior in mixed CommonJS and ESM environments
0 reputation · 01 Jan 2021, 16:54 UTC
0 reputation · 01 Jan 2021, 16:54 UTC
WebStorm provides automatic import suggestions based on the project's module system. In large-scale TypeScript projects utilizing a mix of CommonJS and ECMAScript Modules (ESM), the IDE must resolve symbols across different module boundaries to provide accurate completion.
There is uncertainty regarding how the IDE prioritizes import styles when a symbol is available in both formats or when the tsconfig.json specifies a module system that conflicts with the local file's extension. This can lead to inconsistent suggestions where the IDE alternates between require() and import statements for the same dependency.
32775 reputation · 02 Jan 2021, 03:42 UTC
WebStorm prioritizes the individual file's module type over the project-level settings when generating automatic imports. The IDE determines the module system based on the following hierarchy:
.mjs files are treated as ESM; .cjs files are treated as CommonJS..js or .ts, the IDE looks for the nearest package.json containing "type": "module" (ESM) or "type": "commonjs" (CJS).module and moduleResolution settings in tsconfig.json guide the language server, but the file's perceived identity usually dictates whether the IDE suggests import or require().In mixed environments, inconsistency typically occurs because the IDE is attempting to maintain runtime compatibility. If a file is identified as CommonJS, WebStorm will suggest require() because import statements are syntactically invalid in CJS files (unless using dynamic import()). Conversely, in ESM files, require is not defined, forcing the IDE to suggest import.
When a symbol is available in both formats (a "dual package"), the IDE may alternate suggestions if the tsconfig.json resolution strategy (e.g., Node16 or NodeNext) is not strictly aligned with the actual file extensions used in the project.
To reduce inconsistency and enforce a specific style, adjust the following settings:
tsconfig.json, set "moduleResolution": "NodeNext" or "Node16". This forces the IDE to respect the package.json type field and file extensions more strictly.Settings > Editor > Code Style > TypeScript (or JavaScript). Under the Imports tab, ensure that "Use imports instead of require" is checked. Note that this will only apply to files the IDE recognizes as ESM..mts/.mjs for ESM and .cts/.cjs for CommonJS to remove ambiguity for the IDE's static analysis.To verify which module system Node.js is applying to a specific file (which should mirror the IDE's behavior), you can run a simple check for the require global:
node -e "try { console.log(typeof require); } catch (e) { console.log('ESM Environment'); }"
Diagnostic Detail Needed: To provide a more specific configuration, please specify the moduleResolution value currently defined in your tsconfig.json.
Use comments to ask for clarification. Post a solution as an answer.
5,020 reputation · 01 Jan 2021, 21:39 UTC
While the recent answer described how WebStorm derives a file’s perceived module system (extension → package.json → tsconfig), the IDE also applies a separate code‑style preference that can override the automatically generated import syntax.
In Settings/Preferences → Editor → Code Style → TypeScript → Imports (and the analogous JavaScript page) there is a toggle labelled Use ES6 import syntax. When enabled, WebStorm will suggest import … from … statements even if the tsconfig.json module option is set to commonjs or the file is treated as CommonJS by extension/package.json.
package.json has "type":"commonjs"), enabling the toggle will still produce import suggestions for automatic imports.tsconfig.json. It only changes the textual form of the generated import.Use ES6 import syntax option and observe the automatic import suggestion for a symbol from a CommonJS‑only package.