Skip to content

extremely slow builds / vercel crashes and fails to build our app #26588

@zallarak

Description

@zallarak

Describe the feature you'd like to request

next.js version: 10.2.0

here is our next.js config

const withAntdLess = require("next-plugin-antd-less");
const nextConstants = require("next/constants");
const path = require("path");

const makeCommitSHA = () => {
  const {
    VERCEL_GITHUB_COMMIT_SHA,
    GITHUB_SHA,
    GCLOUD_COMMIT_SHA,
  } = process.env;
  return (
    GCLOUD_COMMIT_SHA || VERCEL_GITHUB_COMMIT_SHA || GITHUB_SHA || "unknown"
  );
};
const makeSentryReleaseID = () => {
  const {
    VERCEL_GITHUB_COMMIT_SHA,
    GITHUB_SHA,
    GCLOUD_COMMIT_SHA,
    SENTRY_RELEASE_ID,
  } = process.env;
  if (SENTRY_RELEASE_ID) {
    return SENTRY_RELEASE_ID;
  }
  if (GCLOUD_COMMIT_SHA) {
    return `gcloud-${GCLOUD_COMMIT_SHA || "unknown"}`;
  }
  if (VERCEL_GITHUB_COMMIT_SHA) {
    return VERCEL_GITHUB_COMMIT_SHA || "unknown";
  }
  if (GITHUB_SHA) {
    return GITHUB_SHA || "unknown";
  }
  return "unknown";
};

const sentryReleaseIDBase = `frontend@${makeSentryReleaseID()}`;
const shouldGenerateSourceMaps =
  process.env.SENTRY_AUTH_TOKEN && sentryReleaseIDBase !== "frontend@unknown";

module.exports = (phase) => {
  const config = withAntdLess({
    reactStrictMode: true,
    productionBrowserSourceMaps: shouldGenerateSourceMaps,
    compress: true,
    images: {
      domains: ["logo.clearbit.com"],
    },
    serverRuntimeConfig: {
      NODE_ENV: process.env.NODE_ENV,
      DOMAIN: process.env.DOMAIN,
      // Third-parties
      LOGROCKET_APP_ID: process.env.LOGROCKET_APP_ID,
      SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY,
      PLAID_ENV: process.env.PLAID_ENV,
      STRIPE_PUBLIC_KEY: process.env.STRIPE_PUBLIC_KEY,
      STRIPE_OAUTH_CLIENT_ID: process.env.STRIPE_OAUTH_CLIENT_ID,
      GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY,
      SENTRY_ENVIRONMENT: process.env.SENTRY_ENVIRONMENT,
      // optional
      MODE: process.env.MODE,
      FEATURE_FLAGS: process.env.FEATURE_FLAGS,
      SENTRY_DSN: process.env.SENTRY_DSN,
    },
    lessVarsFilePath: "./antdThemeVariables.less",
    webpack: (config, { isServer, webpack }) => {
      // sentry stuff
      // In `pages/_app.js`, Sentry is imported from @sentry/node. While
      // @sentry/react will run in a Node.js environment, @sentry/node will use
      // Node.js-only APIs to catch even more unhandled exceptions.
      //
      // This works well when Next.js is SSRing your page on a server with
      // Node.js, but it is not what we want when your client-side bundle is being
      // executed by a browser.
      //
      // Luckily, Next.js will call this webpack function twice, once for the
      // server and once for the client. Read more:
      // https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config
      //
      // So ask Webpack to replace @sentry/node imports with @sentry/react when
      // building the browser's bundle
      // and vice versa
      if (isServer) {
        config.resolve.alias["@sentry/react"] = "@sentry/node";
        config.resolve.alias["@sentry/node"] = "@sentry/node";
      } else {
        config.resolve.alias["@sentry/node"] = "@sentry/react";
        config.resolve.alias["@sentry/react"] = "@sentry/react";
      }

      // See: https://github.com/momopig/react-antd-icons
      config.resolve.alias["@ant-design/icons/lib"] = path.resolve(
        __dirname,
        "./styleMock.tsx"
      );

      config.plugins = config.plugins || [];

      // ignore calls to graphql
      config.plugins.push(
        new webpack.ProvidePlugin({
          graphql: "lodash/noop",
        })
      );

      if (phase === nextConstants.PHASE_PRODUCTION_BUILD) {
        const SENTRY_RELEASE_ID = `${sentryReleaseIDBase}${
          isServer ? "-server" : ""
        }`;

        // Sentry release ID should be hardcoded in the build
        config.plugins.push(
          new webpack.DefinePlugin({
            COMMIT_SHA: JSON.stringify(makeCommitSHA()),
            SENTRY_RELEASE_ID: JSON.stringify(SENTRY_RELEASE_ID),
          })
        );

        const { SENTRY_AUTH_TOKEN } = process.env;
        if (SENTRY_AUTH_TOKEN) {
          console.log(
            `Publishing sourcemaps to Sentry under release id ${SENTRY_RELEASE_ID}`
          );
          const SentryWebpackPlugin = require("@sentry/webpack-plugin");
          config.plugins.push(
            new SentryWebpackPlugin({
              // sentry-cli configuration
              authToken: SENTRY_AUTH_TOKEN,
              org: "pipe",
              project: "frontend",
              include: ".next",
              ignore: ["node_modules"],
              stripPrefix: ["webpack://_N_E/"],
              urlPrefix: `~/_next`,
              release: SENTRY_RELEASE_ID,
            })
          );
        }
        if (shouldGenerateSourceMaps) {
          // This lets Sentry have the sourcemaps without
          // exposing the URL of the source code to the client.
          // In production, we also delete sourcemaps.
          // TODO(igm): private server to host sourcemaps
          // See https://webpack.js.org/configuration/devtool/
          config.devtool = "hidden-source-map";
        }
      } else {
        // Default commit sha/sentry release ID for local dev
        config.plugins.push(
          new webpack.DefinePlugin({
            COMMIT_SHA: JSON.stringify("local-unknown"),
            SENTRY_RELEASE_ID: JSON.stringify("local-unknown"),
          })
        );
      }

      return config;
    },
    typescript: {
      // !! WARN !!
      // Dangerously allow production builds to successfully complete even if
      // your project has type errors.
      // !! WARN !!
      // this is OK because we have type checking in a GH action
      ignoreBuildErrors: true,
    },
    async redirects() {
      return [
        // vendor
        {
          source: "/",
          destination: "/inbox",
          permanent: true,
        },
        {
          source: "/link",
          destination: "/welcome",
          permanent: true,
        },
        {
          source: "/onboard",
          destination: "/welcome",
          permanent: true,
        },
        {
          source: "/settings/payments",
          destination: "/finance/lists/all-transactions",
          permanent: true,
        },
        {
          source: "/settings/payments/:paymentID",
          destination: "/finance/payouts/:paymentID",
          permanent: true,
        },
        {
          source: "/finance/payments",
          destination: "/finance/lists/all-payments",
          permanent: true,
        },
        {
          source: "/finance/payouts",
          destination: "/finance/lists/all-payouts",
          permanent: true,
        },

        // admin
        {
          source: "/admin/subscriptions",
          destination: "/admin/lists/create/subscriptionsv2",
          permanent: true,
        },
        {
          source: "/admin/users",
          destination: "/admin/lists/pipe-admin-users",
          permanent: true,
        },
        {
          source: "/admin/vendors",
          destination: "/admin/lists/create/vendors",
          permanent: true,
        },
        {
          source: "/admin/connectors",
          destination: "/admin/lists/create/connectors",
          permanent: true,
        },
      ];
    },
  });

  if (process.env.ANALYZE === "true") {
    const withBundleAnalyzer = require("@next/bundle-analyzer")({
      enabled: true,
    });
    return withBundleAnalyzer(config);
  }

  return config;
};

Describe the solution you'd like

help debugging or resolution - right now vercel is not usable and we must use google cloud

Describe alternatives you've considered

moving to react or using higher performance machines

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions