Unable to upgrade webpack and make it work with ESM

33 Views Asked by At

I am using a webpack on a project with webpack.config.babel.js so I can use esm systax

I have this babel config

"babel": {
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "browsers": [">1%", "last 4 versions", "not ie < 9"]
        },
        "useBuiltIns": "usage",
        "debug": false,
        "corejs": 3
      }
    ],
    "@babel/preset-react"
  ]
}

I do not have "type": "modules" anywhere on the package.json

Using this script on `package.json

"dev": "webpack serve --env --mode=development --config webpack/webpack.config.babel.js",

And have anong others this packages:

"@babel/core": "~7.12.3",
"@babel/eslint-parser": "^7.21.3",
"@babel/preset-env": "~7.12.1",
"@babel/preset-react": "~7.12.1",
"@babel/register": "~7.12.1",
"webpack": "^5.75.0",
"webpack-bundle-analyzer": "~4.1.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "~3.11.0",
"webpack-merge": "~5.3.0",

I am using node v21.6.2

And all works fine I am able to use import on webpack.

But If I try to upgrade webpack to higher version all breaks up and it becomes unable to read ESM syntax no matter what I do, adding "type": "modules" ... following instructions on babel and updating those too...nothing works, and starts to become a mess as there's not a single article on the internet it works for me, so I end up mixing all. But it never works.

In reply to @Bogdan Gishka:

Old version: Usign webpack.config.babel.js and no "type": "module" and no .js "webpack": "^5.75.0", "webpack-cli": "^4.9.2", "webpack-dev-server": "~3.11.0", "webpack-merge": "~5.3.0"

New version: Usign webpack.config.js with "type": "module" and with .js

"webpack": "^5.90.3", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.2", "webpack-merge": "^5.10.0",

2

There are 2 best solutions below

0
Álvaro On

I figured it out.

Mainly my main problem was that the webpack that I was using before upgrading used imports without mentioning the .js at the end, I still do not know how.

But that threw me off, once I upgraded, added "type": "modules" to the package.json and added the .js to each import it started to work.

It was a matter of chasing the errors as there were things like import { merge } from 'webpack-merge' instead of import merge from 'webpack-merge' a few packages that also needed update suchs as "@pmmmwh/react-refresh-webpack-plugin" and other bit and pieces. But it all works now

1
Bogdan Gishka On

Would be good, if you could specify the old and the new versions of Webpack you're using.

From what I see in your story, the old Webpack used other strategy for module resolution. I recommend to read this page from Webpack docs on how it resolves modules. There are two config fields that might be interesting to you: resolve.enforceExtension (link) and resolve.extensions (link).

resolve.enforceExtension forces you to always specify file extensions. For example:

// resolve.enforceExtension = true
// ===============================================

// Invalid:
import one from "./one";
// Valid:
import two from "./two.js";

// resolve.enforceExtension = false
// ===============================================

// Both variants are valid:
import one from "./one";
import two from "./two.js";

resolve.extensions specifies what extensions can be omitted in the code and Webpack will try to resolve the file automatically. For example:

// resolve.extensions = [".js", ".json"]
// ===============================================

// "*.js" and "*.json" modules can be imported without extension.
//
// Both variants are valid:
import one from "./one";
import one from "./one.js";

// But "*.ts" modules have to be imported with extension specification.
//
// Invalid:
import one from "./one";
// Valid:
import one from "./one.ts";