How to Resolve Webpack Runtime Issues in Custom Next.js Scripts

If you’re working with Next.js and trying to run a custom script for RSS generation like build-rss.js, you might come across an error stating:

Error: Cannot find module '../../webpack-runtime.js'

This issue can arise due to various reasons, especially after upgrading Next.js or making changes to your build configuration. In this post, I will walk you through the error’s explanation, the underlying issue in your configuration, and offer a solution to help you resolve it.

Error Explanation

Error Message:

The error message Cannot find module '../../webpack-runtime.js' is usually seen when there’s an issue with module resolution, where Node.js cannot locate the webpack-runtime.js file in the expected location.

This could be related to a few possible causes:

  • Incorrect path or module resolution: The error may appear when Next.js expects certain files to be available, but they are either missing or not correctly linked.
  • Webpack configurations: If you’ve made custom changes to the webpack configuration (as seen in your next.config.js), it’s possible that these changes have affected how dependencies are bundled, leading to an issue with module resolution during the build.
  • Next.js version update: Since you mentioned that the script used to work earlier, but now it doesn’t, the issue might be related to a version update in Next.js or one of its dependencies that introduced breaking changes in the build process.

Issue in the Configuration

In your next.config.js, you’re trying to dynamically modify the webpack configuration by adding a custom entry point for build-rss.js:

.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.svg$/,
issuer: { and: [/\.(js|ts|md)x?$/] },
use: [
{
loader: '@svgr/webpack',
options: {
prettier: false,
svgo: true,
svgoConfig: { plugins: [{ removeViewBox: false }] },
titleProp: true,
},
},
],
});

if (!options.dev && options.isServer) {
const originalEntry = config.entry;
config.entry = async () => {
const entries = { ...(await originalEntry()) };
entries['./scripts/build-rss'] = './scripts/build-rss.js';
return entries;
};
}

if (!options.isServer) {
config.resolve.fallback.fs = false;
}

return config;
},
}

The part of the configuration that modifies the config.entry is trying to inject the RSS script into the build process. However, this can sometimes lead to problems if Next.js isn’t able to resolve or find webpack-runtime.js properly in the new build context.

Solution and Fix

  • Check File Paths: Ensure that your build-rss.js script is located correctly and that the path in config.entry correctly points to it. The file should be inside the scripts/ folder at the root of your project, as specified in the next.config.js.
  • Modify Webpack Configuration for Serverless: When using node ./.next/serverless/scripts/build-rss.js, ensure that the build process in a serverless setup can still access the necessary Webpack runtime files. You can try a different approach by modifying the script path resolution based on the build mode (serverless vs. regular server).
  • Test with npm run build First: Sometimes, running npm run build and ensuring that the build process completes successfully before running custom scripts can help isolate issues related to build-time configuration.
  • Next.js Version Compatibility: If the issue arose after upgrading Next.js, it might be related to compatibility issues between the custom webpack configuration and newer Next.js versions. Ensure you are using a compatible version of Next.js and check the changelogs for any breaking changes in how webpack is handled.
  • Add Fallback for Webpack Runtime: You can add a fallback in your next.config.js to ensure that the Webpack runtime is correctly bundled for your script. You can use something like:
if (!options.isServer) {
    config.resolve.fallback = {
        fs: false,
        path: false,
        webpack: require.resolve('webpack'),
    };
}
  • Simplify Webpack Configuration: Consider simplifying the custom webpack configuration temporarily to identify which part is causing the issue. For example, remove the build-rss.js entry configuration and test if the error still persists.

Improved Script Handling in package.json

You can simplify your scripts in package.json to ensure the build and export processes work seamlessly, like so:

"scripts": {
"clean": "rimraf .next",
"dev": "next dev",
"export": "next export",
"start": "next start",
"lint": "next lint",
"build:development": "next build && npm run export && npm run rss:development",
"build": "next build && npm run export && npm run rss",
"rss:development": "node ./.next/server/scripts/build-rss.js",
"rss": "node ./.next/serverless/scripts/build-rss.js"
}

Ensure that you are pointing to the correct location of build-rss.js depending on whether you are using a server-side build or serverless functions.

Further Testing

Once you apply these changes, follow these steps to troubleshoot and test:

  1. Run a Clean Build: Use npm run clean and then npm run build:development to ensure a fresh build.
  2. Test Without Custom Webpack: Temporarily remove the custom webpack modifications and test if the issue still arises.
  3. Check for Updates: Ensure all dependencies are up to date by running npm outdated and updating packages if necessary.

Conclusion

The error you encountered, Cannot find module '../../webpack-runtime.js', is likely caused by incorrect handling of the Webpack runtime in your custom Next.js configuration. By ensuring the paths are correct, simplifying your webpack config, and checking compatibility with the Next.js version you’re using, you should be able to resolve this issue.

Related blog posts