next.config.js 2.7 KB

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