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

Webpack build failing with latest version of Next (12.1.6) #263

Closed thomas-short closed 2 years ago

thomas-short commented 2 years ago

Are you trying to transpile a local package or an npm package? Private NPM package. It's an FE library using ESM.

Describe the bug After running build command: NEXT_TELEMETRY_DISABLED=1 next build && tsc --project tsconfig.server.json

The build fails with a webpack error, which is huge unfortunately, and makes it hard to read logs that come from next-transpile-modules debug, but didn't notice any issues in the logs for next-transpile-modules.

The webpack error is as follows: (logs all 28k lines 😢 )

 28116 | }());
 28117 |
 28118 | /* exported ProjectInterface */
 28119 |
 28120 | var ProjectInterface = (function () {
       :     ^^^^^^^^|^^^^^^^
       :             `-- `ProjectInterface` redefined here
       `----

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

To Reproduce Hard to provide this as npm package is private but happy to provide any info about it that might help figure out the issue

Expected behavior Something changed between version 12.1.0 and 12.1.6 to cause the issue. Will try to sift through the changelog to see if there are any clues there.

Setup

Rollup config for FE npm package:

{
        input: 'src/index.ts',
        output: [
            { dir: 'dist', format: 'esm', sourcemap: true, exports: 'named', preserveModules: true },
            { file: pkg.main, format: 'cjs', sourcemap: true, exports: 'named' },
        ],
        external: ['react', 'react-dom'],
        plugins: [
            del({ targets: 'dist/index_temp.js' }),
            resolve({
                browser: true,
                main: true,
                extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
            }),
            postcss({
                extensions: ['.css', '.postcss'],
                extract: path.resolve('dist/index.css'),
                config: { path: path.resolve('./postcss/postcss.config.js') },
            }),
            json(),
            typescript(),
            cjs(),
            svgr({ svgo: false }),
        ],
    },

package.json for FE npm package contains:

"type": "module",
 "sideEffects": false,

next.config.js webpack configuration:

webpack(config, options) {
                // allow importing images from public
                config.resolve.alias = {
                    ...config.resolve.alias,
                    public: path.join(process.cwd(), 'public'),
                };

                if (dynamicAssetPrefix) {
                    config.module.rules.push({
                        test: /\.(jpe?g|png|gif|ico|webp|svg)$/,
                        use: [
                            {
                                loader: 'file-loader',
                                options: {
                                    // make sure imported images end up in next output folder
                                    outputPath: `${options.isServer ? '../' : ''}static/images/`,
                                    publicPath: `${options.isServer ? '_next/' : ''}static/images/`,
                                    name: '[name]-[hash].[ext]',
                                    postTransformPublicPath: (publicPath) =>
                                        options.isServer
                                            ? `(process.env.${assetUrlEnvKey}) + ${`/${assetPathPrefix}/`} + ${publicPath}`
                                            : `__webpack_public_path__ + ${publicPath}`,
                                },
                            },
                        ],
                    });

                    config.module.rules.push({
                        test: /\.(woff|woff2)$/,
                        use: [
                            {
                                loader: 'file-loader',
                                options: {
                                    // make sure imported images end up in next output folder
                                    outputPath: `${options.isServer ? '../' : ''}static/fonts/`,
                                    publicPath: `${options.isServer ? '_next/' : ''}static/fonts/`,
                                    name: '[name].[ext]',
                                    postTransformPublicPath: (publicPath) =>
                                        options.isServer
                                            ? `(process.env.${assetUrlEnvKey}) + ${`/${assetPathPrefix}/`} + ${publicPath}`
                                            : `__webpack_public_path__ + ${publicPath}`,
                                },
                            },
                        ],
                    });
                }

                if (typeof nextConfig.webpack === 'function') {
                    return nextConfig.webpack(config, options);
                }

                return config;
            },

Additional context I cannot say for sure the issue is with next-transpile-modules

What I did was simplify our project down to a very simple form and I narrowed the cause to when we import a npm package that uses ESM.

So it's clear when I just import from this package:

import { someComponent } from 'external-fe-library';

Then webpack build breaks with the error I previously linked. This is a npm package that we transpile using this package:

withTM(['external-fe-library']).

If I remove it from withTM then the build fails with error "ReferenceError: exports is not defined in ES module scope", which is what this package helped to solve in the first place.

The build seems to be ok with other NPM packages that we transpile, so it might be some edge case with this particular package that we are using.

Happy to provide any more info if I can.

martpie commented 2 years ago

Can you provide the full ntm debug log? From next dev/build to the crash?

thomas-short commented 2 years ago

Seems nothing too interesting. Just a lot of logs for each file it transpiles.

info  - Creating an optimized production build .next-transpile-modules - transpiled: /git/project/node_modules/@Privatepackage/translator-client/index.js
next-transpile-modules - transpiled: /git/project/node_modules/@Privatepackage/public-web-common/dist/translator/index.js
next-transpile-modules - transpiled: /git/project/node_modules/@Privatepackage/public-web-common/dist/translator/index.js
next-transpile-modules - transpiled: /git/project/node_modules/@Privatepackage/puco-react/dist/src/index.js
...
...
info  - Creating an optimized production build ..next-transpile-modules - transpiled: /git/project/node_modules/@Privatepackage/public-web-common/dist/_virtual/_commonjsHelpers.js
next-transpile-modules - transpiled: /git/project/node_modules/@Privatepackage/puco-react/dist/index.js
next-transpile-modules - transpiled: /git/project/node_modules/@Privatepackage/public-web-common/dist/translator/index.js
info  - Creating an optimized production build

Right after this point is the webpack error

thomas-short commented 2 years ago

I tried by just bumping one version of next so from 12.1.0 to 12.1.1 and got the error.

./node_modules/@Privatepackage/puco-react/dist/index.js
Error: error: the name `ProjectInterface` is defined multiple times

      |
12757 | function ProjectInterface() { return {}; }
      |          ---------------- previous definition of `ProjectInterface` here
...
28120 | var ProjectInterface = (function () {
      |     ^^^^^^^^^^^^^^^^ `ProjectInterface` redefined here

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

And just before that point logs from ntm show no issue:

...
info  - Creating an optimized production build .next-transpile-modules - transpiled: /node_modules/@Privatepackage/puco-react/dist/index.js
next-transpile-modules - transpiled: /node_modules/@Privatepackage/public-web-common/dist/translator/index.js
info  - Creating an optimized production build
thomas-short commented 2 years ago

hmm when I check the file directly: ./node_modules/@Privatepackage/puco-react/dist/index.js

I do see it has:

12757 function ProjectInterface() { return {}; }
...
28120 var ProjectInterface = (function () {

So problem is already there before it gets transpiled by your package 🤔 I manually removed one of the declarations and now the build works 😵 So indeed not an issue with your package and we can close this issue. But very odd it worked fine with previous version of Next...

I will have to figure out why rollup declares the same function twice.

martpie commented 2 years ago

Seems nothing too interesting. Just a lot of logs for each file it transpiles.

please can you include the full log? It's really important, especially the beginning. Feel free to hide the secret bits, but I really need the full terminal log 😅