dc7290 / next-export-optimize-images

Optimize images at build time with Next.js.
https://next-export-optimize-images.vercel.app
MIT License
384 stars 35 forks source link

Module imports broken for config files with a `.cjs` or `.mjs` file extension #901

Open theorib opened 4 months ago

theorib commented 4 months ago

Describe the bug

next-export-optimize-images fails to recognise export-images.config files that use either .cjs or .mjs extensions. It only recognises files with a .js extension.

This severely limits the library usage since depending on your project configuration, by not using either .cjs or .mjs extensions it's not possible for the config file to resolve imports correctly.

I have tried this with both the current (v4.4.0) and the previous version of the library. I have also tried this with different content inside the export-images.config.cjs.

To Reproduce Steps to reproduce the behavior:

  1. Use an export-images.config.cjs or export-images.config.mjs file instead of export-images.config.js regardless of its content.
  2. Build or run the project in dev mode (npm run dev or npm run build)
  3. You should see the following error message at the beginning of the build/run process: info - [next-export-optimize-images]: Configuration was not loaded. (This is optional.)

Expected behavior The library should be able to recognise at least export-images.config.cjs config files. If the developer wishes to support ESM files that would be even better but it's not necessary to solve this issue.

Desktop (please complete the following information):

Here is my next.config.mjs file

import withExportImages from 'next-export-optimize-images';
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  images: {
    deviceSizes: [390, 430, 640, 768, 1080, 1280, 1920, 2560, 3840],
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.theoribeiro.com',
        port: '',
      },
    ],
  },
  // we will handle errors with git action hooks
  typescript: {
    ignoreBuildErrors: true,
  },
  eslint: {
    ignoreDuringBuilds: true,
  },
};
export default withExportImages(nextConfig);

*Here is my export-images.config.cjs file

/**
 * @typedef {import('./src/data/stillsPortfolio').StillsPortfolioItem} StillsPortfolioItem
 */
module.exports = {
  convertFormat: [
    ['png', 'webp'],
    ['jpg', 'avif'],
  ],
  generateFormats: ['avif', 'webp'],
  remoteImages: async () => {
    const { default: portfolioActions } = await import(
      '@/actions/portfolioActions'
    );
    const { default: paths } = await import('@/lib/paths');
    /** @type {StillsPortfolioItem} */
    const stillsPortfolio = await import('@data/stillsPortfolio');
    const portfolioImageUrls = portfolioActions
      .getPortfolioItems()
      .map(item => paths.remoteAssetsPath() + item.imageUrl);
    /** @type {string} */
    const stillsPortfolioUrls = stillsPortfolio.map(
      item => paths.remoteAssetsPath() + item.src,
    );
    const aboutImage =
      paths.remoteAssetsPath() + 'img/TR_2019_008_000504_LeicaQ_Web.jpg';
    const imageArr = [
      ...portfolioImageUrls,
      ...stillsPortfolioUrls,
      aboutImage,
    ];
    return imageArr;
  },
};

Additional context

If at any point I remove the .cjs extension from my file. I get the following error in my terminal when building or running the project in dev mode. Bear in mind this problem is not related to using url path aliases as it also does not work when using relative paths for the imports. I tried doing this in multiple different ways.

If I remove all the imports and hardcode values, this library works as intended.

node:internal/modules/esm/resolve:841
  throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base), null);
        ^
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@/actions' imported from /Users/theorib/Development/theoribeiro.com-next/export-images.config.js
    at packageResolve (node:internal/modules/esm/resolve:841:9)
    at moduleResolve (node:internal/modules/esm/resolve:914:18)
    at defaultResolve (node:internal/modules/esm/resolve:1119:11)
    at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:542:12)
    at ModuleLoader.resolve (node:internal/modules/esm/loader:511:25)
    at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:241:38)
    at ModuleLoader.import (node:internal/modules/esm/loader:474:34)
    at defaultImportModuleDynamicallyForScript (node:internal/modules/esm/utils:227:31)
    at importModuleDynamicallyCallback (node:internal/modules/esm/utils:249:12)
    at Object.remoteImages (/Users/theorib/Development/theoribeiro.com-next/export-images.config.js:13:43) {
  code: 'ERR_MODULE_NOT_FOUND'
}
dc7290 commented 4 months ago

Certainly, at least for .cjs, support is mandatory!

dc7290 commented 3 months ago

Support was added in v4.5.0 for .cjs! https://github.com/dc7290/next-export-optimize-images/releases/tag/v4.5.0

stevenkkim commented 2 months ago

I think this may be related, but when I updated from 3.3.0 to 4.5.0, all of my pages returned 404 not found error. My config file is using mjs (next.config.mjs) which may be the culprit. I just reverted back to 3.3.0 for now which works fine. I'm on Windows 10 using Chrome.

theorib commented 2 months ago

I think this may be related, but when I updated from 3.3.0 to 4.5.0, all of my pages returned 404 not found error. My config file is using mjs (next.config.mjs) which may be the culprit. I just reverted back to 3.3.0 for now which works fine. I'm on Windows 10 using Chrome.

In all probability, the fact that you were using next.config.mjs would not have caused the bug you are seeing. I had been using it like that before the latest version without any issues. That last update was to support using .cjs extension in the export-images.config file instead. It's possible the bug you are seeing is happening for a different reason.

stevenkkim commented 2 months ago

Thanks for the info @theorib. I don't have time to dig into the bug right now, but I will later when I have a chance. Much appreciated.