Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESM .postcssrc.ts w. "type": "module" results in ERR_REQUIRE_ESM #15869

Closed
7 tasks done
karlhorky opened this issue Feb 11, 2024 · 6 comments · Fixed by #15235
Closed
7 tasks done

ESM .postcssrc.ts w. "type": "module" results in ERR_REQUIRE_ESM #15869

karlhorky opened this issue Feb 11, 2024 · 6 comments · Fixed by #15235
Labels
feat: css p3-minor-bug An edge case that only affects very specific usage (priority)

Comments

@karlhorky
Copy link
Contributor

karlhorky commented Feb 11, 2024

Originally reported over here by @ElPrudi (before the issue was fixed in postcss-load-config):


Describe the bug

Upgrading to a version after postcss-load-config@5.0.0 (which added support for ESM postcss.config.ts w. "type": "module" does not resolve the problem in Vite that require() is used to load an ESM postcss.config.ts (or any other variations on the TS config) when in a "type": "module" project:

> vite

[Failed to load PostCSS config: Failed to load PostCSS config (searchPath: /home/projects/vitejs-vite-2gepfr): [Error] Must use import to load ES Module: /home/projects/vitejs-vite-2gepfr/.postcssrc.ts
require() of ES modules is not supported.
require() of /home/projects/vitejs-vite-2gepfr/.postcssrc.ts from /home/projects/vitejs-vite-2gepfr/node_modules/vite/dist/node/chunks/dep-bb8a8339.js is an ES module file as it is a .ts file whose nearest parent package.json contains "type": "module" which defines all .ts files in that package scope as ES modules.
Instead change the requiring code to use import(), or remove "type": "module" from /home/projects/vitejs-vite-2gepfr/package.json.

Error: Must use import to load ES Module: /home/projects/vitejs-vite-2gepfr/.postcssrc.ts
require() of ES modules is not supported.
require() of /home/projects/vitejs-vite-2gepfr/.postcssrc.ts from /home/projects/vitejs-vite-2gepfr/node_modules/vite/dist/node/chunks/dep-bb8a8339.js is an ES module file as it is a .ts file whose nearest parent package.json contains "type": "module" which defines all .ts files in that package scope as ES modules.
Instead change the requiring code to use import(), or remove "type": "module" from /home/projects/vitejs-vite-2gepfr/package.json.

    at createErrRequireEsm (/home/projects/vitejs-vite-2gepfr/node_modules/ts-node/dist-raw/node-internal-errors.js:46:15)
    at assertScriptCanLoadAsCJSImpl (/home/projects/vitejs-vite-2gepfr/node_modules/ts-node/dist-raw/node-internal-modules-cjs-loader.js:584:11)
    at Object.require.extensions.<computed> [as .ts] (/home/projects/vitejs-vite-2gepfr/node_modules/ts-node/src/index.ts:1610:5)
    at Module.load (node:internal/modules/cjs/loader:54:13457)
    at Function.Module._load (node:internal/modules/cjs/loader:54:10535)
    at Module.require (node:internal/modules/cjs/loader:54:13775)
    at i (node:internal/modules/cjs/helpers:98:2198)
    at eval (/home/projects/vitejs-vite-2gepfr/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:36654:16)
    at Object.search (/home/projects/vitejs-vite-2gepfr/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:29044:44)] {
  code: 'ERR_REQUIRE_ESM'
}

cc @bluwy

Reproduction

https://stackblitz.com/edit/vitejs-vite-2gepfr?file=package.json

Steps to reproduce

Create a config file called postcss.config.ts (or .postcssrc.ts, as in the reproduction above):

import type { Config } from 'postcss-load-config'
import cssnano from 'cssnano'

export default ({ env }): Config => ({
    plugins: [
        cssnano({
            preset: 'default'
        })
    ]
})

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.18.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.14.0 - /usr/local/bin/pnpm

Used Package Manager

npm

Logs

See logs above

Validations

Copy link

stackblitz bot commented Feb 11, 2024

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

@brc-dd
Copy link
Contributor

brc-dd commented Feb 11, 2024

#15235 would fix this. But it's a breaking change, so it will probably be added in v6. Use .cts extension for now.

@karlhorky karlhorky changed the title ESM .postcssrc.ts + "type": "module" = ERR_REQUIRE_ESM ESM .postcssrc.ts w. "type": "module" results in ERR_REQUIRE_ESM Feb 11, 2024
@karlhorky
Copy link
Contributor Author

karlhorky commented Feb 11, 2024

@brc-dd thanks!

I tried using postcss.config.cts, but this resulted in a confusing ts-node error which I was unable to find much info on:

[Failed to load PostCSS config: Failed to load PostCSS config (searchPath: /Users/k/p/projec/packages/slide-decks): [TSError] ⨯ Unable to compile TypeScript:
error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.

TSError: ⨯ Unable to compile TypeScript:
error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.

    at createTSError (/Users/k/p/projec/node_modules/ts-node/src/index.ts:859:12)
    at reportTSError (/Users/k/p/projec/node_modules/ts-node/src/index.ts:863:19)
    at /Users/k/p/projec/node_modules/ts-node/src/index.ts:1379:34
    at Object.compile (/Users/k/p/projec/node_modules/ts-node/src/index.ts:1440:28)
    at Module.m._compile (/Users/k/p/projec/node_modules/ts-node/src/index.ts:1617:30)
    at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
    at Object.require.extensions.<computed> [as .js] (/Users/k/p/projec/node_modules/ts-node/src/index.ts:1621:12)
    at Module.load (node:internal/modules/cjs/loader:1207:32)
    at Function.Module._load (node:internal/modules/cjs/loader:1023:12)
    at Module.require (node:internal/modules/cjs/loader:1235:19)] {
  diagnosticCodes: [ 5110 ]
}
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
github.com/evanw/esbuild/internal/helpers.(*ThreadSafeWaitGroup).Wait(...)
        github.com/evanw/esbuild/internal/helpers/waitgroup.go:36
main.runService.func2()
        github.com/evanw/esbuild/cmd/esbuild/service.go:114 +0x8c
main.runService(0x1)
        github.com/evanw/esbuild/cmd/esbuild/service.go:160 +0x4b4
main.main()
        github.com/evanw/esbuild/cmd/esbuild/main.go:240 +0x8d8

goroutine 18 [chan receive]:
main.runService.func1()
        github.com/evanw/esbuild/cmd/esbuild/service.go:98 +0x40
created by main.runService
        github.com/evanw/esbuild/cmd/esbuild/service.go:97 +0x1a0

goroutine 19 [chan receive]:
main.(*serviceType).sendRequest(0x140001ac060, {0x100866300, 0x140000d3b00})
        github.com/evanw/esbuild/cmd/esbuild/service.go:192 +0x11c
main.runService.func3()
        github.com/evanw/esbuild/cmd/esbuild/service.go:125 +0x38
created by main.runService
        github.com/evanw/esbuild/cmd/esbuild/service.go:122 +0x308
error Command failed with exit code 1.

My tsconfig.json file does indeed use NodeNext for both module and moduleResolution:

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "eslint-config-upleveled/tsconfig.base.json",
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "checkJs": true,
    "jsx": "preserve"
  },
  "include": [
    "**/*.ts",
    "**/*.tsx",
    "**/*.js",
    "**/*.jsx",
    "**/*.cts",
    "**/*.cjs",
    "**/*.mjs"
  ],
  "exclude": ["node_modules"]
}

I tried also switching to tsx as suggested by other users having issues with ts-node ("NODE_OPTIONS='--import tsx' vite dev"), but this led to a different confusing error, also thrown by ts-node:

[Failed to load PostCSS config: Failed to load PostCSS config (searchPath: /Users/k/p/projec/packages/slide-decks): [TypeError] Cannot assign to read only property '.mjs' of object '[object Object]'
TypeError: Cannot assign to read only property '.mjs' of object '[object Object]'
    at registerExtension (/Users/k/p/projec/node_modules/ts-node/src/index.ts:1607:26)
    at registerExtensions (/Users/k/p/projec/node_modules/ts-node/src/index.ts:1579:5)
    at Object.register (/Users/k/p/projec/node_modules/ts-node/src/index.ts:600:3)
    at file:///Users/k/p/projec/node_modules/vite/dist/node/chunks/dep-94_H5fT6.js:29068:43
    at Object.search (file:///Users/k/p/projec/node_modules/vite/dist/node/chunks/dep-94_H5fT6.js:21277:48)]
error Command failed with exit code 1.

@brc-dd
Copy link
Contributor

brc-dd commented Feb 11, 2024

Probably ts-node has some issue with nodenext. You can do something like:

// tsconfig.json
{
  // ...
  "ts-node": {
    "transpileOnly": true,
    "compilerOptions": {
      "module": "ESNext",
      "moduleResolution": "Node10"
    }
  }
}

https://stackblitz.com/edit/vitejs-vite-mbgkvz

@aaronadamsCA
Copy link

Just for added clarity: you can install v5 of postcss-load-config, you can override transitive dependencies to use v5, but Vite still contains postcss-load-config v4 as vendored code. That's why, even after excising ts-node from your codebase, you still get a ts-node error.

IMO just stick with postcss.config.cjs for now. It's just not worth the trouble trying to get ts-node working in a modern environment.

I wonder if Vite v6 could reconsider vendoring postcss-load-config? I definitely wasn't aware until now that installing my own postcss-load-config means I'm writing a "type-safe" config for a completely different version than what's baked into Vite. That is… not ideal!

@bluwy bluwy linked a pull request Feb 13, 2024 that will close this issue
9 tasks
@bluwy bluwy added p3-minor-bug An edge case that only affects very specific usage (priority) feat: css and removed pending triage labels Feb 13, 2024
@benedictleejh
Copy link

As an alternative to not vendoring postcss-load-config, would Vite consider re-exporting the PostCSS config type from postcss-load-config? This would have the advantage of allowing us to write type-safe configs using the same version of postcss-load-config that Vite uses, and users would not need to install their own version of postcss-load-config just to get access to the config typings.

@github-actions github-actions bot locked and limited conversation to collaborators Nov 12, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feat: css p3-minor-bug An edge case that only affects very specific usage (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants