|
| 1 | +## cbml-processor使用场景 |
| 2 | + |
| 3 | +### 实现ui库按需加载插件`babel-plugin-import`的替换 |
| 4 | +#### ui库的按需加载大多的两种思路 |
| 5 | +* 尽可能利用ES module的import静态分析,使用构建工具的tree shaking。但是无论rollup还是webpack都无法做到完全的tree shaking,这主要是因为代码存在副作用(side effect)。 |
| 6 | +* 所以为了实现ui库的按需加载,很多库开发者选择了第二种思路,将单个组件抽离到单个js/css内,回到了jQuery年代。但是为了让使用者通过`import`语法来导入,Antd开发了`babel-plugin-import`插件 |
| 7 | +#### `babel-plugin-import`插件原理 |
| 8 | +1. 当使用者编写以下代码,并且配置好`babel.config.js` |
| 9 | + ```js |
| 10 | + import { Table, Toast } from 'antd' |
| 11 | + ``` |
| 12 | +2. webpack/rollup通过babel转译后拿到的代码 |
| 13 | + ```js |
| 14 | + const Table = require('antd/es/table/index.js').default |
| 15 | + require('antd/es/table/style/index.js') // 自动引入style的css文件 |
| 16 | + |
| 17 | + const Toast = require('antd/es/toast/index.js').default |
| 18 | + require('antd/es/toast/style/index.js') // 自动引入style的css文件 |
| 19 | + ``` |
| 20 | +可以看到插件是改写了js AST节点,并交给babel来生成代码 |
| 21 | +#### 使用`cbml-processor`的插件替换 |
| 22 | +1. 编写插件,自定义一个`es-import`注释标签,定义`import`的attribute,作为组件文件名,定义`from`的attribute,作为ui库包名 |
| 23 | +2. 编写代码如下 |
| 24 | + ```js |
| 25 | + /*<es-import import='Table, Toast' from='antd' />*/ |
| 26 | + ``` |
| 27 | +3. 通过`cbml-processor`转译后拿到的代码 |
| 28 | + ```js |
| 29 | + const Table = require('antd/es/table/index.js').default |
| 30 | + require('antd/es/table/style/index.js') // 自动引入style的css文件 |
| 31 | + |
| 32 | + const Toast = require('antd/es/toast/index.js').default |
| 33 | + require('antd/es/toast/style/index.js') // 自动引入style的css文件 |
| 34 | + ``` |
| 35 | + |
| 36 | +> 补充说明:虽然cbml-processor可以实现此效果,但从源码的语义可读性来讲,还是建议使用babel。 |
| 37 | +
|
| 38 | +### 动态增删修改注释块 |
| 39 | +1. 如果项目里需要某些代码在打包后不存在,使用babel来操作AST会非常麻烦,因为js的AST过于复杂 |
| 40 | +2. 使用webpack/rollup的全局替换,比如vue-cli3的环境参数,虽然可以做到不同环境打包后代码动态运行,但是生成的代码始终存在,会被浏览器解释 |
| 41 | + ```js |
| 42 | + const shouldUseVConsole = process.env.shouldUseVConsole |
| 43 | + // 如果配置为false,虽然不会初始化vConsole,但是生成的代码会包含,并且if语句会被浏览器解释执行 |
| 44 | + if (shouldUseVConsole) { |
| 45 | + const VConsole = require('vConsole') |
| 46 | + new VConsole() |
| 47 | + } |
| 48 | + ``` |
| 49 | +3. 编写`cbml-processor`插件,自定义一个`visible`注释标签,定义`lib`的attribute,作为包,定义`pin`的attribute,作为头部注释内容 |
| 50 | +2. 编写代码如下 |
| 51 | + ```js |
| 52 | + /*<visible lib='VConsole' pin='初始化VConsole'>*/ |
| 53 | + const vConsole = new VConsole() |
| 54 | + /*</visible>*/ |
| 55 | + ``` |
| 56 | +3. 通过`cbml-processor`转译后拿到的代码,可以通过lib来过滤是否需要展示代码块 |
| 57 | + ```js |
| 58 | + // 初始化VConsole |
| 59 | + const vConsole = new VConsole() |
| 60 | + ``` |
0 commit comments