lingui / js-lingui

🌍 📖 A readable, automated, and optimized (3 kb) internationalization for JavaScript
https://lingui.dev
MIT License
4.5k stars 378 forks source link

`compileNamespace` should take package.json "type" into account #1704

Open lukescott opened 1 year ago

lukescott commented 1 year ago

When you set "type": "module" in your JSON both .js and .ts files (if you are using TypeScript) are considered modules. You only need to use the .m[jt]s or .c[jt]s extensions as an override.

I bring this up because it also applies to TypeScript, not just vanilla JavaScript. And both can have module.exports = or export const depending on the combination of package type and extension used.

I'm running into issues with babel when compiling code with a mix of .ts and .cts extensions. Babel just compiles everything to .js. There doesn't seem to be a way to solve this.

Also, newer node versions unfortunately are extremely strict about this, so if you don't use the right syntax it just fails.

I would like to propose reading the package.json type and use the following logic:

If this is too complicated I understand. Ideally Lingui would just have a "typescript" option and just detect the package.json type. And optionally be able to provide a custom compilation function.

gadicc commented 1 year ago

In the meantime, just posting the script I'm using as a workaround in package.json for { "type": "module" }:

{
  "scripts":
    "i18n:compile": "lingui compile && for file in locales/*/messages.js; do sed -i 's/module.exports={messages:\\(.*\\)};$/export const messages = \\1;/' $file ; done",
}

It changes from module.exports = { messages: {} } to export const messages = {} (it could just as easily rename the file to .cjs).

timofei-iatsenko commented 1 year ago

@lukescott i think it would be more straightforward and easy to understand/use if we add a bunch of new parameters instead of one namespace and reading implicitly the "type": "module".

lingui compile --modules=cjs --extension=js => write module.exports = to a .js file lingui compile --modules=esm --extension=mjs => write export const messages = to a .mjs file lingui compile --modules=esm --extension=mts --typescript => write export const messages: AllMessages = to a .mts file

What do you think?

vonovak commented 6 months ago

I'd also rather make this explicitly configurable, as opposed to trying to infer from package.json file. In monorepos with multiple package.json files that approach would be problematic.

stabildev commented 6 months ago

In the meantime, just posting the script I'm using as a workaround in package.json for { "type": "module" }:

{
  "scripts":
    "i18n:compile": "lingui compile && for file in locales/*/messages.js; do sed -i 's/module.exports={messages:\\(.*\\)};$/export const messages = \\1;/' $file ; done",
}

It changes from module.exports = { messages: {} } to export const messages = {} (it could just as easily rename the file to .cjs).

Thanks, this slight variation works for me:

"compile": "lingui compile && for file in locales/*/messages.js; do sed -i '' 's/module.exports=\\({messages:.*}\\);/export const messages = \\1;/' $file; done"

Would be great to have a --modules=esm option