Yeshwanth Kumar
Yeshwanth Kumar

Reputation: 121

Invalid next.config.js options detected - Root value has unexpected property

Updated my next version from 10 to 12 and when I run the local dev server getting the following error in terminal and therefore the code does not compile. How do I resolve this?

Invalid next.config.js options detected:

My current next config file

const composePlugins = require ('next-compose-plugins');
const css = require('@zeit/next-css');
const optimizedImages = require ('next-optimized-images');
const transpileModules = require ('next-transpile-modules');
const path = require ('path');
const readFileSync = require ('jsonfile').readFileSync;
const realpathSync = require ('fs').realpathSync;
const resolve = require ('resolve');
const sass = require('@zeit/next-sass');
const lodashWebpack = require ('lodash-webpack-plugin');

// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebookincubator/create-react-app/issues/637
const appDirectory = realpathSync (process.cwd ());
const resolveApp = relativePath => path.resolve (appDirectory, relativePath);
const paths = require (resolveApp ('config/paths'));
const packageJson = readFileSync (paths.appPackageJson);
// const withPreact = require('next-plugin-preact');

const root = packageJson.homepage;
const dev = !(process.env.NODE_ENV
  ? process.env.NODE_ENV.indexOf (`production`) + 1
  : false);
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
const withBundleAnalyzer = require ('@next/bundle-analyzer') ({
  enabled: process.env.ANALYZE === 'true',
});
let nextEnv = process.env.NEXT_ENV;
for (let argument of process.argv) {
  if (argument.indexOf (`--next-env=`) > -1) {
    nextEnv = argument.split (`=`)[1];
  }
}
const nextConfig = {
   async redirects() {
    return [
      {
        source: '/',
        destination: '/forbusiness',
        basePath: false,
        permanent: false,
      },
    ]
  },
  assetPrefix: '/forbusiness',
  basePath: '/forbusiness',
  images: {
    domains: ['att.com', 'directv.com'],
  },
  devIndicators: {
    autoPrerender: false,
  },
  distDir: `dist`,
  // Will only be available on the server side
  serverRuntimeConfig: {
    devProxy: process.env.APP_DEV_PROXY,
    nextEnv,
    popCacheInt: process.env.UF_CACHE_INT,
    pxy: process.env.APP_HTTP_PROXY,
    solrEnv: process.env.IDP_SOLR_ENV,
  },
  // Will be available on both server and client.
  publicRuntimeConfig: {
    NEXT_PUBLIC_ENV: process.env.NEXT_PUBLIC_ENV,
    prod: !dev,
    root,
    local: process.env.ENV,
    NEXT_PUBLIC_MICROPROPERTIES_OID: process.env.NEXT_PUBLIC_MICROPROPERTIES_OID,
    NEXT_PUBLIC_MICROPROPERTIES_RECORD_TYPE: process.env.NEXT_PUBLIC_MICROPROPERTIES_RECORD_TYPE,
    NEXT_PUBLIC_MICROPROPERTIES_ORG_BASE_URL: process.env.NEXT_PUBLIC_MICROPROPERTIES_ORG_BASE_URL
  },
  // Use a consistent build id for deployments in multiple locations:
  // See: https://github.com/zeit/next.js#configuring-the-build-id
  generateBuildId: async () => {
    return packageJson.version;
  },
  webpack: (config, options) => {
    const {dir, isServer} = options;
    const newConfig = {...config};
    const originalEntry = newConfig.entry;

    newConfig.externals = [];

    // Some libraries import Node modules but don't use them in the browser.
    // Tell Webpack to provide empty mocks for them so importing them works.
    newConfig.node = {
      dgram: `empty`,
      dns: `empty`,
      fs: `empty`,
      net: `empty`,
      tls: `empty`,
      child_process: `empty`,
      path: 'empty',
      __dirname: true,
    };

    newConfig.entry = async () => {
      const entries = await originalEntry ();
      if (
        entries['main.js'] &&
        !entries['main.js'].includes ('./src/services/Polyfills/polyfill.js')
      ) {
        entries['main.js'].unshift ('./src/services/Polyfills/polyfill.js');
      }
      return entries;
    };

    // Rename the webpack function to not conflict with the dynatrace webpack function.
    newConfig.output.jsonpFunction = `salesJsonp`;

    if (isServer) {
      newConfig.externals.push ((context, request, callback) => {
        resolve (
          request,
          {basedir: dir, preserveSymlinks: true},
          (err, res) => {
            if (err) {
              return callback ();
            }
            if (
              res.match (/node_modules[/\\].*\.js/) &&
              !res.match (/node_modules[/\\]webpack/) &&
              !res.match (/node_modules[/\\]@idp/) &&
              !res.match (/node_modules[/\\]@video/)
            ) {
              return callback (null, `commonjs ${request}`);
            }
            callback ();
          }
        );
      });
    }
    newConfig.module.rules.push ({
      test: /\.(woff|woff2|eot|ttf|otf)$/,
      use: [
        {
          loader: 'url-loader',
          options: {
            limit: 100000,
            fallback: 'file-loader',
            outputPath: `./static/fonts/`,
          },
        },
      ],
    });
    newConfig.plugins = newConfig.plugins.filter (plugin => {
      if (plugin.constructor.name === 'ForkTsCheckerWebpackPlugin')
        return false;
      return true;
    });
    return newConfig;
  },
};

module.exports = composePlugins (
  [
    [
      lodashWebpack,
      {
        caching: true,
        exotics: true,
      },
    ],
    [
      optimizedImages,
      {
        svgo: {
          plugins: [
            {
              removeComments: true,
              cleanupAttrs: true,
              inlineStyles: true,
              minifyStyles: true,
            },
          ],
        },
      },
    ],    
    [css, {
        cssModules: true,
        cssLoaderOptions: {
            camelCase: true,
            import: true,
            importLoaders: 1,
            localIdentName: dev ? '_[local]_[hash:base64:5]' : `_[hash:base64:5]`,
            minimize: true,
            modules: true,
            sourceMap: shouldUseSourceMap,
        },
    }],
    [sass, {
        cssModules: true,
        cssLoaderOptions: {
            camelCase: true,
            import: true,
            importLoaders: 1,
            localIdentName: dev ? '_[local]_[hash:base64:5]' : `_[hash:base64:5]`,
            minimize: true,
            modules: true,
            sourceMap: shouldUseSourceMap,
        },
        sassLoaderOptions: {
            outputStyle: 'compressed',
            precision: 5,
        }
    }],
    [withBundleAnalyzer, {}],
  ],
  nextConfig
);

Upvotes: 5

Views: 27990

Answers (2)

Ahmet Firat Keler
Ahmet Firat Keler

Reputation: 4075

Actually next-compose-plugins npm package works with the latest version of Next.

The root value has an unexpected property, webpackDevMiddleware, which is not in the list of allowed properties (amp, analyticsId, assetPrefix, basePath, cleanDistDir, compiler, compress, crossOrigin, devIndicators, distDir, env, eslint, excludeDefaultMomentLocales, experimental, exportPathMap, future, generateBuildId, generateEtags, headers, httpAgentOptions, i18n, images, onDemandEntries, optimizeFonts, output, outputFileTracing, pageExtensions, poweredByHeader, productionBrowserSourceMaps, publicRuntimeConfig, reactStrictMode, redirects, rewrites, sassOptions, serverRuntimeConfig, staticPageGenerationTimeout, swcMinify, trailingSlash, typescript, useFileSystemPublicRoutes, webpack).

To get rid of this, you need to remove that key from the defaultConfig object.

Official documentation says: 'Since Next.js 12.1.0, you can use an async function'

So we update or next config from this

const { withSentryConfig } = require('@sentry/nextjs');

const moduleExports = {
 // next config
};

const sentryWebpackPluginOptions = {
 // sentry config
}

const withPlugins = require('next-compose-plugins')
const withBundleAnalyzer = require('@next/bundle-analyzer')({
 enabled: process.env.ANALYZE === 'true',
})

module.exports = withPlugins(
    [withBundleAnalyzer],
    withSentryConfig(moduleExports, sentryWebpackPluginOptions)
);

to this

const { withSentryConfig } = require('@sentry/nextjs');

const moduleExports = {
 // next config
};

const sentryWebpackPluginOptions = {
 // sentry config
}

const withPlugins = require('next-compose-plugins')
const withBundleAnalyzer = require('@next/bundle-analyzer')({
 enabled: process.env.ANALYZE === 'true',
})

module.exports = async (phase, { defaultConfig }) => {
 delete defaultConfig['webpackDevMiddleware'];

 return withPlugins(
     [withBundleAnalyzer],
     withSentryConfig(moduleExports, sentryWebpackPluginOptions)
 )(phase, { defaultConfig });
}

This applies to the other props such as 'configOrigin', we just remove it as we did for webpackDevMiddleware.

delete defaultConfig['configOrigin'];

Further reading

https://nextjs.org/docs/api-reference/next.config.js/introduction

Upvotes: 3

rschristian
rschristian

Reputation: 2967

next-compose-plugins doesn't work with newer versions of Next. You'll need to remove it and rebuild your config.

See: https://github.com/cyrilwanner/next-compose-plugins/issues/59

Upvotes: 5

Related Questions