Next.js: Cannot find module `pages/_document`

Created on 24 Sep 2018  ·  25Comments  ·  Source: vercel/next.js

Bug report

Describe the bug

Upgrading to 7 from 6 and application works fine in development mode. In production, all pages fail with the server error Cannot find module '/app/.next/server/static/ddabb420240ac61ad07cc315c21cfa96e55c20df/pages/_document'.

Not using a custom document, but am using a custom _app.js. Verified that _document.js exist at that path in .next.

To Reproduce

Upgrade to Next 7.

Expected behavior

Pages should load without the error.

System information

package.json:

"dependencies": {
        "@babel/core": "7.1.0",
        "@babel/register": "7.0.0",
        "@fortawesome/fontawesome-svg-core": "1.2.4",
        "@fortawesome/free-brands-svg-icons": "5.3.1",
        "@fortawesome/free-regular-svg-icons": "5.3.1",
        "@fortawesome/free-solid-svg-icons": "5.3.1",
        "@fortawesome/react-fontawesome": "0.1.3",
        "@zeit/next-css": "1.0.1",
        "aws-sdk": "2.317.0",
        "babel-plugin-inline-import": "3.0.0",
        "babel-plugin-inline-svg": "1.0.0",
        "clipboard": "2.0.1",
        "css-loader": "1.0.0",
        "csv-parse": "3.0.0",
        "enum": "2.5.0",
        "file-loader": "1.1.11",
        "js-md5": "0.7.3",
        "luxon": "1.3.3",
        "newrelic": "4.8.1",
        "next": "7.0.0",
        "path-match": "1.2.4",
        "promise-file-reader": "1.0.2",
        "react": "16.5.2",
        "react-autosuggest": "9.4.1",
        "react-dom": "16.5.2",
        "react-load-script": "0.0.6",
        "react-phone-number-input": "2.2.5",
        "react-places-autocomplete": "7.2.0",
        "react-tagsinput": "3.19.0",
        "socket.io-client": "2.1.1",
        "sw-loader": "0.1.2",
        "timeago.js": "3.0.2",
        "uuid": "3.3.2"
    }
good first issue

Most helpful comment

Got this issue after importing nonexistent file in my page/_document and using it in the render function. There were no any import error, only Cannot find module pages/_document. After fixing the import error everything works fine.

To get a detailed error message in _document I renamed it to document page and opened myhost/document.

All 25 comments

Upgrade to Next 7.

This is not a clear and concise reproduction of the issue.

This application was working without problem on 6. Obviously not every 7 next app has this problem, but it could be literally anything since the stack trace is so vague. Additional information:

Stack trace:

at Function.Module._resolveFilename (module.js:538:15)
    at Function.Module._load (module.js:468:25)
    at Module.require (module.js:587:17)
    at require (internal/module.js:11:18)
    at _callee3$ (/Users/seth/Documents/overtime/OvertimeAdmin/node_modules/next/dist/server/render.js:227:17)
    at tryCatch (/Users/seth/Documents/overtime/OvertimeAdmin/node_modules/@babel/runtime-corejs2/node_modules/regenerator-runtime/runtime.js:62:40)
    at Generator.invoke [as _invoke] (/Users/seth/Documents/overtime/OvertimeAdmin/node_modules/@babel/runtime-corejs2/node_modules/regenerator-runtime/runtime.js:288:22)
    at Generator.prototype.(anonymous function) [as next] (/Users/seth/Documents/overtime/OvertimeAdmin/node_modules/@babel/runtime-corejs2/node_modules/regenerator-runtime/runtime.js:114:21)
    at asyncGeneratorStep (/Users/seth/Documents/overtime/OvertimeAdmin/node_modules/@babel/runtime-corejs2/helpers/asyncToGenerator.js:5:24)
    at _next (/Users/seth/Documents/overtime/OvertimeAdmin/node_modules/@babel/runtime-corejs2/helpers/asyncToGenerator.js:27:9) code: 'MODULE_NOT_FOUND' }

next.config.js:

const fs = require('fs');
const config = require('./config');
const _ = require('lodash');

const withCSS = require('@zeit/next-css');

const nextConfig = {
    generateBuildId: () => {
        const id =
            process.env.CIRCLECI === 'true' ? process.env.CIRCLE_SHA1 : fs.readFileSync(process.cwd() + '/BUILD_ID', 'utf8');
        console.log('Build id: ', id);
        return id;
    },
    serverRuntimeConfig: config,
    publicRuntimeConfig: _.pick(config, [
        'AWS_BUCKET_PREFIX',
        'OVERTIME_BACKEND_URL',
        'OVERTIME_AUTH_URL',
        'OVERTIME_VIDEOS_CDN',
        'OVERTIME_VIDEOS_SOCKET',
        'OVERTIME_IMAGES_CDN',
        'GOOGLE_MAPS_API_KEY',
        'OVERTIME_WWW_URL'
    ]),
    webpack: config => {
        config.module.rules.push({
            test: /\.(png|jpg|gif|svg)$/,
            use: [
                {
                    loader: 'file-loader',
                    options: {}
                }
            ]
        });
        return config;
    }
};

module.exports = withCSS(nextConfig);

babel.config.js:

const next = {
    presets: [
        [
            'next/babel',
            {
                'preset-env': {
                    modules: 'commonjs',
                    debug: true
                }
            }
        ]
    ],
    plugins: [['inline-svg']]
};

module.exports = {
    env: {
        test: {
            presets: [
                [
                    'env',
                    {
                        targets: {
                            node: 'current'
                        },
                        modules: 'commonjs'
                    }
                ]
            ]
        },
        production: next,
        development: next
    }
};
{
                'preset-env': {
                    modules: 'commonjs',
                    debug: true
                }
            }

This shouldn't be added. It disabled tree shaking.

Your babel config can be updated to this:

{
  "presets": ["next/babel"],
  "plugins": ["inline-svg"]
}

With Next 7 we automatically enabled modules: 'commonjs' when in the test environment.

Can you create a minimal GitHub repository, this is still not enough to reproduce.

'preset-env': { modules: 'commonjs' }

is necessary to use import in server-side code with next.js

If you want to transpile the custom server, which I wouldn't recommend as your custom server should only be implementing routing and is in most cases not more than 1 file. You can put it into a server directory and add a .babelrc to that directory.

After moving the server file into a subdirectory with its own .babelrc.js and removing the modules config from the root babel config, still getting the Cannot find module error.

If I remove generateBuildId from the next.config.js the problem is resolved, though I can't see any obvious reason why.

@timneutkens
What about

"production": {
      "presets": [["next/babel", {
        "preset-env": {
          "targets": {
            "browsers": ["last 2 versions", "safari >= 7"]
          }
        }
      }]]
    },

???

Ok, here's a minimal repro repo. Looks like babel was a red herring:

https://github.com/sethsamuel/NextTest

The key piece appears to be a generateBuildId function that reads from the file system. npm run build && npm start to see the 500 error.

Changing generateBuildId to return the same value without using fs and it works OK.

Can confirm, same thing -- we were using https://www.npmjs.com/package/simple-git to fetch the latest git commit and it was throwing the same error in prod. Solved it by doing:

BUILD_ID=$(git rev-parse HEAD) next build

And then in next.config.js:

generateBuildId: async () => {
  return process.env.BUILD_ID;
}

The way we use docker makes passing the build id in as a file much preferable to an env var, but good to know it's bypassable if it comes to it.

This is really interesting, I wonder if this could be something related to \n or something being included in the result. The only time we call generateBuildId is when running next build and the result of that is written to BUILD_ID in the .next folder. You can check the code path in build/index.js if you want to debug this further @ivanakimov @sethsamuel

Yep, it looks like a .trim fixes it, so must be a change that removed that safety check in 7. For now just trimming it on the next.config.js side of things.

Feel free to send a PR 👍

We were facing the same issue when updating to NextJS 7, but the difference is that we use next-build-id to handle BUILD_ID. The fix for us was adding the method to next.config.js as suggested in new-in-version-2 .

generateBuildId: async () => {
    const fromGit = await nextBuildId({ dir: __dirname })
    return fromGit.id
  }

Also, make sure your graphql version is up to 14, in our case 14.0.2 according to the issue.

Got this issue after importing nonexistent file in my page/_document and using it in the render function. There were no any import error, only Cannot find module pages/_document. After fixing the import error everything works fine.

To get a detailed error message in _document I renamed it to document page and opened myhost/document.

As @a-kon mentioned, currently any errors that occur when building _document are swallowed (from the dev's perspective), making issues very hard to debug. In my case, I didn't immediately notice that I was doing:

import NextDocument, { Head, Main, NextScript } from "next/document";
import Head from "next/head";

as the error was simply:

Error: Cannot find module '…/.next/server/static/development/pages/_document'

thx @a-kon I can fix my 'import' problem using your renaming method

@sethsamuel I had the same bug, and also I deploy in a docker image as well.

In may case the only way that I could resolve the issue, was removing my git commit id dependency from next.config.js and relay to generate the new BUILD_ID in the same way as you did @sethsamuel did, which was the following:

next.config.js

module.exports = {
...
         generateBuildId: async () => {
        const id = fs.readFileSync(process.cwd() + "/BUILD_ID", "utf8");
        return id;
    }
}

BUILD_ID


The only problem with that is that I need to change my "some_id" each time that I need to build a new docker image right? @sethsamuel

@Jero786 Yes, we run our docker builds using an npm script, and part of that script puts the git commit into the BUILD_ID file to be copied into the container. Then the next build happens inside the container with that file providing the build id.

@sethsamuel Awesome! I'm trying to do that, I'm thinking to do the following way:

FROM node:9

MAINTAINER "[email protected]"

WORKDIR /usr/src/app

COPY package*.json ./

# Install libraries
RUN npm install -g eslint jest now && \
        npm install && \
        mkdir pages && \
        git init && \
    git add --all && \
    git config --global user.email "[email protected]" && \
    git config --global user.name "git test" && \
    git commit -m "commit test" && \
    git log --format="%H" -n 1 > BUILD_ID && \
        npm run build


COPY . .

# EXPOSE 3000

CMD [ "npm", "run", "start" ]

But seems really annoying... because I need to initialize a git context each time, etc. And also, AFAIK, each docker image will have their own BUILD_UI because I'm initializing inside the image the git id. So I don't know if will work with multiple instance properly :S

Do you have a better way to do that? I really appreciate your help on that!
Thanks in advance!

I have the same error. It's just because of Link having 2 children. Good luck!

I had similar issue, had a syntax error in _document.js. Fixed it and moved ahead.

This comment helped

Was this page helpful?
0 / 5 - 0 ratings

Related issues

formula349 picture formula349  ·  3Comments

swrdfish picture swrdfish  ·  3Comments

ghost picture ghost  ·  3Comments

jesselee34 picture jesselee34  ·  3Comments

rauchg picture rauchg  ·  3Comments