postcss / postcss-load-config

Autoload Config for PostCSS
MIT License
638 stars 71 forks source link

TypeScript doesn't work with "type": "module" in package.json #239

Closed TimothyGu closed 8 months ago

TimothyGu commented 2 years ago

Running any postcss-cli command fails with

Details

After support for .mjs was added in version 4 of this module, I expected ESM-mode TypeScript to work as well. Unfortunately, it does not.

The issue has to do with how TypeScript config files are loaded: https://github.com/postcss/postcss-load-config/blob/b8cdab0a91052bbe2d19a869534f29170c14d873/src/index.js#L114-L117

Using ts-node.register() / require() with "type": "module" is simply unsupported. See ts-node documentation.

Workaround

The ts-node documentation describes a valid workaround:

  • You have moved your project to ESM but still have a config file, such as webpack.config.ts, which must be executed as CommonJS
    • Solution: Configure a module type override. Docs

Indeed, if I include

  "ts-node": {
    "moduleTypes": {
      "postcss.config.ts": "cjs"
    }
  }

in tsconfig.json then the error goes away.

Error (Logs|Stacks)

https://gist.github.com/TimothyGu/e65fcba3fd759cd6fa2e415ed2047b77#file-readme-md

Reproduction (Code)

See https://gist.github.com/TimothyGu/e65fcba3fd759cd6fa2e415ed2047b77

$ git clone https://gist.github.com/e65fcba3fd759cd6fa2e415ed2047b77.git testdir
$ cd testdir
$ yarn
$ node_modules/.bin/postcss test.css

Environment

OS node npm/yarn package
Linux 5.17.15-1-MANJARO 18.3.0 yarn 1.22.19 postcss 8.4.14
postcss-cli 10.0.0
postcss-load-config 4.0.1
see yarn.lock
TimothyGu commented 2 years ago

For what it's worth, webpack had the same issue: https://github.com/webpack/webpack-cli/issues/2458

Their fix does not work with postcss, however:

$ NODE_OPTIONS=--loader=ts-node/esm node_modules/.bin/postcss test.css

still throws the same error.

ai commented 2 years ago

Seems like for now there is no good way to use TS and ESM together. All of them are very dirty (like hacking Node.js with custom loaders).

It is better to use .js for PostCSS configs until the problem will not be fixed on ecosystem level.

If you have any trick in mind, we can review the PR.

polyzen commented 1 year ago

From https://github.com/vitejs/vite/issues/11894: postcss-load-config should use import() in this case if the config is compiled to ESM.

ai commented 1 year ago

@polyzen do you have an idea how to fix it?

polyzen commented 1 year ago

I do not.

polyzen commented 1 year ago

https://tailwindcss.com/blog/tailwindcss-v3-3#esm-and-typescript-support

I do not know if this is equivalent, but tailwind.config.ts (and vite.config.ts) works in this situation. Perhaps their implementation can be inspiration.

xiaohaoo commented 1 year ago

来自vitejs/vite#11894postcss-load-config should use import() in this case if the config is compiled to ESM.

我认为这是一个bug,为什么还没修复

brc-dd commented 11 months ago

Tailwind uses jiti + sucrase to handle this: https://github.com/tailwindlabs/tailwindcss/blob/master/src/lib/load-config.ts

I can create a PR here if the maintainers allow. jiti already comes with babel, so sucrase is only required if you want to increase perf.

Also, this issue is similar to #246. Fixing this will close it too.

ai commented 11 months ago

@TimothyGu can you check that https://github.com/postcss/postcss-load-config/issues/246 works on your big repo?

karlhorky commented 5 months ago

Thanks for the release postcss-load-config@5.0.0 with full ESM support in postcss.config.ts with "type": "module" @brc-dd and @ai 🙌

gyf0601 commented 3 months ago

should use this config "ts-node": { "transpileOnly": true, "moduleTypes": { "webpack.config.ts": "cjs", // Globs are also supported with the same behavior as tsconfig "include" "webpack-config-scripts/**/*": "cjs" } } https://github.com/TypeStrong/ts-node/tree/97f9afd046b66a0fe05a7d76e7a32f94b872016f#module-type-overrides