Reduce bundle size and tree shaking

Apr-12, 2025 ยท 2min

change language

Learn how to reduce bundle size through tree shaking technology, including the optimized import method of the motion library and the module export strategy

motion

https://m.dev/docs/react-reduce-bundle-size#reduce-size

In the motion library, to reduce the bundle size, you need to use

import * as m from 'motion/react-m'

to import the components of motion, so that there is tree shaking when bundling.

Explanation

foo.ts
function add(a: number, b: number) {
  return a + b
}

function sub(a: number, b: number) {
  return a - b
}

console.log('11111111')
const module = {
  add,
  sub,
}

export default module
index.ts
import foo from './foo'

console.log(foo.add(1, 2))

The final bundled product, it can be seen that even if the sub function is not used, it will be packaged in.

index.js
// src/foo.ts
function add(a, b) {
  return a + b
}
function sub(a, b) {
  return a - b
}
console.log('11111111')
var module = {
  add,
  sub,
}
var foo_default = module

// src/index.ts
console.log(foo_default.add(1, 2))
//# sourceMappingURL=index.js.map

Using * as to import modules

bar.ts
export function add(a: number, b: number) {
  return a + b
}

console.log('111111')
export function sub(a: number, b: number) {
  return a - b
}
index.ts
import * as bar from './bar'

console.log(bar.add(1, 2))

The final bundled product

index.js
// src/bar.ts
function add(a, b) {
  return a + b
}
console.log('111111')

// src/index.ts
console.log(add(1, 2))
//# sourceMappingURL=index.js.map

It can be seen that using * as to import modules has tree shaking when bundling, and it can also identify that console.log is a side effect.

Use unplugin-auto-import to simplify the writing

To avoid the problem of * as m not being able to be automatically imported, you can use unplugin-auto-import to simplify the writing.

This is a nextjs configuration

next.config.ts
const nextConfig: NextConfig = {
  output: 'export',
  experimental: {
    reactCompiler: true,
  },
  webpack: (config) => {
    config.plugins.push(
      AutoImport({
        include: [
          /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
        ],
        imports: [
          'react',
          {
            // Automatically import the components of motion, and can tree shaking
            from: 'motion/react-m',
            imports: [['*', 'motion']],
          },
        ],
        dts: true,
      }),
    )

    return config
  },
}
auto-import.d.ts
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
  const motion: typeof import('motion/react-m')
}