cyrilwanner / next-compose-plugins

đź’ˇnext-compose-plugins provides a cleaner API for enabling and configuring plugins for next.js
MIT License
736 stars 12 forks source link

How to do with a custom next.config.js #36

Open rahul3103 opened 4 years ago

rahul3103 commented 4 years ago

How can i use next-compose-plugins here?

/* eslint-disable no-param-reassign */
/* eslint-disable no-console */
const {
  PHASE_DEVELOPMENT_SERVER,
  PHASE_PRODUCTION_SERVER,
  PHASE_PRODUCTION_BUILD
} = require('next/constants');

const withPWA = require('next-pwa');
const optimizedImages = require('next-optimized-images');
const withVideos = require('next-videos');
const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true'
});

const nextConfig = (phase) => {
  const isDev = phase === PHASE_DEVELOPMENT_SERVER;
  const isProd = phase === PHASE_PRODUCTION_SERVER;
  const isProdBuild = phase === PHASE_PRODUCTION_BUILD;
  let assetPrefix = `${process.env.ASSET_PREFIX}${process.env.SERVER}`;
  let PUBLIC = `${assetPrefix}/_next`;
  if (isDev || !process.env.SERVER) {
    assetPrefix = '';
    PUBLIC = '';
  }

  return {
    assetPrefix,
    analyzeServer: ['server', 'both'].includes(process.env.BUNDLE_ANALYZE),
    analyzeBrowser: ['browser', 'both'].includes(process.env.BUNDLE_ANALYZE),
    optimizeImagesInDev: true,
    removeOriginalExtension: true,
    assetDirectory: 'static',
    bundleAnalyzerConfig: {
      server: {
        analyzerMode: 'static',
        reportFilename: '../bundles/server.html'
      },
      browser: {
        analyzerMode: 'static',
        reportFilename: '../bundles/client.html'
      }
    },
    pwa: {
      disable: isDev,
      register: true,
      dest: 'public',
      sw: 'sw.js'
    },
    env: {
      isDev,
      isProd,
      isProdBuild,
      APP_ENV: process.env.APP_ENV,

    },
    webpack(config, { isServer }) {
      if (!isServer) {
        config.resolve.alias['@sentry/node'] = '@sentry/browser';
      }
      return config;
    }
  };
};

module.exports = (phase) =>
  withBundleAnalyzer(withPWA(optimizedImages(withVideos(nextConfig(phase)))));
wilbsy commented 3 years ago

@rahul3103 rahul3103 You can achieve this by extending the next.config you posted.

I ran across this because I was trying to use the same type of isDev logic in my next-compose-plugins driven next.config, and extending a base config was the solution I settled on. However, I feel there's likely a better option for simply exposing the phase (especially since it's easy to mistakenly overwrite the entire env object in the encapsulating next.config).

@cyrilwanner Could you clarify how to reproduce the phase logic detailed in this next example using next-compose-plugins syntax?

Thank you!

FranciscoG commented 3 years ago

The extending thing didn't quite work for me so I ended up writing my config like another plugin

const withPlugins = require('next-compose-plugins');
const optimizedImages = require('next-optimized-images');
const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
});
const siteMap = require('./scripts/sitemap'); // this is just a plain node script

function ourConfig(nextConfig = {}) {
  // can do logic that doesn't depend on webpack config or options here
  return Object.assign({}, nextConfig, {
    webpack(config, options) {
      // logic that depends on config/options here
      if (options.isServer) {
        siteMap({
          // use globby patters to full path inside `/src`
          exclude: ['!pages/temp-page.js'],
        });
      }

     // I needed to add a way to raw load markdown files so I can process them with remark
      config.module.rules.push({
        test: /\.md$/,
        loader: 'raw-loader',
      });
      if (typeof nextConfig.webpack === 'function') {
        return nextConfig.webpack(config, options);
      }
      return config;
    },
  });
}

module.exports = withPlugins([
  [withBundleAnalyzer({})],
  [ourConfig()],
  [
    optimizedImages,
    {
      responsive: {
        adapter: require('responsive-loader/sharp'),
      },
      pngquant: {
        speed: 10,
      },
    },
  ],
]);
FunctionDJ commented 3 years ago

I wanted to find a way to use the phase inside my nextConfig and i came up with this:

function getNextConfig(phase) {
  return {
    // ...
  }
}

module.exports = (phase, ...rest) => {
  const nextConfig = getNextConfig(phase);
  return withPlugins(plugins, nextConfig)(phase, ...rest);
};