Skip to content

Latest commit

 

History

History
60 lines (55 loc) · 3.04 KB

using-scene.md

File metadata and controls

60 lines (55 loc) · 3.04 KB

cbml-processor使用场景

实现ui库按需加载插件babel-plugin-import的替换

ui库的按需加载大多的两种思路

  • 尽可能利用ES module的import静态分析,使用构建工具的tree shaking。但是无论rollup还是webpack都无法做到完全的tree shaking,这主要是因为代码存在副作用(side effect)。
  • 所以为了实现ui库的按需加载,很多库开发者选择了第二种思路,将单个组件抽离到单个js/css内,回到了jQuery年代。但是为了让使用者通过import语法来导入,Antd开发了babel-plugin-import插件

babel-plugin-import插件原理

  1. 当使用者编写以下代码,并且配置好babel.config.js
import { Table, Toast } from 'antd'
  1. webpack/rollup通过babel转译后拿到的代码
const Table = require('antd/es/table/index.js').default
require('antd/es/table/style/index.js') // 自动引入style的css文件

const Toast = require('antd/es/toast/index.js').default
require('antd/es/toast/style/index.js') // 自动引入style的css文件

可以看到插件是改写了js AST节点,并交给babel来生成代码

使用cbml-processor的插件替换

  1. 编写插件,自定义一个es-import注释标签,定义import的attribute,作为组件文件名,定义from的attribute,作为ui库包名
  2. 编写代码如下
/*<es-import import='Table, Toast' from='antd' />*/
  1. 通过cbml-processor转译后拿到的代码
const Table = require('antd/es/table/index.js').default
require('antd/es/table/style/index.js') // 自动引入style的css文件

const Toast = require('antd/es/toast/index.js').default
require('antd/es/toast/style/index.js') // 自动引入style的css文件

补充说明:虽然cbml-processor可以实现此效果,但从源码的语义可读性来讲,还是建议使用babel。

动态增删修改注释块

  1. 如果项目里需要某些代码在打包后不存在,使用babel来操作AST会非常麻烦,因为js的AST过于复杂
  2. 使用webpack/rollup的全局替换,比如vue-cli3的环境参数,虽然可以做到不同环境打包后代码动态运行,但是生成的代码始终存在,会被浏览器解释
const shouldUseVConsole = process.env.shouldUseVConsole
// 如果配置为false,虽然不会初始化vConsole,但是生成的代码会包含,并且if语句会被浏览器解释执行
if (shouldUseVConsole) {
  const VConsole = require('vConsole')
  new VConsole()
}
  1. 编写cbml-processor插件,自定义一个visible注释标签,定义lib的attribute,作为包,定义pin的attribute,作为头部注释内容
  2. 编写代码如下
/*<visible lib='VConsole' pin='初始化VConsole'>*/
const vConsole = new VConsole()
/*</visible>*/
  1. 通过cbml-processor转译后拿到的代码,可以通过lib来过滤是否需要展示代码块
// 初始化VConsole
const vConsole = new VConsole()