Search code examples
webpackbabeljsbabel-loader

Transpile code with Babel 7 to be used in a Node12/Babel6 app


I'm creating a package that will be rendering some React components (MDX to be precise) into a string, with renderToStaticMarkup. I'm using Webpack + Babel 7 to transpile it.

Now I need to be able to consume this code from a legacy Node12/Babel6 app. I get this error when I'm trying to do that:

Requires Babel "^7.0.0-0", but was loaded with "6.26.3".

Requires Babel "^7.0.0-0", but was loaded with "6.26.3".

I don't understand why it happens. My package shouldn't need any babel runtime, it has import/export+async/await, all of it should transpile to Node12 without needing any runtime.

webpack.config.js:

const path = require('path')

module.exports = {
  mode: 'production',
  target: 'node',
  entry: ['./src/index.ts'],
  output: {
    path: path.resolve(__dirname, 'dist'),
    library: {
      type: 'commonjs2',
    },
  },
  module: {
    rules: [
      {
        test: /\.(js|ts|tsx)$/,
        use: [
          {
            loader: 'babel-loader',
          },
        ],
      },
      {
        test: /\.mdx?$/,
        use: [
          {
            loader: 'babel-loader',
          },
          {
            loader: '@mdx-js/loader',
          },
        ],
      },
    ],
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
  },
}

.babelrc:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "12"
        },
        "useBuiltIns": false
      }
    ],
    [
      "@babel/preset-react",
      {
        "runtime": "automatic"
      }
    ],
    "@babel/preset-typescript"
  ]
}

Solution

  • Your Babel 6 app probably passes your dependencies through Babel.

    When compiling a file, the default Babel 6 behavior is to load the nearest .babelrc file and use it (this has been changed in Babel 7 - https://babeljs.io/docs/en/config-files#6x-vs-7x-babelrc-loading): your Babel 6 instance is reading the .babelrc file meant to be used by Babel 7, tries to load the Babel 7 plugins and throws.

    A possible workaround is to rename .babelrc to .babelrc.json: it's not supported by Babel 6, so it will be ignored.

    A proper solution, if we are talking about a published package, is to add .babelrc to your .npmignore file: by doing so it won't be present in your node_modules, so it won't be accidentally loaded by Babel 6.