NormalModuleReplacementPlugin doesn't resolve relative imports of also replaced modules within replaced modules anymore in webpack 5
Bug report
What is the current behavior?
Apologies for the cryptic title but I'm not sure how to describe this better. I fear what follows below might not be much easier to understand either, sadly.
We're using NormalModuleReplacementPlugin in element-web to replace files within matrix-react-sdk (which is in node_modules) with files from element-web: https://github.com/vector-im/element-web/blob/develop/webpack.config.js#L79 (the replacement map is read from https://github.com/vector-im/element-web/blob/develop/components.json)
Some of the replaced-with files import other replaced-with files. E.g. VectorAuthPage from element-web (which replaces AuthPage from matrix-react-sdk) imports VectorAuthFooter from element-web (which replaces AuthFooter from matrix-react-sdk): https://github.com/vector-im/element-web/blob/develop/src/components/views/auth/VectorAuthPage.tsx#L20
This has worked fine up until the latest current version of Webpack 4 but stopped working in Webpack 5. With:
new webpack.NormalModuleReplacementPlugin(
new RegExp(oldPath.replace(/\//g, "[\\/\\\\]").replace(/\./g, "\\.")),
path.resolve(__dirname, newPath))
we're now hitting this error
[webpack-cli] ModuleNotFoundError: Module not found: Error: Can't resolve './VectorAuthFooter' in '/Users/jm/Code/element-web/node_modules/matrix-react-sdk/src/components/views/auth'
Note how it tries to look for VectorAuthFooter (which is imported from VectorAuthPage and in element-web) in matrix-react-sdk/src/components/views/auth (which is the parent directory of the replaced file AuthFooter in matrix-react-sdk).
To get it to work, we have to manually set the context now as in:
new webpack.NormalModuleReplacementPlugin(
new RegExp(oldPath.replace(/\//g, "[\\/\\\\]").replace(/\./g, "\\.")),
function (resource) {
resource.request = path.resolve(__dirname, newPath);
resource.createData.resource = path.resolve(__dirname, newPath);
console.log(resource)
// Starting with Webpack 5 we also need to set the context as otherwise replacing
// files in e.g. matrix-react-sdk with files from element-web will try to resolve
// them within matrix-react-sdk
/resource.context = path.dirname(resource.request)
resource.createData.context = path.dirname(resource.createData.resource);
}
If the current behavior is a bug, please provide the steps to reproduce.
–
What is the expected behavior?
Setting context manually should not be necessary.
Other relevant information:
webpack version: 5.88.2 Node.js version: 18.16.1 Operating System: macOS Additional tools:
This issue had no activity for at least three months.
It's subject to automatic issue closing if there is no activity in the next 15 days.
Sorry for delay, can you provide a small reproducible example?
I got the same issue with the webpack v5. NormalModuleReplacementPlugin is not replacing the file anymore. As mentioned, I had to use at least these two lines to make it work.
resource.request = path.resolve(__dirname, newPath);
resource.createData.resource = path.resolve(__dirname, newPath);
@antoantonydh Can you create reproducible test repo? Thank you
Issue was closed because of inactivity.
If you think this is still a valid issue, please file a new issue with additional information.