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

[Vite version 3.0.0-alpha.9]: Treeshaking does not work with libs. #8464

Closed
7 tasks done
zouhangwithsweet opened this issue Jun 4, 2022 · 18 comments · Fixed by #15184
Closed
7 tasks done

[Vite version 3.0.0-alpha.9]: Treeshaking does not work with libs. #8464

zouhangwithsweet opened this issue Jun 4, 2022 · 18 comments · Fixed by #15184
Labels
feat: deps optimizer Esbuild Dependencies Optimization p3-significant High priority enhancement (priority)

Comments

@zouhangwithsweet
Copy link

Describe the bug

[Vite version 3.0.0-alpha.9]: Cannot treeshaking libs.
image

[Vite version 2.9.9]: Its ok.
image

Reproduction

https://stackblitz.com/edit/vitejs-vite-bqjtx1?file=src%2FApp.tsx,vite.config.ts,stats.html

System Info

System:
    OS: macOS 11.6
    CPU: (8) arm64 Apple M1
    Memory: 99.69 MB / 8.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.13.0 - ~/.nvm/versions/node/v16.13.0/bin/node
    Yarn: 1.22.17 - ~/.nvm/versions/node/v16.13.0/bin/yarn
    npm: 8.1.0 - ~/.nvm/versions/node/v16.13.0/bin/npm
  Browsers:
    Chrome: 102.0.5005.61
    Safari: 14.1.2
  npmPackages:
    @vitejs/plugin-legacy: ^1.8.0 => 1.8.2 
    @vitejs/plugin-react: ^1.3.2 => 1.3.2 
    vite: ^3.0.0-alpha.9 => 3.0.0-alpha.9

Used Package Manager

pnpm

Logs

$ pnpm run build

> vite-antd-seed@0.0.0 build /Users/sun/Desktop/work/vite-antd-seed
> vite build

vite v3.0.0-alpha.9 building for production...
✓ 42 modules transformed.
dist/assets/favicon.4b63ffc1.svg        1.49 KiB
dist/index.html                         0.53 KiB
dist/assets/TestComponent.7cc13317.js   0.12 KiB / gzip: 0.13 KiB
dist/assets/index.0d2e4644.js           0.19 KiB / gzip: 0.17 KiB
dist/assets/index.2636713a.js           5.91 KiB / gzip: 2.51 KiB
dist/assets/esm-VW3YJATR.944f0927.js    214.24 KiB / gzip: 64.88 KiB
dist/assets/index.06cb8156.css          530.03 KiB / gzip: 67.17 KiB
dist/assets/vendor.8dd48daa.js          1696.88 KiB / gzip: 538.35 KiB

(!) Some chunks are larger than 500 KiB after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/guide/en/#outputmanualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.

Validations

@zouhangwithsweet zouhangwithsweet changed the title [Vite version 3.0.0-alpha.9]: Cannot treeshaking libs. [Vite version 3.0.0-alpha.9]: Treeshaking does not work with libs. Jun 4, 2022
@bluwy bluwy added this to the 3.0 milestone Jun 11, 2022
@haoqunjiang haoqunjiang added the p3-significant High priority enhancement (priority) label Jun 15, 2022
@lukemovement
Copy link

lukemovement commented Jun 16, 2022

The solution I found to this, prior to Vite Alpha-11 was to provide all files as entry point within build -> rollupOptions -> input as well as correcting import paths manually. At Alpha-11 I had to implement build -> rollupOptions -> output -> manualChunks with the following to resolve this issue.

  • SourceRoot and NodeModulesRoot should be adjusted to point at the base of your source code. In most projects this is the src directory.
  • .ts files are assumed to be entry points
  • SourceRoot directory structure will be copied
import { extname, resolve } from "path";

export class ManualChuncker {
  // Project
  private static readonly SupportedFiles = [
    "ts",
    "vue",
    "scss",
    "scss?inline",
    "js",
    "json",
  ];
  private static readonly SourceRoot = resolve(
    __dirname,
    "..",
    "library",
    "api"
  );
  private static readonly NodeModulesRoot = resolve(
    __dirname,
    "..",
    "node_modules"
  );

  // Generated
  private static readonly AssetDir = "_assets/";
  private static readonly NodeModuleDir = "_external/";
  private static readonly PluginDir = "_plugins/";
  private static readonly VueDir = "_vue/";

  public static resolve(path: string) {
    return new ManualChuncker(path).resolve();
  }

  constructor(public readonly path: string) {}

  public resolve(): string | void {
    return this.moduleName;
  }

  private get moduleName() {
    const CleanPath = this.path.substring(
      0,
      this.path.length - extname(this.path).length
    );
    if (this.isNodeModule) {
      return `${ManualChuncker.NodeModuleDir}${CleanPath.substring(
        ManualChuncker.NodeModulesRoot.length + 1
      )}`;
    }

    if (this.isVue) {
      return `${ManualChuncker.VueDir}${CleanPath.substring(
        ManualChuncker.SourceRoot.length + 1
      )}`;
    }

    if (this.isAsset) {
      return `${ManualChuncker.AssetDir}${CleanPath.substring(
        ManualChuncker.SourceRoot.length + 1
      )}`;
    }

    if (this.isPlugin) {
      return `${ManualChuncker.PluginDir}${this.path}`;
    }

    return CleanPath.substring(ManualChuncker.SourceRoot.length + 1);
  }

  private get isNodeModule() {
    return this.path.startsWith(ManualChuncker.NodeModulesRoot);
  }

  private get isAsset() {
    return (
      this.fileType === "scss" ||
      this.fileType === "json" ||
      this.fileType === "scss?inline"
    );
  }

  private get isVue() {
    return this.path.endsWith(".vue");
  }

  private get isPlugin() {
    return !ManualChuncker.SupportedFiles.map((ext) =>
      this.path.endsWith(`.${ext}`)
    ).includes(true);
  }

  private get fileType():
    | typeof ManualChuncker["SupportedFiles"][number]
    | null {
    const ext = extname(this.path).substring(1);

    if (ManualChuncker.SupportedFiles.includes(ext)) {
      return ext as typeof ManualChuncker["SupportedFiles"][number];
    }

    return null;
  }
}

P.S. yarn publish doesn't seem to like the node_modules folder create (node_modules/vite/deps_build-dist) when you use the dist folder as the root of the package when deploying.

@ckvv
Copy link

ckvv commented Jul 7, 2022

I'm not sure if it's related to this problem. When I run vite build for the first time, the packaged files are obviously not as big as those of the second vite build.

I can't reproduce this issue in a newly created project, below are screenshots of two runs
what could be the problem?

  • When the generated .vite folder does not exist under node_module

177530123-3c475208-eed6-407d-8c95-c19fbdd11efd

+ When the generated `.vite` folder exists `under node_module`

177530327-80cc6abe-92ee-4d78-9997-adc0ea3aa563

I suspect it has something to do with the cache. When I set optimizeDeps.force to true, the files output by each build are different but the size is very close

截屏2022-07-07 16 35 03

@consegrado
Copy link

^ I have the same problem

@patak-dev
Copy link
Member

@ckvv @consegrado, would you share a repro as minimal as possible so we can build a bench for these issues. Thanks!

@ckvv
Copy link

ckvv commented Jul 7, 2022

@patak-dev
This is a private project, and when I delete the src directory and add a simple case, the problem is not reproduced

@patak-dev
Copy link
Member

@ckvv
Copy link

ckvv commented Jul 7, 2022

@patak-dev

When I set optimizeDeps.disabled = "build", vite build throws an error
截屏2022-07-07 17 21 20

@patak-dev
Copy link
Member

Have you tried #8965? Please open a new issue with a reproduction if you find a bug when using it

@ckvv
Copy link

ckvv commented Jul 8, 2022

@patak-dev
updated to 3.0.0-beta.8 solved my problem

@patak-dev
Copy link
Member

Thanks for testing @ckvv, we'll review the tree-shaking issues and try to flip the default in v4 to optimize deps again 👍🏼
Let's keep this issue open to track the problem

@zouhangwithsweet
Copy link
Author

zouhangwithsweet commented Jul 8, 2022

image

Woo! Great work of your team.

@patak-dev patak-dev removed this from the 3.0 milestone Jul 12, 2022
@stavalfi
Copy link

tree shaking does not work in 3.0.0-beta.8 and 3.0.0-beta.10

@lrstanley
Copy link

tree shaking does not work in 3.0.0-beta.8 and 3.0.0-beta.10

Have you tried 3.0.0 (non-beta/alpha)? Wasn't previously working for me with the alpha, but works perfectly fine with the major release.

@rainydayDY
Copy link

I tried 3.0.0-beta.8 and 3.0.0-beta.10 and 3.0.0 and 3.0.2,tree shaking does not work

@bluwy bluwy added the feat: deps optimizer Esbuild Dependencies Optimization label Sep 6, 2022
littlebtc added a commit to otohime-site/web that referenced this issue Sep 9, 2022
@jiby-aurum
Copy link
Contributor

@patak-dev I recently hit a similar issue, where I had a third party library which could have been completely tree shaken out but was not. And enabling dep optimiser manually did fix the issue.

It was a bit weird for me, as I expected better tree shaking without dep optimisation, as I believe dep optimisation is done without knowledge of what is actually imported from the lib.

@kresli
Copy link

kresli commented Oct 6, 2022

I'm on vite 3.1.0 and tree shaking not working at all

import { fill } from "lodash";
console.log(fill([], ""));

will includes all the lodash functions

@jiby-aurum
Copy link
Contributor

@kresli please share your configuration, I had to manually enable dependency optimisation to get tree shaking in lib mode

{
  optimizeDeps: {
    disabled: false
  },
  build: {
    commonjsOptions: {
      include: [],
    },
    rollupOptions: {
      treeshake: 'smallest',
    }
  }
}

@o-alexandrov
Copy link

@kresli tree-shaking doesn't work on lodash (it has nothing to do with vite, rollup, or esbuild).
For those who want tree-shaking with lodash, there's lodash-es package.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feat: deps optimizer Esbuild Dependencies Optimization p3-significant High priority enhancement (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.