Next.js: `getServerSideProps` does not work with Parse server due to `child_process`

Created on 16 May 2020  Β·  7Comments  Β·  Source: vercel/next.js

Bug report

Describe the bug

After generating a new Next project, adding Parse, adding a small bit of code to see if the two play together nicely, and running next build, I get the following error:

$ next build
Creating an optimized production build

Failed to compile.

./node_modules/xmlhttprequest/lib/XMLHttpRequest.js
Module not found: Can't resolve 'child_process' in '/Users/devanb/Projects/parse-test/node_modules/xmlhttprequest/lib'


> Build error occurred
Error: > Build failed because of webpack errors
    at build (/Users/devanb/Projects/parse-test/node_modules/next/dist/build/index.js:13:913)
error Command failed with exit code 1.

I'm not sure exactly what the issue is other than child_process, unfortunately. In over my head a little πŸ˜…

To Reproduce

Full reproduction here:
https://github.com/DevanB/next-parse-server

System information

  • OS: macOS 10.15.4
  • Browser: Safari 13.1
  • Version of Next.js: 9.4.0
  • Version of Node.js: 12.16.3

Most helpful comment

Same here with [email protected]:

> Using external babel configuration
> Location: "/path/to/project/babel.config.js"
Creating an optimized production build  

Failed to compile.

./node_modules/command-exists/lib/command-exists.js
Module not found: Can't resolve 'child_process' in '/path/to/project/node_modules/command-exists/lib'

This happened after I bumped Next from 9.4.0 to 9.4.1 and also updated a few other deps in one small open-source side project. Here is the commit: https://github.com/kachkaev/video-easter-eggs/commit/d535f5919f82c72d940cf9529804cda935f7ba65

Simply pinning next to [email protected] in package.json has not helped, so going to investigate further.

UPD: Bumping next to 9.4.1-canary.9 does not help either πŸ€”

UPD2: _Probably_ my issue is in the user land, i.e. in https://github.com/kachkaev/video-easter-eggs/commit/5e3ffaee371c850b73ff81c4774aab9c3784c42c πŸ€” It’s a pretty large diff, but most of it is just moving files around. There are no ESLint and TypeScript problems both before and after.

UPD3: @DevanB I resolved the issue for my project πŸŽ‰ It had nothing to do with Next.js, purely user land. Roughly speaking, I had:

src/shared/something/types.ts ← just TS types
src/shared/something/doX.ts   ← function that works on the server and in the browser
src/shared/something/doY.ts   ← function that only works on the server, depends on execa
src/shared/something/index.ts ← re-exports everything from the above three files

Here is what I mistakenly did while refactoring src/ui/MyComponent.tsx:

- import { doX } from "../shared/something/doX"
- import { SomeType } from "../shared/something/types"
+ import { doX, SomeType } from "../shared/something"

My expectation was that Next.js would tree-shake the import and thus exclude doY while building the client bundle. This did not happen though, so webpack started processing doY β†’ execa β†’ child_process and failed.

Replacing one import statement back with two resolved the issue. Hope that my investigation helps others who face a similar puzzle too πŸ™‚

All 7 comments

Please try upgrading to next@canary!

@Timer Thanks for the quick response ❀️

I upgraded to 9.4.1-canary.7, trashed node_modules and .next, and ran yarn && next build. I'm still receiving the same issue.

$ next build
Creating an optimized production build

Failed to compile.

./node_modules/xmlhttprequest/lib/XMLHttpRequest.js
Module not found: Can't resolve 'child_process' in '/Users/devanb/Projects/parse-test/node_modules/xmlhttprequest/lib'


> Build error occurred
Error: > Build failed because of webpack errors
    at build (/Users/devanb/Projects/parse-test/node_modules/next/dist/build/index.js:13:913)
error Command failed with exit code 1.

Did you believe canary should have a possible fix in it? Or did I not follow the directions and should have tested canary first?

Same here with [email protected]:

> Using external babel configuration
> Location: "/path/to/project/babel.config.js"
Creating an optimized production build  

Failed to compile.

./node_modules/command-exists/lib/command-exists.js
Module not found: Can't resolve 'child_process' in '/path/to/project/node_modules/command-exists/lib'

This happened after I bumped Next from 9.4.0 to 9.4.1 and also updated a few other deps in one small open-source side project. Here is the commit: https://github.com/kachkaev/video-easter-eggs/commit/d535f5919f82c72d940cf9529804cda935f7ba65

Simply pinning next to [email protected] in package.json has not helped, so going to investigate further.

UPD: Bumping next to 9.4.1-canary.9 does not help either πŸ€”

UPD2: _Probably_ my issue is in the user land, i.e. in https://github.com/kachkaev/video-easter-eggs/commit/5e3ffaee371c850b73ff81c4774aab9c3784c42c πŸ€” It’s a pretty large diff, but most of it is just moving files around. There are no ESLint and TypeScript problems both before and after.

UPD3: @DevanB I resolved the issue for my project πŸŽ‰ It had nothing to do with Next.js, purely user land. Roughly speaking, I had:

src/shared/something/types.ts ← just TS types
src/shared/something/doX.ts   ← function that works on the server and in the browser
src/shared/something/doY.ts   ← function that only works on the server, depends on execa
src/shared/something/index.ts ← re-exports everything from the above three files

Here is what I mistakenly did while refactoring src/ui/MyComponent.tsx:

- import { doX } from "../shared/something/doX"
- import { SomeType } from "../shared/something/types"
+ import { doX, SomeType } from "../shared/something"

My expectation was that Next.js would tree-shake the import and thus exclude doY while building the client bundle. This did not happen though, so webpack started processing doY β†’ execa β†’ child_process and failed.

Replacing one import statement back with two resolved the issue. Hope that my investigation helps others who face a similar puzzle too πŸ™‚

Next.js 9.4.1 should've fixed all cases of this that we were aware of. We also added regression tests.

@DevanB can you please provide a minimal reproducing demo and we can help resolve it (like above) or fix the bug if one exists?

@Timer I just pushed an update to the original minimal reproducing demo. It appears that 9.4.1 has not resolved the issue.

You can clone this, execute yarn && yarn build and see the error.

@DevanB these lines may be causing the problem: https://github.com/DevanB/next-parse-server/blob/5b320862ba963da6f763939d4485556054bf225c/pages/index.js#L4-L11

The issue should be resolved if you move them into getServerSideProps(). Not sure it would be correct for Next to remove your Parse.initialize() call from the root of the file in the browser bundle. What if it’s something else that’s needed on both sides?

To avoid initializing your parse instance on the client _and_ on every request you can do

import { getParse } from "./../shared/whatever"

export const getServerSideProps = async () => {
  const Parse = getParse();
  // ... as before
}

In shared/whatever β†’ getParse, you’ll make calls to Parse.initialize etc. based on whether you have already initialized it or not. With this trick in place, Next.js can remove the getParse import on the client because it sees that this dependency is only used inside getServerSideProps.

@kachkaev this makes sense now. Testing locally.

-- Update --

This worked! Thanks so much @kachkaev. I understand what's going on now :)

I'm closing this report @Timer. Thanks for the help πŸ˜„

Was this page helpful?
0 / 5 - 0 ratings

Related issues

irrigator picture irrigator  Β·  3Comments

swrdfish picture swrdfish  Β·  3Comments

YarivGilad picture YarivGilad  Β·  3Comments

olifante picture olifante  Β·  3Comments

timneutkens picture timneutkens  Β·  3Comments