背景
背景:当我们同时引入一个包中的两个方法,有两种方式
第一种形式:
import {flatten,join} from 'lodash';
第二种形式:
import flatten from 'lodash/flatten'
import join from 'lodash/join'
第一种方式的引入会把整个loadsh包都引进来,打包后的文件大小为550kb;
第二种方法是只会引入包中的这两个方法,打包后的文件大小为21kb。
显然我们要用第二种
但是一般的项目中,大部分都是以import结构的形式,所以这里我们就写一个插件,当我们写成第一种形式引入的时候,利用插件转化成第二种形式
插件实现
下面是插件的实现:
- 新建文件夹babel-plugin-demand-loading
- 执行npm init -y
- 安装babel-core、babel-types
- 根目录下新建index.js,并编写代码,如下:
const babel = require('babel-core')
const types = require('babel-types')
module.exports = {
visitor: {
// 这里的ref是ImportDeclaration的第二个参数,这里的值是.babelrc中的 {
// "library": "lodash" //}, 这里是指定 我们在引用哪个库的时候使用这个插件
ImportDeclaration(path, ref={}){
let {opts} = ref
let node = path.node
let specifiers = node.specifiers
if(opts.library === node.source.value && !types.isImportDeclaration(specifiers[0])){
const newImport = specifiers.map((specifier) => (
types.importDeclaration([types.importDefaultSpecifier(specifier.local)], types.stringLiteral(`${node.source.value}/${specifier.local.name}`))
))
path.replaceWithMultiple(newImport)
}
}
}
}
- yalc publish本地发布包
- 在项目中使用命令
yalc add babel-plugin-demand-loading@1.0.0 -D安装该插件 - 在webpack.config.js文件中配置该插件
const PluginDemandLoading = require('babel-plugin-demand-loading')
module : {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|browser_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: [
[PluginDemandLoading,{
'library': 'lodash', // 指定哪些库使用这个插件
}]
]
}
}
},
]
}
使用该babel插件后,打包后的文件大小为19kb.
import {flatten, join} from 'lodash'
const arr = [1,2,['3','4',6,7]]
console.log(flatten(arr)) // [ 1, 2, '3', '4', 6, 7 ]
console.log(join(flatten(arr))) //1,2,3,4,6,7
AST Explorer
babel插件注意事项
- babel插件的文件夹命名,必须以babel-plugin-xxx(你写的插件名)命名,否则引入不成功。
- babel插件返回的是一个对象,里面有一个访问者模式的visitor对象,里面是我们的转化代码