web-infra-dev / rspack

The fast Rust-based web bundler with webpack-compatible API 🦀️
https://rspack.dev
MIT License
10.04k stars 573 forks source link

[Feature]: better treeshaking when lib conditional judgment e.g: `process.env.NODE_ENV` #8487

Open SoonIter opened 2 days ago

SoonIter commented 2 days ago

System Info

System: OS: macOS 14.6.1 CPU: (10) arm64 Apple M1 Pro Memory: 124.89 MB / 32.00 GB Shell: 5.9 - /bin/zsh Browsers: Chrome: 131.0.6778.70 Chrome Canary: 133.0.6847.0 Safari: 17.6

Details

DCE analysis in one big esm file, compared with rollup

https://github.com/SoonIter/rspack-rollup-treeshake-repro

// node_modules/@aibee/crc-bmap/lib/bmap.esm.js:9565
var isOnline = process.env.CRC_BMAP_MODE === 'online';        // <--- env conditional judgement
var ParkingTypeIconMap3;
if (isOnline) {
  ParkingTypeIconMap3 = (init_online(), __toCommonJS(online_exports))
    .ParkingTypeIconMap;
} else {
  ParkingTypeIconMap3 = (init_offline(), __toCommonJS(offline_exports))
    .ParkingTypeIconMap;
}
// ...
// index.ts
import { BMap } from "@aibee/crc-bmap"

console.log(BMap)
  source: {
    define: {
      'process.env.CRC_BMAP_MODE': JSON.stringify('online'),
    },
  },

Result

rsbuild 3875kb > vite(rollup) 812kb

rsbuild

ready   Built in 0.95 s (web)

  File (web)                                  Size         Gzip
  dist-rsbuild/index.html                     0.31 kB      0.22 kB
  dist-rsbuild/static/js/index.f63e9bd1.js    1.8 kB       0.90 kB
  dist-rsbuild/static/js/698.df5bb1bd.js      3875.7 kB    1683.1 kB

  Total: 3877.8 kB (gzip: 1684.2 kB)

vite(rollup)

vite v4.4.5 building for production...
✓ 1449 modules transformed.
dist/index.html            0.45 kB │ gzip:   0.28 kB
dist/index.js              0.77 kB │ gzip:   0.44 kB
dist/chunks/crc-bmap.js  812.95 kB │ gzip: 220.61 kB
✓ built in 3.79s

Reproduce link

https://github.com/SoonIter/rspack-rollup-treeshake-repro

Reproduce Steps

ni
npx rsbuild build
npx vite build
SoonIter commented 2 days ago

some investigation

https://github.com/SoonIter/rspack-rollup-treeshake-repro/tree/investigation

input

// index.ts
import { Arrow3 } from './a';

console.log(Arrow3);
// a.ts
var isOnline = "online" === "online";
import { qux } from './qux'

function a() {}
function b() {}

var ManGlb3;
if (isOnline) {
  ManGlb3 = a();
} else {
  ManGlb3 = b();
  console.log(qux);
}
var Arrow3;
if (isOnline) {
  Arrow3 = 3;
} else {
  Arrow3 = 4;
  console.log(qux);
}

export { ManGlb3, Arrow3 }
// qux.ts
export const qux = 'QUX';

output

rollup

var Arrow3;
{
  Arrow3 = 3;
}
console.log(Arrow3);

rspack

;// CONCATENATED MODULE: ./src/qux.ts
const qux = 'QUX';

;// CONCATENATED MODULE: ./src/a.ts
var isOnline = "online" === "online";

function a() {}
function b() {}
var ManGlb3;
if (isOnline) {
    ManGlb3 = a();
} else {
    ManGlb3 = b();
    console.log(qux);
}
var Arrow3;
if (isOnline) {
    Arrow3 = 3;
} else {
    Arrow3 = 4;
    console.log(qux);
}

;// CONCATENATED MODULE: ./src/index.ts
console.log(Arrow3);

then, rspack would use terser to DCE, once the concatenatedModule bailouts, the dce effect will be lower than rollup a lot