Microbundle: Tree-shaking not working

Created on 27 Jul 2020  路  4Comments  路  Source: developit/microbundle

layout-ui is bundled using mircobundle and produces cjs/esm/umd bundles.

While using any of named export from layout-ui, the final application bundle contains whole esm bundle from layout-ui.
e.g

import React from "react";
import { Stack } from "layout-ui";

export default function App() {
  return (
      <Stack gap="2rem" align="center">
        <div>Item 1</div>
        <div>Item 2</div>
      </Stack>
  );
}

In above example, ideally it should only bundle code for Stack.

question

Most helpful comment

That's because it's not possible for current bundlers/minifiers to detect if styled() has side-effects or not. To ensure that those are tree-shaken they need to be prepended with a hint that they are in fact pure. This can be done by adding /* #__PURE__ */ as a comment just before the function call.

const Foo = /* #__PURE__ */ styled("div")`
  color: red;
`

For a babel plugin that does inserts these comments check out:

All 4 comments

That's because it's not possible for current bundlers/minifiers to detect if styled() has side-effects or not. To ensure that those are tree-shaken they need to be prepended with a hint that they are in fact pure. This can be done by adding /* #__PURE__ */ as a comment just before the function call.

const Foo = /* #__PURE__ */ styled("div")`
  color: red;
`

For a babel plugin that does inserts these comments check out:

just trying to understand it in detail.
For example

// library.js
function useMyHook(){...} // current bundlers/minifiers don't know whether useMyHook is pure or not 
export function ComponentWithHook(){ 
 const [a,b] = useMyHook();
 // do something with a & b
...
}
export function IAmPure(){...}

```js
// app1.js
import {ComponentWithHook} from 'library';
render()

```js
// app2.js
import {IAmPure} from 'library';
render(<IAmPure/>)

In above case

  • [ ] App1 will bundle whole library
  • [ ] App1 will bundle ComponentWithHook & useMyHook
  • [ ] App2 will bundle only IAmPure
  • [ ] App2 will bundle IAmPure & useMyHook
  • [ ] App2 will bundle whole library

@marvinhagemeister ^ which option(s) is correct ? 馃檪

@kuldeepkeshwar Maybe just try it out?

The top level exports aren't the only requirement for tree-shaking. Tree-shaking is a subclass of dead code elimination (=DCE) and it's only possible to remove something when the minifier/bundler is 100% certain that removing it won't alter the program. For todays bundlers this usually translates to checking if the code in question has no side-effects. If the body of a function can't be proven to be pure and is used somewhere, it won't be removed.

FYI: microbundle is mainly an opinionated wrapper around rollup. It tree shakes the same code as rollup does and any issues should be filed there 馃憤

Was this page helpful?
0 / 5 - 0 ratings

Related issues

belozer picture belozer  路  3Comments

cowboyd picture cowboyd  路  3Comments

manferlo81 picture manferlo81  路  5Comments

sptimer picture sptimer  路  4Comments

dmitrykurmanov picture dmitrykurmanov  路  3Comments