next.config.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /**
  2. * == Notes for production build==
  3. * The modules required from this file must be transpiled before running `next build`.
  4. *
  5. * See: https://github.com/vercel/next.js/discussions/35969#discussioncomment-2522954
  6. */
  7. const eazyLogger = require('eazy-logger');
  8. const { withSuperjson } = require('next-superjson');
  9. const { i18n, localePath } = require('./src/next-i18next.config');
  10. const isProduction = process.env.NODE_ENV === 'production';
  11. const isBuildingNext = process.env.BUILDING_NEXT === 'true';
  12. // define additional entries
  13. const additionalWebpackEntries = {
  14. boot: './src/client/boot',
  15. };
  16. /** @type {import('next').NextConfig} */
  17. const nextConfig = {
  18. // == DOES NOT WORK
  19. // see: https://github.com/vercel/next.js/discussions/27876
  20. // experimental: { esmExternals: true }, // Prefer loading of ES Modules over CommonJS
  21. reactStrictMode: true,
  22. typescript: {
  23. tsconfigPath: 'tsconfig.build.client.json',
  24. },
  25. pageExtensions: ['page.tsx', 'page.ts', 'page.jsx', 'page.js'],
  26. i18n,
  27. /** @param config {import('next').NextConfig} */
  28. webpack(config, options) {
  29. // Avoid "Module not found: Can't resolve 'fs'"
  30. // See: https://stackoverflow.com/a/68511591
  31. if (!options.isServer) {
  32. config.resolve.fallback.fs = false;
  33. }
  34. // See: https://webpack.js.org/configuration/externals/
  35. // This provides a way of excluding dependencies from the output bundles
  36. config.externals.push('dtrace-provider');
  37. // configure additional entries
  38. const orgEntry = config.entry;
  39. config.entry = () => {
  40. return orgEntry().then((entry) => {
  41. return { ...entry, ...additionalWebpackEntries };
  42. });
  43. };
  44. const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
  45. config.plugins.push(
  46. new WebpackManifestPlugin({
  47. fileName: 'custom-manifest.json',
  48. }),
  49. );
  50. // setup i18next-hmr
  51. if (!options.isServer && options.dev) {
  52. const { I18NextHMRPlugin } = require('i18next-hmr/plugin');
  53. config.plugins.push(new I18NextHMRPlugin({ localesDir: localePath }));
  54. }
  55. return config;
  56. },
  57. };
  58. const passThrough = nextConfig => nextConfig;
  59. let withTM = passThrough;
  60. if (!isProduction || isBuildingNext) {
  61. const { listScopedPackages, listPrefixedPackages } = require('./src/utils/next.config.utils');
  62. // setup logger
  63. const logger = eazyLogger.Logger({
  64. prefix: '[{green:next.config.js}] ',
  65. useLevelPrefixes: false,
  66. });
  67. const setupWithTM = () => {
  68. // define transpiled packages for '@growi/*'
  69. const packages = [
  70. ...listScopedPackages(['@growi'], { ignorePackageNames: ['@growi/app'] }),
  71. // listing ESM packages until experimental.esmExternals works correctly to avoid ERR_REQUIRE_ESM
  72. 'react-markdown',
  73. 'unified',
  74. 'comma-separated-tokens',
  75. 'decode-named-character-reference',
  76. 'html-void-elements',
  77. 'property-information',
  78. 'space-separated-tokens',
  79. 'trim-lines',
  80. 'web-namespaces',
  81. 'vfile',
  82. 'zwitch',
  83. 'emoticon',
  84. ...listPrefixedPackages(['remark-', 'rehype-', 'hast-', 'mdast-', 'micromark-', 'micromark-', 'unist-']),
  85. ];
  86. logger.info('{bold:Listing scoped packages for transpiling:}');
  87. logger.unprefixed('info', `{grey:${JSON.stringify(packages, null, 2)}}`);
  88. return require('next-transpile-modules')(packages);
  89. };
  90. withTM = setupWithTM();
  91. }
  92. module.exports = withSuperjson()(withTM(nextConfig));