vercel / next.js

The React Framework
https://nextjs.org
MIT License
127.02k stars 26.99k forks source link

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

Open yanv1991 opened 1 year ago

yanv1991 commented 1 year ago

Verify 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

EloB commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

@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 commented 1 year ago

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

yanv1991 commented 1 year ago

yes actually the repo uses babel.config

yanv1991 commented 1 year ago

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 commented 1 year ago

@yanv1991 Does next contain new syntax? :)

EloB commented 1 year ago

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

yanv1991 commented 1 year ago

@yanv1991 Does next contain new syntax? :)

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

yanv1991 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

@woshiqiang1 for 3rd parties you need transpilePackages option

woshiqiang1 commented 1 year ago

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

EloB commented 1 year ago

@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 commented 1 year ago

@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 commented 1 year ago

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 commented 11 months ago

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 commented 9 months ago

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 commented 9 months ago

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 - https://github.com/vercel/next.js/issues/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.