npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

module-decompose-loader

v1.1.0

Published

decomposing module importing to minimize bundle size in webpack

Downloads

12

Readme

npm node license tests

npm install --save-dev module-decompose-loader

The module-decompose-loader reduces bundle size by decomposing import statements to more specific module imports.

When we have import statement like below:

import { Button, IputItem } from 'antd-mobile';
import { debounce } from 'lodash';

It will convert to below lines:

import Button from 'antd/lib/button';
import 'antd/lib/button/style/css';
import InputItem from 'antd/lib/input-item';
import 'antd/lib/input-item/style/css';
import debounce from 'lodash/debounce'

decomposing es6/typescript module import

antd-mobile-test.js

import { Button, IputItem } from 'antd-mobile';
console.log(Button, InputItem );

lodash-test.js

import { debounce } from 'lodash';
console.log(debounce);

webpack.config.js

module.exports = {
  module: {
    // ...
    rules: [
      {
        enforce: "pre",
        test: /\.(js|ts)$/,
        use: {
          loader: 'module-decompose-loader',
          options: {
            modules: {
              'antd-mobile': {
                components: 'lib',
                style: 'css',
                camel2Dash: true
              },
              lodash: {
                // nothing, but need this empty object literal
              }
            }
          }
        }
      }
    ]
    // ...
  }
}

build result:

> webpack

Hash: 417e4a14fffa92b4e502
Version: webpack 3.8.1
Time: 1435ms
          Asset     Size  Chunks             Chunk Names
 antd-mobile.js   168 kB       0  [emitted]  antd-mobile
      lodash.js  17.8 kB       1  [emitted]  lodash
antd-mobile.css  51.1 kB       0  [emitted]  antd-mobile
  [62] ./antd-mobile-test.js 220 bytes {0} [built]
 [139] ./lodash-test.js 63 bytes {1} [built]
 [143] (webpack)/buildin/global.js 488 bytes {1} [built]
    + 156 hidden modules

compared to(without loader):

> webpack

Hash: c903537458fe95455342
Version: webpack 3.8.1
Time: 2121ms
         Asset     Size  Chunks                    Chunk Names
antd-mobile.js  1.35 MB       0  [emitted]  [big]  antd-mobile
     lodash.js   544 kB       1  [emitted]  [big]  lodash
  [66] (webpack)/buildin/global.js 488 bytes {0} {1} [built]
 [118] ./antd-mobile-test.js 81 bytes {0} [built]
 [349] ./lodash-test.js 57 bytes {1} [built]
 [351] (webpack)/buildin/module.js 495 bytes {1} [built]
    + 348 hidden modules

|Name|Type|Default|Description| |:--:|:--:|:-----:|:----------| |modules|{Object}|undefined| The root configuration object | |modules[moduleName]|{Object}| undefined | Tell which module to enable decomposing | |modules[moduleName].components|{String} | undefined| undefined | Configure the generated import from statement | |modules[moduleName].style |{String | Boolean}|false| Configure whether and how to output css import statement | |modules[moduleName].camel2Dash|{Boolean}|false| Configure whether the path is camel case or dash |

modules

Contains node modules to decompose, if it's not set, warning will be shown and the loader will not take effect.

modules[moduleName]

Every node module to be decomposed should be configured. The object contains configurations for each module, if not set, the module won't get decomposed.

modules[moduleName].components

For import { debounce } from 'lodash', if components set to undefined, the output is import debounce from 'lodash/debounce'; while components set to lv1/lv2, the output is import debounce from 'lodash/lv1/lv2/debounce

The from part generation rule is:

  1. when components is undefined, the result is ${moduleName}/${componentPath}
  2. otherwise the result is ${moduleName}/${componentsDirectory}/${componentPath}

modules[moduleName].style

This option tells whether to generate style import statement and how to. When style is falsy, no style import will be generated, usefull for libraries without UI. When style is String, the value is used to generate the from path. Given import { Button } from 'antd', when style is css/default, generated style statement will be import 'antd/button/style/css/default'.

modules[moduleName].camel2Dash

If the option is true, import { Button } from 'antd' will generate import Button from 'antd/button'; If not, the result will be import Button from 'antd/Button'

import moduleDecomopse from 'module-decompose-loader/lib/module-decompose';

const input = `import { Button } from 'antd'`;

const output = moduleDecompose(input, {
  modules: {
    antd: {
      components: 'es',
      style: 'css',
      camel2Dash: true
    }
  }
});

console.log(output);
> node index.js


import Button from 'antd/es/button';
import 'antd/es/button/style/css';

Why the bundle is still big

Probable causes:

  1. The options is incorrect, which will be reported on console.
  2. The module isn't included in modules configuration. Please add it to loader options.
  3. Used import default. Say import _, { debounce } from 'lodash', in this way, lodash will be fully loaded.