webpack-cli: Unexpected token 'export' using webpack.config.babel.js with Webpack CLI v5

Describe the bug

The following webpack.config.babel.js works with Webpack CLI v4 but fails with v5:

import config from "./webpack/config"; // <---- exports fails with v5 (works with v4)
import path from "path";

export default {
  entry : "./src/main.js",
  output : {
    path : path.resolve(__dirname, config.dist),
    filename : "main.js"
  }
};

The error:

> webpack-cli-repro-babel@1.0.0 build
> webpack

[webpack-cli] Failed to load '/Users/yves/Projects/OSS/webpack-cli-repro-babel/webpack.config.babel.js' config
[webpack-cli] /Users/yves/Projects/OSS/webpack-cli-repro-babel/webpack/config.js:4
export default {
^^^^^^

SyntaxError: Unexpected token 'export'
    at Object.compileFunction (node:vm:360:18)
    at wrapSafe (node:internal/modules/cjs/loader:1088:15)
    at Module._compile (node:internal/modules/cjs/loader:1123:27)
    at Module._compile (/Users/yves/Projects/OSS/webpack-cli-repro-babel/node_modules/pirates/lib/index.js:136:24)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Object.newLoader [as .js] (/Users/yves/Projects/OSS/webpack-cli-repro-babel/node_modules/pirates/lib/index.js:141:7)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Function.Module._load (node:internal/modules/cjs/loader:878:12)
    at Module.require (node:internal/modules/cjs/loader:1061:19)
    at require (node:internal/modules/cjs/helpers:103:18)

Full repo repo: https://github.com/yvele/webpack-cli-repro-babel

What is the current behavior?

I’ve created a minimal bug repo repository that works fine with Webpack CLI v4 but fails with v5: https://github.com/yvele/webpack-cli-repro-babel

To Reproduce

Steps to reproduce the behavior: https://github.com/yvele/webpack-cli-repro-babel#build

Expected behavior

webpack.config.babel.js should be handled by Babel all the import way down. Same behaviour than Webpack CLI v4.

Screenshots

N/A

Please paste the results of npx webpack-cli info here, and mention other relevant information

Additional context

I’m using Node.js v18.12.1 and the following dependencies:

"devDependencies": {
  "@babel/core": "^7.20.7",
  "@babel/preset-env": "^7.20.2",
  "@babel/register": "^7.18.9",
  "webpack": "^5.75.0",
  "webpack-cli": "^5.0.1"
}

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 16
  • Comments: 16 (7 by maintainers)

Commits related to this issue

Most upvoted comments

I’ll check this.

I wanted to find a workaround but I never did. I had to rename all of our files. Sorry to be the bearer of bad news.

We recently upgraded interpret to v3 in https://github.com/webpack/webpack-cli/pull/3437.

Support .babel.(jsx|tsx) extensions (1e3d0f8)

I believe it’s related. I can see this in the CHANGELOG.

Same issue. None of the breaking changes seem applicable.

I don’t want to start mucking around with .mjs files to fix this - they’ve given me so many headaches in the past.

Our config name is webpack.config.renderer.dev.babel.js. Is our placement of babel okay, or are there some strict rules about how to name the files for Babel transpilation?

It’s quite a messy mess. I understand the meaningful benefits for some, but for us it’s just a lot of work for nothing gained.

I undestand you, but I don’t see any options to disable/configure it (we will provide them if it will be possible), maybe better ask about it interpret developers, because that’s just my guess (about perf)

Sorry for delay, I think you don’t undestand how a register works, if you have webpack.config.babel.js, you need to import config.babel.js, not config.js, because register can’t undestand what is ESM and what is non ESM, so don’t transpile files, we are using interpret + rechoir under the hood to transpile files.

Why it works before - let’s look at changelog of interpret - https://github.com/gulpjs/interpret/releases/tag/v3.0.0

Ensure babel only transforms files that match the full extension

So @babel/register will work only for .babel.js files if your root file has the .babel.js extension.

The question - why it was done by interpret team?

The answer is simple - for performance reasons. Previously, if you had a .babel.js root file extension, all import/require were processed by @babel/register, and if there are many, performance will degrade - remember that babel is not as fast as you want.

So again, the solution is to add the .babel.js extension to all imported files that contain pseudo ESM (or need to be transpiled for any other reason). Sorry, we don’t want to restore the previous behavior, and that’s only possible if we downgrade our dependecy, and that’s not possible because new features are used a lot and this is actually the correct fix because it will potentially increase your speed.

Feel free to feedback, I will peen the issue for other developers

We recently upgraded interpret to v3 in #3437.

Support .babel.(jsx|tsx) extensions (1e3d0f8)

I believe it’s related. I can see this in the CHANGELOG.

@snitin315 Do we need to make an interpret issue? I don’t fully understand why this commit is making Babel not to interpret imported files 🤔