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

Add ESM support to typescript config files #246

Closed
NashJames opened this issue Jul 11, 2023 · 12 comments · Fixed by #249
Closed

Add ESM support to typescript config files #246

NashJames opened this issue Jul 11, 2023 · 12 comments · Fixed by #249

Comments

@NashJames
Copy link

Hi! It would be quite nice to start writing postcss config files with full ESM + TS support since it seems to be becoming standard with most popular tools. As an example, a postcss.config.ts file written as such:

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

export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
} satisfies Config

If it is any help, I noticed Tailwind made some small mention of the libraries they used to handle this in a blog post.

Thanks.

@ai
Copy link
Member

ai commented Jul 11, 2023

I think we already support ESM configs since 4.0.

What we need to add for TS support?

@NashJames
Copy link
Author

For a minimal example:

  1. pnpm create-next-app and click Enter through all the options
  2. Remove the postcss.config.js file
  3. Add a postcss.config.ts file and add the above config
  4. Launch the app with pnpm dev

Fairly sure the problematic bit is the export default as it acts slightly differently to module.exports

@ai
Copy link
Member

ai commented Jul 12, 2023

@NashJames can you do a investigation and find what we should change?

@NashJames
Copy link
Author

Sure. I had a quick look at tailwind and found these two files:

https://github.com/tailwindlabs/tailwindcss/blob/master/loadConfig.js
https://github.com/tailwindlabs/tailwindcss/blob/master/src/lib/load-config.ts

An example of it being used here: https://github.com/tailwindlabs/tailwindcss/blob/e853901591c410ec0ce053c6fc57c92e4ff11548/src/cli/build/plugin.js#L151

I think the config just needs sending through this transformer

@ai
Copy link
Member

ai commented Jul 12, 2023

Can you check that PR (which we already merged)?

#234

@NashJames
Copy link
Author

I did skim the whole project earlier, and just now that PR. I'm not exactly sure what you're asking but I'm not sure it includes anything to handle an export default? You seem to use lilconfig and even they suggest using loaders for ESM which I couldn't find any instances of in the repo?

@ai
Copy link
Member

ai commented Jul 13, 2023

@michael42 can you explain how we did ESM support in your PR and what to do to use it with .ts extension?

@NashJames what is your tsconfig.json? Do you have type: module in package.json?

@NashJames
Copy link
Author

I have no trouble doing this for any other configuration files (I'm assuming they all added support) so I don't think it'll be my setup being problematic. Unless you have trouble re-creating it?

what is your tsconfig.json?

{
  "compilerOptions": {
    "target": "es2022",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [{ "name": "next" }],
    "paths": {
      "@public/*": ["./public/*"],
      "@components/*": ["./src/components/*"],
      "@pages/*": ["./src/pages/*"],
      "@data/*": ["./src/data/*"],
      "@lib/*": ["./src/lib/*"]
    },
    "noImplicitAny": true,
    "noImplicitThis": true,
    "strictNullChecks": true
  },
  "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

Do you have type: module in package.json?

Nope

@michael42
Copy link
Contributor

@NashJames: Default exports should be supported, in fact (for most file types, it's the only kind of export that's supported, as even CommonJS files are loaded with import(...).

@ai: I didn't, however, get a .ts-file that compiles to ESM to work with an unmodified postcss-load-config. I think that's because postcss-load-config enables ts-node by calling require('ts-node').register(), as that API doesn't support ESM as far as I know.

Supporting ESM in .ts-files should be possible in postcss-load-config, but personally, I don't see that as worthwhile. Using a simple .js/.mjs file, like /** @type {import("postcss-load-config").Config} */ export default {}):

  • can be immediately executed, because it doesn't need a transpiler (ts-node? plain tsc? esbuild? swc? babel? tsx?)
  • doesn't depend on tsconfig.json settings (during run-time)
  • is just as type-safe as .ts-file, because TypeScript can also check .js files (enabled by default)
    • code completion by the TS language service is the same
    • TypeScript errors when compiling with tsc are the same

@ai
Copy link
Member

ai commented Jul 13, 2023

@NashJames if you don’t have type: module in package.json then all .ts files will be treated as CJS files.

@NashJames
Copy link
Author

I'm agreed with everything said and am aware that there's no real benefit to TS config files. I'm quite happy to use JS or type:module in projects, but I figure it was worth raising for consistency.

I'm experiencing a lot more libraries encouraging TS as their default config file format with ESM defaults and satisfy typing examples. I think there's a huge preference to use TS for everything now and it's a small surprise when you find something not supported out-of-the-box. Particularly, ESM and TS both supported but not at the same time was a little weird.

Even though there's no material benefit to adding the support natively, it may save people time figuring the same out in the future. I reckon it is worth keeping open until either the API has an update or someone is looking to contribute. Especially since there's no harm to adding support (the transpilation cost should be next to nothing?).

I'll make the issue title a little clearer since this only affects .ts files.

@NashJames NashJames changed the title Add ESM support to config files Add ESM support to typescript config files Jul 13, 2023
@ai ai closed this as completed in #249 Nov 30, 2023
@karlhorky
Copy link

karlhorky commented Feb 11, 2024

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 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants