2

npm包开发 之 按需加载

简介

大家做 npm 包的会发现,如果你的 npm 包中有 n 个方法,而在某个项目中只引用了其中某一个,但是在 webpack 打包中,也会被全部打入,这样就导致文件体积莫名过大,用过 antd 的人就知道,antd 官方专门出了个 babel 插件,针对 antd 按需加载的。

例如:

// Home.jsx
import {Button} from 'antd';

他的 babel 干了些什么呢?

import {Button} from 'antd';
 
import Button from 'antd/Button';
 
const Button = require('antd/Button');

那么,如果我们自己开发插件是不是也可以这么玩呢!

上代码

babel6

const babel = require('babel-core');
const types = require('babel-types');
 
module.exports = {
  visitor: {
    ImportDeclaration(path, ref = {}) {
      let {opts} = ref;
      let node = path.node;
      let specifiers = node.specifiers;
      if (opts.library == node.source.value && !types.isImportDeclaration(specifiers[0])) {
        let newImport = specifiers.map((specifier) => (
          types.importDeclaration([types.ImportDefaultSpecifier(specifier.local)], types.stringLiteral(`${node.source.value}/${specifier.local.name}`))
        ));
        path.replaceWithMultiple(newImport)
      }
    }
  }
};

babel7

const babel = require('@babel/core');
const types = require('@babel/types');
 
module.exports = function (api, options, dirname) {
  return {
    visitor: {
      ImportDeclaration(path, ref = {}) {
        let {opts} = ref;
        let node = path.node;
        let specifiers = node.specifiers;
        if (opts.library == node.source.value && !types.isImportDeclaration(specifiers[0])) {
          let newImport = specifiers.map((specifier) => (
            types.importDeclaration([types.ImportDefaultSpecifier(specifier.local)], types.stringLiteral(`${node.source.value}/${specifier.local.name}`))
          ));
          path.replaceWithMultiple(newImport)
        }
      }
    }
  }
};

.babelrc

"plugins": [
    ["babel-plugin-demand-loading", { "library": "你需要按需加载的包名" }]
]

gitub地址

https://github.com/fish-uncle/babel-plugin-demand-loading


鱼叔子
95 声望0 粉丝