martpie / next-transpile-modules

Next.js plugin to transpile code from node_modules. Please see: https://github.com/martpie/next-transpile-modules/issues/291
MIT License
1.13k stars 85 forks source link

Module not found for transitive ESM modules #264

Closed shishkin closed 1 year ago

shishkin commented 2 years ago

Are you trying to transpile a local package or an npm package? Local scoped package.

Describe the bug

I had a working TM setup with CJS modules. Now I'm trying to switch to ESM and get issues with transpilation. Due to ESM requirements, relative TS imports have to have .js extension. This causes the issue when I import a TS module my-esm-module on a page without extension, then TM transpiles it fails to load ./util.js (because it is ./util.ts).

Here are the logs:

info  - Creating an optimized production build
Failed to compile.

../my-esm-module/src/index.ts
Module not found: Can't resolve './util.js' in '/Users/user/my-project/packages/my-esm-module/src'

To Reproduce

Following the steps in this guide.

Expected behavior

Webpack should pick the right .ts file extension when looking up transitive imports.

Setup

next.config.js:

/* eslint-disable @typescript-eslint/no-var-requires */
const withTM = require("next-transpile-modules")([
  "my-esm-module",
]);

// @type {import('next').NextConfig}
const nextConfig = {
  reactStrictMode: true,
};

module.exports = withTM(nextConfig);

Additional context Add any other context about the problem here.

martpie commented 2 years ago

Can you enable the debug mode and paste the full logs here?

shishkin commented 2 years ago

Hi @martpie, thanks for the quick reply. I've reproduced the issue in a fork of your example repo: https://github.com/martpie/monorepo-typescript-next-the-sane-way/compare/master...shishkin:esm.

Here is the debug output of the build:

> yarn workspace @local/website build
yarn workspace v1.22.18
yarn run v1.22.18
$ next build
next-transpile-modules - trying to resolve the following modules:
  - @local/shared
next-transpile-modules - the following paths will get transpiled:
  - /Users/serega/code/oss/monorepo-typescript-next-the-sane-way/shared
info  - Checking validity of types
info  - Creating an optimized production build ...next-transpile-modules - transpiled: /Users/serega/code/oss/monorepo-typescript-next-the-sane-way/shared/src/index.ts
info  - Creating an optimized production build
Failed to compile.

../shared/src/index.ts
Module not found: Can't resolve './calc.js' in '/Users/serega/code/oss/monorepo-typescript-next-the-sane-way/shared/src'

Import trace for requested module:
./pages/index.tsx

> Build failed because of webpack errors
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed.
Exit code: 1
Command: /Users/serega/.fnm/node-versions/v16.13.0/installation/bin/node
Arguments: /Users/serega/.fnm/node-versions/v16.13.0/installation/lib/node_modules/yarn/lib/cli.js build
Directory: /Users/serega/code/oss/monorepo-typescript-next-the-sane-way/website
Output:

info Visit https://yarnpkg.com/en/docs/cli/workspace for documentation about this command.
shishkin commented 2 years ago

It actually works if I change the import line in index.tsx to import * as Calc from "../../shared/src/calc";. So I wonder if TM could be made aware of and account for module dependencies.

tmadison-gpsw commented 2 years ago

Next.js version: 12.1.6 next-transpile-modules version: 9.0.0 Node.js version: 16.13.2 npm/yarn version: npm 8.1.2 Operating System: MacOS Monterey 12.4 Webpack 4 or 5: 5

I have the same a related issue with an NPM package that is being transpiled and referencing a relative path in it's index.ts file:

/** @type {import('next').NextConfig} */
const withTM = require('next-transpile-modules')([
  '@scoped/package-name',
], {
  debug: true,
});

module.exports = withTM({
  reactStrictMode: true,
});
error - ./node_modules/@scoped/package-name/src/index.ts:1:0
Module not found: Can't resolve './subfolder/file'

Where './subfolder/file' is relative to the index.ts in the module being transpiled

Any suggestions would be greatly appreciated.

janvennemann commented 2 years ago

This is a webpack issue and can be fixed by updating the config. See this comment for more details.

const {
  withBlitz
} = require("@blitzjs/next")
const withTM = require('next-transpile-modules')(['my-package-1', 'my-package-2'])

module.exports = withTM(withBlitz({
  webpack: (config) => {
    config.resolve = {
      ...config.resolve,
      extensionAlias: {
        ...config.resolve.extensionAlias,
        '.js': ['.ts', '.js'],
        '.mjs': ['.mts', '.mjs'],
      },
    }
    return config
  }
}))