Skip to content

Flag for ESM loader to override package.json "type" #1342

@cspotcode

Description

@cspotcode

Desired Behavior

Allow running e.g a webpack.config.ts as CommonJS in an otherwise ESM project.

ESM hook can be configured to override package.json "type" field for certain files to accomplish this.

Is this request related to a problem?

In a project:
using webpack.config.ts
with package.json "type": "module" and tsconfig "module": "esnext"
using ts-node's ESM loader for unit tests
does not want to pass NODE_OPTIONS=--loader ts-node/esm to webpack

In these projects, package.json is forcing all .ts files to execute as ESM. Attempting to require them will throw ERR_REQUIRE_ESM (#1232) This means webpack.config.ts always fails: webpack tries to require it, gets the error, tries to import it, and it fails because the emitted JS calls require in an ESM context.

We can enable our ESM loader to override package.json "type"

Possible solutions

Ways to do this:

  • set glob patterns to match; those files get overridden "type"
  • simple boolean; if true, "type" always matches compilerOptions; never package.json
//tsconfig.json
{
  "ts-node": {
    // modelled after "files", "include", "exclude" configs: can use globs, all relative to tsconfig.json
    // modelled after gitignore / gitattributes: later entries override earlier ones
    "moduleTypes": {
      "webpack.config.ts": "commonjs"
    }
  }

If webpack.config.ts loads other files, they may also need the override.
Would require: "moduleTypes": {"*": "commonjs"} in a special webpack-only tsconfig (or make a special test-only tsconfig without it)

Needs to play nice with eventual composite project support.

Alternatives considered

  • Projects can place their webpack.config.ts in a subdirectory, e.g. ./config/webpack.config.ts, and put a package.json in that subdirectory.

  • Add a commonjsEntrypoints config
    Any file matched by commonjsEntrypoints will be compiled and run as CJS, and anything it require()s will also compile and run as CJS.

  • Add an autoCommonjs option
    Automatically switches to commonjs emit and moduleType when ESM loader is not loaded

Additional context

jestjs/jest#11453

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions