2

I want to create RSS script using Next.js.

So I put up a script in a subfolder inside the root folder scripts/ & named it build-rss.js

next.config.js

module.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
    },
}

When I try to run my script npm run build:development which in package.json represents:

"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"
}

It throws an error saying:

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

But I checked. The file does exist.

The blunder is this used to work earlier. Probably few versions ago when my other project used the same combination.

I have made a complete reproduction showcasing the error → https://github.com/deadcoder0904/next-script-rss-error

Just clone it, install it & try the script npm run build:development in the terminal to see the error.

12
  • .next directory is not present in your repo. also, that file webpack-runtime.js is being located in .next/serverless directory. when you're running the script, try process.cwd() to know the context directory from where script is being executed. Commented Aug 11, 2021 at 6:58
  • @boxdox .next gets created when you run next build & I have ignored it specifically in .gitignore so its not in the repo but exists locally. It only gets on .next/serverless on Vercel but on development it generates on .next/server. I'll try your process.cwd() suggestion but would love to know if you have anymore suggestions :) Commented Aug 11, 2021 at 7:10
  • @boxdox just tryied process.cwd() but it throws error before even running build-rss.js. Notice, how the entire file is empty & it still doesn't work. I did try with content in the file but nope it doesn't work either. Commented Aug 11, 2021 at 7:13
  • i don't have much experience with nextjs, but usually this issue is because how you call the file, and how does it's directory context change. mostly either it's looking in the wrong directory, or the required file is being generated after the script has finished Commented Aug 11, 2021 at 7:13
  • @boxdox ah this used to work previously so not sure what's the problem now haha. i'll take a look around though, thanks :) Commented Aug 11, 2021 at 7:14

3 Answers 3

1

Based on our conversation:

entry: path.join(__dirname, '..', 'path/to/file')

That's what a webpack entry looks like. It can also be an array or an object:

entry: [
  path.join(__dirname, '..', 'path/to/file'),
  // other entries here
]

Whereas you're already getting the whole webpack config:

webpack: (config, options)

So doing:

const originalEntry = config.entry

config.entry = async () => {
  const entries = { ...(await originalEntry()) }
  entries['./scripts/build-rss'] = './scripts/build-rss.js'
  return entries
}

Makes no sense to me if you can just do:

config.entry.push('./scripts/build-rss')
// config.entry['./scripts/build-rss'] = './scripts/build-rss.js'

Unless I miss something with how nextjs is loading the webpack config.

Even then I'd suggest that you use path.join in order to ensure it's loaded to the correct location, because that relative root will execute from wherever webpack is compiled from.

Along with that in your first project you used nextjs v10 and now you're using nextjs v11, which has an upgrade from webpack 4 to 5, which is a major upgrade. I don't know the details, I can only speculate, but under no conditions should you assume that "because your previous project was working this one should using the same stuff", it won't necessarily (especially not in this case).

The first intuitive thing I thought was that webpack should by default bundle everything to a single output file, unless the configuration for that was changed by nextjs (I don't know). So using a script you added to entries didn't make sense to me, because it wouldn't exist. But you're saying that it does exist so I can only assume that webpack is configured to do code splitting and outputs each entry to a different file. In which case I have no idea. As far as I'm aware in webpack 5 (I don't know about webpack 4) code splitting is disabled in dev and enabled in production so your problem is likely a discrepancy between dev and production.

Perhaps the last thing you can try is to change your !options.dev, because right now you're only adding that script when it's production but you're trying to run the script using development.

If you really just have to get it working you can downgrade your nextjs to the previous version you were using (v10), even though that's not really a solution.

Other than that I'm out of ideas.

Sign up to request clarification or add additional context in comments.

7 Comments

I get an error TypeError: config.entry.push is not a function when I use push
Try the second example I commented out, perhaps it's an object.
This time I get the original error I got Error: Cannot find module '../../webpack-runtime.js' so looks like both solutions lead to the same problem. Something definitely changed in either Next.js or Webpack I think :(
No both solutions don't lead to the same problem, now you've successfully removed all that unnecessary and irrelevant async stuff and just directly assigned the entry value. Now you can deal with your main problem which I addressed in the rest of my answer.
Still doesn't work. I tried removing options.dev as well as removing the whole if statement but no luck. I think next build does run production build. I've just named my scripts npm run build:development as Vercel has the folder name .serverless on server & its .server locally so I'm not sure if that's the problem. I've asked the Webpack creator who now works in Next.js as well so he most probably knows the answer & hopefully answers. Thanks for your help though. I'll try downgrading in the meantime to see if it works & open an issue if it's really a bug :)
|
0

Not sure if you are still looking for an answer, but simply changing the webpack entry as follows seems to have fixed the problem.

entries['scripts/build-rss'] = './scripts/build-rss.js';
// instead of entries['./scripts/build-rss']

1 Comment

i'll accept this when i check it for myself but as i said on the github issue (yes, same guy), ./ was working on previous next versions :)
0

I had the same Error! I deleted the .next Folder and did an npm run dev, It started to work for me!

2 Comments

this only worked bcz in recent versions, the error has been fixed :)
Ohh Glad that it did, but still I have to do did frequently, No Idea Why this is happening

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.