vercel / next.js

The React Framework
https://nextjs.org
MIT License
125.83k stars 26.85k forks source link

Cannot find pages/_document target serverless #6691

Closed eddiebeazer closed 5 years ago

eddiebeazer commented 5 years ago

Bug report

{ Error: Cannot find module '/srv/next/server/static/t~h9~HiTNHFDHMSqvJtLw/pages/_document'
    at Function.Module._resolveFilename (module.js:548:15)
    at Function.Module._load (module.js:475:25)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.loadComponents (/srv/node_modules/next-server/dist/server/load-components.js:16:24)
    at Server.renderToHTMLWithComponents (/srv/node_modules/next-server/dist/server/next-server.js:224:48)
    at Server.renderErrorToHTML (/srv/node_modules/next-server/dist/server/next-server.js:260:21)
    at Server.renderToHTML (/srv/node_modules/next-server/dist/server/next-server.js:242:29)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:229:7) code: 'MODULE_NOT_FOUND' }

Describe the bug

I just started my first project with Next and wanted to host on firebase. I started using the with-firebase-hosting and mixed it in with the material-ui example. Zero problems with production builds and deploying. I wanted to use the new serverless build option with the Firebase Hosting example so I upgraded to the latest version of Next(8.0.3). Still no issues with my production build. When I add the "target: serverless" option in my next config I get this error message in my production build whenever I try to load a live page.

Next Config

const withCSS = require('@zeit/next-css');
const withPlugins = require('next-compose-plugins');
const withImages = require('next-images');
const withOffline = require('next-offline');

module.exports = withPlugins(
  [
    withCSS()
  ],
  {
    distDir: '../../dist/functions/next',
    target: "serverless"
  },
  [
    withOffline()
  ],
  [
    withImages()
  ]
);

babelrc

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "8.14"
        }
      }
    ]
  ]
}

_document

import React from 'react';
import PropTypes from 'prop-types';
import Document, { Head, Main, NextScript } from 'next/document';
import flush from 'styled-jsx/server';

//import "../assets/scss/material-kit-react.css";

class MyDocument extends Document {
  render() {
    const { pageContext } = this.props;

    return (
      <html>
        <Head>
          <meta charset="utf-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
          <meta name="theme-color" content="#000000" />
          <link rel="manifest" href="/static/manifest.json" />
          <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png" />
          <link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png" />
          <link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png" />
          <link rel="manifest" href="/static/site.webmanifest" />
          <meta name="msapplication-TileColor" content="#da532c" />
          <meta name="theme-color" content="#ffffff" />
          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jvectormap/2.0.4/jquery-jvectormap.css" type="text/css" media="screen"/>
          <link href="https://use.fontawesome.com/releases/v5.0.7/css/all.css" rel="stylesheet" />
          <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons" />
          <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}

MyDocument.getInitialProps = ctx => {
  // Resolution order
  //
  // On the server:
  // 1. app.getInitialProps
  // 2. page.getInitialProps
  // 3. document.getInitialProps
  // 4. app.render
  // 5. page.render
  // 6. document.render
  //
  // On the server with error:
  // 1. document.getInitialProps
  // 2. app.render
  // 3. page.render
  // 4. document.render
  //
  // On the client
  // 1. app.getInitialProps
  // 2. page.getInitialProps
  // 3. app.render
  // 4. page.render

  // Render app and page and get the context of the page with collected side effects.
  let pageContext;
  const page = ctx.renderPage(Component => {
    const WrappedComponent = props => {
      pageContext = props.pageContext;
      return <Component {...props} />;
    };

    WrappedComponent.propTypes = {
      pageContext: PropTypes.object.isRequired,
    };

    return WrappedComponent;
  });

  let css;
  // It might be undefined, e.g. after an error.
  if (pageContext) {
    css = pageContext.sheetsRegistry.toString();
  }

  return {
    ...page,
    pageContext,
    // Styles fragment is rendered after the app and page rendering finish.
    styles: (
      <React.Fragment>
        <style
          id="jss-server-side"
          // eslint-disable-next-line react/no-danger
          dangerouslySetInnerHTML={{ __html: css }}
        />
        {flush() || null}
      </React.Fragment>
    ),
  };
};

export default MyDocument;

_app

import React from 'react';
import App, { Container } from 'next/app';
import Head from 'next/head';
import { MuiThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import JssProvider from 'react-jss/lib/JssProvider';
import getPageContext from '../getPageContext';

class MyApp extends App {
  constructor() {
    super();
    this.pageContext = getPageContext();
  }

  componentDidMount() {
    // Remove the server-side injected CSS.
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles && jssStyles.parentNode) {
      jssStyles.parentNode.removeChild(jssStyles);
    }
  }

  render() {
    const { Component, pageProps } = this.props;
    return (
      <Container>
        <Head>
          <title>My page</title>
        </Head>
        {/* Wrap every page in Jss and Theme providers */}
        <JssProvider
          registry={this.pageContext.sheetsRegistry}
          generateClassName={this.pageContext.generateClassName}
        >
          {/* MuiThemeProvider makes the theme available down the React
              tree thanks to React context. */}
          <MuiThemeProvider
            theme={this.pageContext.theme}
            sheetsManager={this.pageContext.sheetsManager}
          >
            {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
            <CssBaseline />
            {/* Pass pageContext to the _document though the renderPage enhancer
                to render collected styles on server-side. */}
            <Component pageContext={this.pageContext} {...pageProps} />
          </MuiThemeProvider>
        </JssProvider>
      </Container>
    );
  }
}

export default MyApp;

package.json

{
  "name": "with-firebase-hosting",
  "version": "4.0.1",
  "description": "Host Next.js SSR app on Firebase Cloud Functions with Firebase Hosting redirects.",
  "engines": {
    "node": "8"
  },
  "scripts": {
    "dev": "next \"src/app/\" -p 4000",
    "preserve": "npm run build-public && npm run build-funcs && npm run build-app && npm run copy-deps && npm run install-deps",
    "serve": "cross-env NODE_ENV=production firebase serve",
    "predeploy": "npm run build-public && npm run build-funcs && npm run build-app && npm run copy-deps && npm run copy-static",
    "deploy": "yarn deploy-functions",
    "deploy-functions": "firebase deploy --only functions:next",
    "clean": "rimraf \"dist/functions/**\" && rimraf \"dist/public\"",
    "build-public": "cpx \"src/public/**/*.*\" \"dist/public\" -C",
    "build-funcs": "babel \"src/functions\" --out-dir \"dist/functions\"",
    "build-app": "next build \"src/app/\"",
    "copy-static": "cpx \"src/app/static/*\" \"dist/functions/static\" -C",
    "copy-deps": "cpx \"*{package.json,package-lock.json,yarn.lock}\" \"dist/functions\" -C",
    "install-deps": "cd \"dist/functions\" && npm i"
  },
  "dependencies": {
    "@material-ui/core": "3.1.1",
    "@material-ui/icons": "3.0.1",
    "@zeit/next-css": "^1.0.1",
    "auth0-js": "^9.10.0",
    "axios": "^0.18.0",
    "classnames": "^2.2.6",
    "firebase-admin": "^6.3.0",
    "firebase-functions": "^2.1.0",
    "jss": "^9.8.7",
    "next": "^8.0.3",
    "next-compose-plugins": "^2.1.1",
    "next-images": "^1.1.1",
    "next-offline": "^3.3.6",
    "prop-types": "^15.7.2",
    "react": "16.8.4",
    "react-dom": "16.8.4",
    "react-jss": "^8.6.1",
    "react-markdown": "^4.0.6",
    "remark": "^10.0.1",
    "styled-jsx": "^3.2.1"
  },
  "devDependencies": {
    "@babel/cli": "^7.2.0",
    "cpx": "^1.5.0",
    "cross-env": "^5.2.0",
    "firebase-tools": "^6.1.0",
    "rimraf": "^2.6.0"
  }
}

Expected behavior

Was expecting the serverless option to deploy my functions on firebase and increase the efficiency of cold starts. I also did not know whether the serverless option works with firebase in general. When I remove the serverless option in my next config, my production build works flawlessly, it jut has long cold starts(30-45s).

System information

This is my first time submitting an issue, please let me know if I left out anything useful :)

eddiebeazer commented 5 years ago

Cleaning my dist folder and rebuilding solved the issue for me. Thought I already did this but it turns out that I didn't 🙄