Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nextjs 13.4.13 is not transpiling code to browser old versions even with browserslist option in package.json #53821

Open
1 task done
yanv1991 opened this issue Aug 9, 2023 · 20 comments
Labels
bug Issue was opened via the bug report template.

Comments

@yanv1991
Copy link

yanv1991 commented Aug 9, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: x64
      Version: Darwin Kernel Version 20.6.0: Thu Mar  9 20:39:26 PST 2023; root:xnu-7195.141.49.700.6~1/RELEASE_X86_64
    Binaries:
      Node: 16.14.2
      npm: 8.5.0
      Yarn: 1.22.19
      pnpm: N/A
    Relevant Packages:
      next: 13.4.14-canary.1
      eslint-config-next: 13.4.13
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.1.6
    Next.js Config:
      output: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

No response

Link to the code that reproduces this issue or a replay of the bug

https://github.com/yanv1991/test-2017

To Reproduce

run yarn build and then yarn start

note: webpack custom config was added to disable minimizer

look for the .next folder inside the main-xxxxx file you will see non es5 syntax like:

image (1)

Describe the Bug

when adding browserslist option in package.json with a value like this: >0.3%, defaults, supports es5 the next bundle is still generating modern syntax.

Expected Behavior

if browserslist with es5 target is configured the bundle should not generate modern syntax like let, const....

Which browser are you using? (if relevant)

Chrome 48.0.2527.0

How are you deploying your application? (if relevant)

local

@yanv1991 yanv1991 added the bug Issue was opened via the bug report template. label Aug 9, 2023
@EloB
Copy link

EloB commented Aug 10, 2023

I've tried older versions and seems like it doesn't work there either.

EDIT: I think this works it's just that node_modules/ packages doesn't get transpiled. You manually need to add them to transpilePackages. I got this working with both Babel and SWC.

Try using this to figure out which dependency/package or sub dependency contains the new syntax and att that to the list.

module.exports = {
  webpack: (config) => {
    config.optimization.minimize = false;
    return config;
  },
}

A feature request would be if Next.js could validate if out/ folder contains unsupported code and make a big warning about it in the build step.

@EloB
Copy link

EloB commented Aug 10, 2023

My problem was transpilePackages. I had some packages in node_modules/ that wasn't transpiled that I had to include in the array. So maybe not related. I had to use .babelrc because SWC didn't transpile to old syntax.

https://nextjs.org/docs/app/api-reference/next-config-js/transpilePackages

next.config.js

module.expoorts = {
  // ...
  transpilePackages: [
    'react-hook-form',
  ]
}

.babelrc

{
  "presets": ["next/babel"],
  "plugins": []
}

@yanv1991
Copy link
Author

@EloB yes the repo that I posted here is a app generated using the next-create-app CLI, without any dependency and the error looks like is inside nextjs core

@EloB
Copy link

EloB commented Aug 10, 2023

@yanv1991 Have you tried babel? It might be a SWC issue.

@yanv1991
Copy link
Author

yes actually the repo uses babel.config

@yanv1991
Copy link
Author

hey @EloB I tried adding next in the transpile packages option and it worked, however not sure if this is a clean solution 🤔 https://github.com/yanv1991/test-2017/blob/32bb16a17fff9e12b488b33dbad48b18a9bf0f88/next.config.js#L13

@EloB
Copy link

EloB commented Aug 11, 2023

@yanv1991 Does next contain new syntax? :)

@EloB
Copy link

EloB commented Aug 11, 2023

Have you tried if this works with SWC? I really don't want to use babel.

@yanv1991
Copy link
Author

yanv1991 commented Aug 11, 2023

@yanv1991 Does next contain new syntax? :)

yes, take a look to the error, this is running in chromium 48:
image (1)

@yanv1991
Copy link
Author

yanv1991 commented Aug 11, 2023

Have you tried if this works with SWC? I really don't want to use babel.

it worked even with swc, as long as I keep next in the transpilePackage

@woshiqiang1
Copy link

This bug sames occur after v13.2.0, use v13.2.0 the main-**.js is ok, but when you import third part package in the project the file in dist chunks folder still have es6 syntax even you config browserslist.

@yanv1991
Copy link
Author

@woshiqiang1 for 3rd parties you need transpilePackages option

@woshiqiang1
Copy link

@yanv1991 I add the package in transpilePackages option, but the dist chunks folder still have es6 syntax
image

@EloB
Copy link

EloB commented Aug 16, 2023

@woshiqiang1 The easiest way to find with package it was is:
next.config.js

module.exports = {
  webpack: (config) => {
    config.optimization.minimize = false;
    return config;
  },
}

Sometimes it might be a sub dependency of a dependency. When you do like that you still have the comments left with package names and discovered that sub packages contained ES6 code. Than I just added them too.

I got this working for both babel and swc. Don't forget to set the browserslist in package.json.

@woshiqiang1
Copy link

@EloB Thanks I try the way you said above and it works !! but it's really not a very elegant and convenient way hope Next.js optimize this DX someday.

@longzheng
Copy link
Contributor

I also ran into issues after upgrading to Next 13.5.2, the build would generate non-ES5 syntax (that I check with the es-check package es-check es5 '.next/static/chunks/main-*.js')

I also found that the output chunk contained some Next.js router code that had let.

I also fixed it by adding next to my transpilePackages config.

/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['next'],
}
 
module.exports = nextConfig

@egemon
Copy link

egemon commented Nov 27, 2023

13.5.6 same issue. Adding next breaks the build

/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['next'],
}
 
module.exports = nextConfig

Error tail

> next build

error - No Sentry auth token configured. Source maps will not be uploaded.
You can find information on how to generate a Sentry auth token here: https://docs.sentry.io/api/auth/
After generating a Sentry auth token, set it via the SENTRY_AUTH_TOKEN environment variable during the build.

Failed to compile.

./node_modules/swr/_internal/dist/index.mjs
Attempted import error: 'useEffect' is not exported from 'react' (imported as 'useEffect').

Import trace for requested module:
./node_modules/swr/_internal/dist/index.mjs
./node_modules/swr/core/dist/index.mjs

@tua-Mascot
Copy link

I conducted an experiment on a pure next.js project with these basic settings.
Windows 10
Node.js v20.9.0
Code_bDSpNZEJ3T

It seems that the settings for browserslist inside package.json have no effect on the size of the bundle and have a very strange effect on the size of the .next folder.

clean project (npx create-next-app@latest)

Route (app)                              Size     First Load JS
┌ ○ /                                    5.12 kB        89.3 kB
└ ○ /_not-found                          885 B            85 kB
+ First Load JS shared by all            84.2 kB
  ├ chunks/69-1b6d135f94ac0e36.js        28.9 kB
  ├ chunks/fd9d1056-cc48c28d170fddc2.js  53.4 kB
  └ other shared chunks (total)          1.86 kB

.next folder size - 32.4 MB (33,984,512 bytes)

"browserslist": ["last 2 Chrome versions"] (package.json)

Route (app)                              Size     First Load JS
┌ ○ /                                    5.12 kB        89.3 kB
└ ○ /_not-found                          885 B            85 kB
+ First Load JS shared by all            84.2 kB
  ├ chunks/69-1b6d135f94ac0e36.js        28.9 kB
  ├ chunks/fd9d1056-cc48c28d170fddc2.js  53.4 kB
  └ other shared chunks (total)          1.86 kB

.next folder size - 31.4 MB (32,952,320 bytes)

"browserslist": ["last 2 Chrome versions"] (package.json) + transpilePackages: ['react', 'react-dom', 'next'] (next.config.mjs)

Route (app)                              Size     First Load JS
┌ ○ /                                    5.12 kB        89.3 kB
└ ○ /_not-found                          885 B            85 kB
+ First Load JS shared by all            84.2 kB
  ├ chunks/69-1b6d135f94ac0e36.js        28.9 kB
  ├ chunks/fd9d1056-cc48c28d170fddc2.js  53.4 kB
  └ other shared chunks (total)          1.86 kB

.next folder size - 33.0 MB (34,631,680 bytes)

Can one of the developers look at this problem (possibly - @timneutkens @Timer @leerob)?
Looks like a serious bug (but maybe I just don’t fully understand how it should work 😅).

@tua-Mascot
Copy link

I also noticed an extremely strange effect.
If I remove browserslist from package.json (I think that the default settings specified in the documentation should be used), then in the chunk file ".next\static\chunks\app_not-found-[hash].js" in default next.js 14 project I see let variables. If I add browserslist with “last 2 Chrome versions”, then in the same chunk I see var variables 👀.
In general, there is a feeling that no matter what target you set in browserslist and no matter what experimental settings you use (for example, from this issue - #12557), the size of the client bundle does not change in any way (no difference is observed in either the CLI report after the 'build' command or in the 'next/bundle-analyzer' report. sometimes by 1-2 kb, but even then rarely).
It's quite a frustrating experience. I don't want to sound rude (and I apologize if it sounds like that), but I see only 2 possible options here:

  1. I don’t understand how this should work in complex systems like Next.js
  2. We really have a problem with the target for the final bundle and tree-shaking, and judging by the number of issues and comments inside - this is a long-standing problem that for some reason is not being solved or does not receive enough attention from Next.js team.

@jim-king-2000
Copy link

I tried adding next to my transpilePackages config.

/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['next'],
}
 
module.exports = nextConfig

But there are still private properties in my js. Is it possible to transpile private properties?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

No branches or pull requests

7 participants