lingui / js-lingui

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

babel-plugin-macros seems to be already added in extractBabelOptions #359

Closed JSteunou closed 5 years ago

JSteunou commented 5 years ago

Describe the bug Using babel macros and adding 'macros' to the list of babel plugins works when building with webpack but does not when extracting messages with lingui.

> lingui extract

/home/jsteunou/someproject/node_modules/@babel/core/lib/config/config-descriptors.js:205
      throw new Error([`Duplicate plugin/preset detected.`, `If you'd like to use two separate instances of a plugin,`, `they need separate names, e.g.`, ``, `  plugins: [`, `    ['some-plugin', {}],`, `    ['some-plugin', {}, 'some unique name'],`, `  ]`].join("\n"));
      ^

Error: Duplicate plugin/preset detected.
If you'd like to use two separate instances of a plugin,
they need separate names, e.g.

To Reproduce Using lingui.config.js with extractBabelOptions the same object than in your webpack config for example, which should have 'macros' in the list of babel plugins

If you make a separate config for lingui with 'macros' commented out, it works.

Expected behavior

Should be able to use the same babel config between build & lingui extract

Additional context

plugins: [
    'babel-plugin-macros',
    '@babel/plugin-syntax-dynamic-import',
    '@klaxoon/babel-plugin-jsx-attributes-transformer',
    ['@babel/plugin-proposal-decorators', {legacy: true}],
    ['@babel/plugin-proposal-class-properties', {loose: true}],
    '@babel/plugin-proposal-object-rest-spread',
    [
        '@babel/plugin-transform-runtime',
        {
            regenerator: false,
            useESModules: true,
        },
    ],
],
presets: [
    [
        '@babel/preset-env',
        {
            targets: {
                esmodules: true,
            },
            modules: false,
        },
    ],
    ['@babel/preset-react', {development: IS_DEV}],
],
tricoder42 commented 5 years ago

Hi @JSteunou, you're right, lingui extract adds plugin on it's own. I think we could fix it here by providing plugin name: ['macros', {}, 'lingui-extract-macros'],. Would you like to send a PR?

In Babel 7 we inspect the babel config so we could add macros plugin conditionally. I'm not sure if such feature exists in Babel 6. Having two macros plugins in config should be safe, I alraedy use it like that in combination with react-scripts.

Meanwhile as a workaround you could do the same in your config. Just add a plugin name to make it work: ['macros', {}, 'my-macros'],

JSteunou commented 5 years ago

Why not just removing "macros" here ?

It's already written in the doc that "macros" should be added in the plugins list, and obviously babel 7 (I dont know about babel 6) does not allow to put the same plugin twice, so the user's babel configuration is already ready to work with lingui extract command when the user follows the documentation.

danielkcz commented 5 years ago

I kinda agree with @JSteunou, macros plugin should be more like peer dependency considering there is a such limitation with Babel 7.

tricoder42 commented 5 years ago

Actually, this is a good point. If you use macros, you should have them in your babel config anyway. If lingui extract detects a framework and adds a preset (like react-scripts), these presets should already have them.

@JSteunou Ok, feel free to remove it and add peer dependency for @lingui/cli.