5

I am building a library with vite library mode, the problem is the bundler is not tree shakable.

There are some related topics here, here and maybe here also.

So, anyone has experience with this?

ShinaBR2
  • 2,519
  • 2
  • 14
  • 26

2 Answers2

2

I believe this has to do with the way esbuild bundles under the hood. It's a little different than the way babel has done it with their more established plugin eco-system.

Some of your code that you would expect to the tree-shaken by default might not be marked as /* @__PURE__ */ as you might expect.

The solution that worked for me was:

  1. Mark all functions that are able to be dropped if unused, tree-shaken, with /* @PURE */. (use caution)
// src/icon.tsx

/* @__PURE__ */
export const Icon = React.forwardRef<SVGSVGElement, IconProps>(
  (props, forwardedRef) => (
    <svg {...props} ref={forwardedRef}>
      <path
        d="M14.5"
        fill={props.color}
      />
    </svg>
  ),
)
  1. Preserve modules in your build step:
// vite.config.ts

rollupOptions: {
  output: {
    preserveModules: true,
  },
},
hoop71
  • 21
  • 6
1

I had the same problem building my library with Vite lib mode ..

Either, @hoop71 solution works but you have to mark everything with /* @__PURE__ */ or use rollup-plugin-pure to help with that.

Either, don't use lib mode and use rollup like I did :

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import dts from "vite-plugin-dts";
import pkg from "./package.json";
import { visualizer } from "rollup-plugin-visualizer";

export default defineConfig({
  esbuild: {
    minifyIdentifiers: false,
  },
  build: {
    rollupOptions: {
      preserveEntrySignatures: "strict",
      input: ["src/index.ts", "src/nav/index.ts"],
      external: [...Object.keys(pkg.peerDependencies)],
      output: [
        {
          dir: "dist",
          format: "esm",
          preserveModules: true,
          preserveModulesRoot: "src",
          entryFileNames: ({ name: fileName }) => {
            return `${fileName}.js`;
          },
        },
      ],
    },
  },
  plugins: [
    react({
      jsxRuntime: "classic",
    }),
    visualizer(),
    dts(),
  ],
});

⚠️ jsxRuntime : "classic" is removed from @vitejs/plugin-react@4.0.0... I have not upgrade it to v4 yet and handle automatic runtime. Read more

Clément CREUSAT
  • 301
  • 3
  • 6
  • 13