mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-04-19 20:08:05 +00:00
chore: 删除 code-generator / material-parser
This commit is contained in:
parent
d035d7362c
commit
e8b172cc80
@ -1 +0,0 @@
|
|||||||
test-cases/
|
|
||||||
@ -1,441 +0,0 @@
|
|||||||
# Change Log
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
||||||
|
|
||||||
<a name="1.0.22"></a>
|
|
||||||
## [1.0.22](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.21...@ali/lowcode-code-generator@1.0.22) (2020-11-16)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* 🐛 解决出码的 disk publisher 不能正确地创建子目录的问题 ([fb5ba93](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/fb5ba93))
|
|
||||||
* 🐛 解决多行文本在出码的时候生成的字符串是无效代码的问题 ([fa68857](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/fa68857))
|
|
||||||
* 🐛 schema 中没有 state 的定义, 出码后的 Rax/React 组件应有个默认的空的 state ([7e37f8d](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/7e37f8d))
|
|
||||||
* babel build bug & add some comment ([1511e2c](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/1511e2c))
|
|
||||||
* object property name fix logic ([dd69113](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/dd69113))
|
|
||||||
* pure string export in jsx ([1a9e953](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/1a9e953))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="1.0.21"></a>
|
|
||||||
## [1.0.21](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.20...@ali/lowcode-code-generator@1.0.21) (2020-11-10)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.20"></a>
|
|
||||||
## [1.0.20](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.19...@ali/lowcode-code-generator@1.0.20) (2020-11-10)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.19"></a>
|
|
||||||
## [1.0.19](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.18...@ali/lowcode-code-generator@1.0.19) (2020-11-05)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.18"></a>
|
|
||||||
## [1.0.18](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.17...@ali/lowcode-code-generator@1.0.18) (2020-11-05)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.17"></a>
|
|
||||||
## [1.0.17](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.16...@ali/lowcode-code-generator@1.0.17) (2020-11-05)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.16"></a>
|
|
||||||
## [1.0.16](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.15...@ali/lowcode-code-generator@1.0.16) (2020-11-04)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.15"></a>
|
|
||||||
## [1.0.15](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.13...@ali/lowcode-code-generator@1.0.15) (2020-11-04)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.14"></a>
|
|
||||||
## [1.0.14](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.13...@ali/lowcode-code-generator@1.0.14) (2020-11-04)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.13"></a>
|
|
||||||
## [1.0.13](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.12...@ali/lowcode-code-generator@1.0.13) (2020-11-02)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* children 在 schema 和 props 中并存的情况处理 ([7b639eb](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/7b639eb))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="1.0.12"></a>
|
|
||||||
## [1.0.12](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.11...@ali/lowcode-code-generator@1.0.12) (2020-10-20)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.11"></a>
|
|
||||||
## [1.0.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.10...@ali/lowcode-code-generator@1.0.11) (2020-10-19)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.10"></a>
|
|
||||||
## [1.0.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.9...@ali/lowcode-code-generator@1.0.10) (2020-09-29)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.9"></a>
|
|
||||||
## [1.0.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.8...@ali/lowcode-code-generator@1.0.9) (2020-09-28)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.8"></a>
|
|
||||||
## [1.0.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.8-0...@ali/lowcode-code-generator@1.0.8) (2020-09-28)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* 🐛 解决 Rax 出码到小程序的时候 require(xxx) 语句不能被编译的问题 ([332a473](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/332a473))
|
|
||||||
* 🐛 经验证发现小程序里面还是得包上 eval 否则 Rax 框架会误把 context 发送到渲染进程而出错 ([c7a10c0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/c7a10c0))
|
|
||||||
* 🐛 若全量引入 lodash 则在小程序下会跑不通,所以改成引入 lodash/clone ([a1a3b68](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/a1a3b68))
|
|
||||||
* 🐛 小程序里面不支持可选链 "?.", 先直接访问 dataSourceEngine 吧 ([36c486b](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/36c486b))
|
|
||||||
* 🐛 fix typo of dataHandler ([acd1f06](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/acd1f06))
|
|
||||||
* 🐛 Rax 出码到小程序, 事件处理函数绑定 JSExpression 时也不应该包裹一个 eval, 小程序会报错 ([9f129aa](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/9f129aa))
|
|
||||||
* 🐛 Result use types package ([dd97a0c](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/dd97a0c))
|
|
||||||
* 🐛 use lowcode types ([b11425b](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b11425b))
|
|
||||||
* enhance api design ([95d67c1](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/95d67c1))
|
|
||||||
* fix test result ([7f6fbe8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/7f6fbe8))
|
|
||||||
* ignore eslintrc in test-case ([c0ef4bc](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/c0ef4bc))
|
|
||||||
* merge problems & deps bugs ([7a36eab](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/7a36eab))
|
|
||||||
* miniAppBuildType config(temp) ([584b4c2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/584b4c2))
|
|
||||||
* miss scope ([97242c3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/97242c3))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* 🎸 按 826 对齐结论调整出码和数据源引擎 ([b9a562e](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b9a562e))
|
|
||||||
* 🎸 补充对数据源的一些处理 ([4572b53](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/4572b53))
|
|
||||||
* 🎸 补充一个默认的数据源的构建后的样子 ([78f34ab](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/78f34ab))
|
|
||||||
* 🎸 出码模块的 DiskPublisher 改成支持传入自定义 FS ([46c896e](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/46c896e))
|
|
||||||
* 🎸 出码模块的 schema 相关的类型统一都改成引用 [@ali](https://gitlab.alibaba-inc.com/ali)/lowcode-types 中的,与设计器一致 ([27a9800](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/27a9800))
|
|
||||||
* 🎸 导出 Rax 的 solutions 的定义 ([27f0e13](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/27f0e13))
|
|
||||||
* 🎸 搞定 Rax 出码的时候的 package.json 中的 dependencies ([eba172c](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/eba172c))
|
|
||||||
* 🎸 还原出码模块的 solutions 的导出 ([c2a7d63](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/c2a7d63))
|
|
||||||
* 🎸 解决通过 Rax 出码到小程序的时候循环里面没法用循环变量的问题 ([779ea7c](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/779ea7c))
|
|
||||||
* 🎸 容器的模块名统一都用 PascalCase, 并为页面添加特定后缀防止与组件名冲突 ([42f7bdb](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/42f7bdb))
|
|
||||||
* 🎸 数据源的类型默认是 fetch ([ec8a191](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/ec8a191))
|
|
||||||
* 🎸 数据源的requestHandlers选项改成requestHandlersMap, 命名更清晰 ([42e41bb](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/42e41bb))
|
|
||||||
* 🎸 添加 didMount 和 willUnmount 两个基本的生命周期 ([e33a95e](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/e33a95e))
|
|
||||||
* 🎸 添加一个判断 ContainerSchema 的 util 方便后续用 ([c3fdfe5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/c3fdfe5))
|
|
||||||
* 🎸 通过 config.miniAppBuildType 来支持 Rax 的 runtime 模式 ([35fcdd9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/35fcdd9))
|
|
||||||
* 🎸 完善 Rax 出码, 补充更复杂的带有数据源绑定/条件/循环以及 Utils 的测试用例并 pass ([adcfacb](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/adcfacb))
|
|
||||||
* 🎸 完善 Rax 出码, 跑通第一个测试用例👏👏👏 ([9f62110](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/9f62110))
|
|
||||||
* 🎸 完善 Rax 出码的时候的全局样式处理 ([058b087](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/058b087))
|
|
||||||
* 🎸 为 Rax 出码增加对 i18n 的支持 ([8d198bd](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/8d198bd))
|
|
||||||
* 🎸 新增 less 文件类型的定义, 以备后续某些 solution 出码用 less 文件作为样式文件 ([cac29d8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/cac29d8))
|
|
||||||
* 🎸 优化 Rax 出码时对绑定的表达式的包裹逻辑, 对于一些简单的安全的表达式不做包裹 ([facfa2a](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/facfa2a))
|
|
||||||
* 🎸 优化 ResultDir 的报错信息, 更方便定位问题 ([965ef4a](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/965ef4a))
|
|
||||||
* 🎸 优化完善 Rax 出码相关的模板和插件 ([c3d909a](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/c3d909a))
|
|
||||||
* 🎸 与国凯的数据源保持一致,将 urlParams 所需的 search 参数直接传入 ([19fabc1](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/19fabc1))
|
|
||||||
* 🎸 与国凯的数据源引擎联调,对齐包名和导出方式 ([fea0946](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/fea0946))
|
|
||||||
* 🎸 支持对 JSON 文件进行 prettier 格式化 ([b7c4854](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b7c4854))
|
|
||||||
* 🎸 add rax code generator solution and test case ([20c0953](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/20c0953))
|
|
||||||
* 🎸 custom 类型的数据源请求不需要 handler ([fa939c4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/fa939c4))
|
|
||||||
* 🎸 globalStyle 支持定制样式文件的后缀名 ([e78dae0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/e78dae0))
|
|
||||||
* 🎸 Rax 出码器支持路由功能 ([8ecc002](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/8ecc002))
|
|
||||||
* 🎸 Rax 出码适配数据源引擎的默认 requestHandlers ([5f529ae](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/5f529ae))
|
|
||||||
* 🎸 Rax 出码支持 constants 常量定义 ([fcf6c32](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/fcf6c32))
|
|
||||||
* 🎸 Rax 出码中添加数据源的 dataHandler 并与数据源引擎的对齐参数 ([42b9db3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/42b9db3))
|
|
||||||
* 🎸 Rax 出码中增加对 urlParams 这种特殊数据源的处理 ([c743afd](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/c743afd))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="1.0.8-0"></a>
|
|
||||||
## [1.0.8-0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.7-0...@ali/lowcode-code-generator@1.0.8-0) (2020-09-09)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.7-0"></a>
|
|
||||||
## [1.0.7-0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.6-0...@ali/lowcode-code-generator@1.0.7-0) (2020-09-02)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.6-0"></a>
|
|
||||||
## [1.0.6-0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.5-0...@ali/lowcode-code-generator@1.0.6-0) (2020-09-02)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.5-0"></a>
|
|
||||||
## [1.0.5-0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.4-0...@ali/lowcode-code-generator@1.0.5-0) (2020-08-20)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.4-0"></a>
|
|
||||||
## [1.0.4-0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.3-0...@ali/lowcode-code-generator@1.0.4-0) (2020-08-20)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.3-0"></a>
|
|
||||||
## [1.0.3-0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.2-0...@ali/lowcode-code-generator@1.0.3-0) (2020-08-20)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.2-0"></a>
|
|
||||||
## [1.0.2-0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.1-0...@ali/lowcode-code-generator@1.0.2-0) (2020-08-20)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.1-0"></a>
|
|
||||||
## [1.0.1-0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@1.0.0...@ali/lowcode-code-generator@1.0.1-0) (2020-08-20)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="1.0.0"></a>
|
|
||||||
# [1.0.0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.13.0...@ali/lowcode-code-generator@1.0.0) (2020-08-17)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="0.13.0"></a>
|
|
||||||
# [0.13.0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.12.0...@ali/lowcode-code-generator@0.13.0) (2020-08-17)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="0.12.0"></a>
|
|
||||||
# [0.12.0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.10.0...@ali/lowcode-code-generator@0.12.0) (2020-08-17)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="0.11.0"></a>
|
|
||||||
# [0.11.0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.10.0...@ali/lowcode-code-generator@0.11.0) (2020-08-17)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="0.10.0"></a>
|
|
||||||
# [0.10.0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.9.0...@ali/lowcode-code-generator@0.10.0) (2020-08-16)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="0.9.0"></a>
|
|
||||||
# [0.9.0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.8.10...@ali/lowcode-code-generator@0.9.0) (2020-08-14)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* 🐛 bugs about deps ([1eabd50](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/1eabd50))
|
|
||||||
* 🐛 children in props ([fe0ace8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/fe0ace8))
|
|
||||||
* 🐛 get deps info from slot ([6c3ae36](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/6c3ae36))
|
|
||||||
* 🐛 group chunks by filetype family ([db144a9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/db144a9))
|
|
||||||
* 🐛 loop bug ([8f53910](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/8f53910))
|
|
||||||
* 🐛 repair children before deps analyze ([737d06e](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/737d06e))
|
|
||||||
* 🐛 support JSFunction type ([9061e4b](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/9061e4b))
|
|
||||||
* 🐛 更改复杂类型生成工具的接口形式,减少调用复杂度 ([ce616b5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/ce616b5))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* 🎸 add node type mapping config for jsx plugin ([19a51b8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/19a51b8))
|
|
||||||
* 🎸 code generator fix slot support ([e51b9cb](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/e51b9cb))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="0.8.10"></a>
|
|
||||||
## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.8.9...@ali/lowcode-code-generator@0.8.10) (2020-07-21)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* 修复 condition 代码导出错误 ([57b30cf](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/57b30cf))
|
|
||||||
* 新增自定义模式 demo & 导出自定义需要的信息 ([07e2759](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/07e2759))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* add zip publisher ([31156ed](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/31156ed))
|
|
||||||
* prepare publish for code-generator ([93ff5c2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/93ff5c2))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="0.8.9"></a>
|
|
||||||
## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.8.7...@ali/lowcode-code-generator@0.8.9) (2020-07-12)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="0.8.7"></a>
|
|
||||||
## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.8.6...@ali/lowcode-code-generator@0.8.7) (2020-07-12)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* demo data ([b4a27fc](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b4a27fc))
|
|
||||||
* factory api ([237b866](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/237b866))
|
|
||||||
* same name chunk case ([d6855e2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/d6855e2))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* add recore project template ([267953b](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/267953b))
|
|
||||||
* add template create tool ([e906683](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/e906683))
|
|
||||||
* recore solution ([3bfe758](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/3bfe758))
|
|
||||||
* rewrite demo & export plugins and utils ([6cf7c3d](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/6cf7c3d))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="0.8.6"></a>
|
|
||||||
## [0.8.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.8.5...@ali/lowcode-code-generator@0.8.6) (2020-06-23)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* 更改生成 id 的规则, 否则命中 recore 解析 id 的一个限制 ([5adff44](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/5adff44))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="0.8.5"></a>
|
|
||||||
## [0.8.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.8.4...@ali/lowcode-code-generator@0.8.5) (2020-04-15)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* enhance compile config ([2899149](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/2899149))
|
|
||||||
* path resolve problem ([b12c0f8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b12c0f8))
|
|
||||||
* post process file error ([389eaf7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/389eaf7))
|
|
||||||
* rm demo in lib ([55630d6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/55630d6))
|
|
||||||
* use webpack for package ([b350a88](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b350a88))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* add prettier post processor ([49ac9a3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/49ac9a3))
|
|
||||||
* export publisher ([4a53faa](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/4a53faa))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="0.8.4"></a>
|
|
||||||
## [0.8.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.8.3...@ali/lowcode-code-generator@0.8.4) (2020-03-30)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="0.8.3"></a>
|
|
||||||
## [0.8.3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-code-generator@0.8.2...@ali/lowcode-code-generator@0.8.3) (2020-03-30)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ali/lowcode-code-generator
|
|
||||||
|
|
||||||
<a name="0.8.2"></a>
|
|
||||||
## 0.8.2 (2020-03-30)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* code generator main process ([021d6e0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/021d6e0))
|
|
||||||
* demo schema & complex children type ([a5ee6bd](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/a5ee6bd))
|
|
||||||
* fix gaps ([32af3d3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/32af3d3))
|
|
||||||
* project builder fix & publish demo to disk ([26983b3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/26983b3))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="0.8.1"></a>
|
|
||||||
## 0.8.1 (2020-03-30)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* code generator main process ([021d6e0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/021d6e0))
|
|
||||||
* demo schema & complex children type ([a5ee6bd](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/a5ee6bd))
|
|
||||||
* fix gaps ([32af3d3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/32af3d3))
|
|
||||||
* project builder fix & publish demo to disk ([26983b3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/26983b3))
|
|
||||||
* code generator main process ([021d6e0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/021d6e0fe9fb29a8b6c1c5d5f4d06ec71896faa5))
|
|
||||||
* demo schema & complex children type ([a5ee6bd](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/a5ee6bd55806fc9aea695096ccd4c7f50b8e31c4))
|
|
||||||
* fix gaps ([32af3d3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/32af3d3a3ca4d5aca15be25e05c840c8ea0cb6ae))
|
|
||||||
* project builder fix & publish demo to disk ([26983b3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/26983b38c2b0f1d39d79964eb54d8ce60250dd82))
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
# 出码模块
|
|
||||||
|
|
||||||
**重要!!! 本模块是 Node 端运行的!本模块是 Node 端运行的!本模块是 Node 端运行的!暂不支持 Web 端直接跑。**
|
|
||||||
如果有业务诉求需要在 Web 端运行,可以联系 @春希(armslave.yy),会在架构组讨论优先度。
|
|
||||||
|
|
||||||
详细介绍看这里:[出码模块 语雀文档](https://yuque.antfin.com/docs/share/2b342641-6e01-4c77-b8e0-30421f55f69b)
|
|
||||||
|
|
||||||
## 安装接入
|
|
||||||
|
|
||||||
## 自定义导出
|
|
||||||
|
|
||||||
## 开始开发
|
|
||||||
|
|
||||||
本项目隶属于 [ali-lowcode-engine](http://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine), 需要和整个 [ali-lowcode-engine](http://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine) 一起开发。
|
|
||||||
|
|
||||||
所以先要初始化整个 [ali-lowcode-engine](http://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine) 的环境:
|
|
||||||
|
|
||||||
1. 克隆 [ali-lowcode-engine](http://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine): `git clone git@gitlab.alibaba-inc.com:ali-lowcode/ali-lowcode-engine.git`
|
|
||||||
2. 运行 `setup` 脚本,初始化环境: `npm run setup`
|
|
||||||
|
|
||||||
然后,因为本项目依赖 `@ali/lowcode-types` 所以需要先构建下 `type`,即执行: `lerna run build --scope @ali/lowcode-types`
|
|
||||||
|
|
||||||
最后,可以运行 `npm start` 命令启动本地调试(本项目通过 `ava` 进行单元测试,故 `start` 脚本其实就是 `watch` 模式的 `ava`):
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# 到本项目目录下执行:(推荐)
|
|
||||||
npm start
|
|
||||||
|
|
||||||
# 或直接执行 ava:
|
|
||||||
npx ava --watch
|
|
||||||
|
|
||||||
# 或在 ali-lowcode-engine 工程根目录下执行: (不推荐,因为命令太长而且没法响应输入)
|
|
||||||
lerna run start --stream --scope @ali/lowcode-code-generator
|
|
||||||
```
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"plugins": [
|
|
||||||
"build-plugin-component"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,198 +0,0 @@
|
|||||||
const fs = require('fs');
|
|
||||||
// ../lib 可以替换成 @ali/lowcode-code-generator
|
|
||||||
const CodeGenerator = require('../lib').default;
|
|
||||||
|
|
||||||
function flatFiles(rootName, dir) {
|
|
||||||
const dirRoot = rootName ? `${rootName}/${dir.name}` : dir.name;
|
|
||||||
const files = dir.files.map((file) => ({
|
|
||||||
name: `${dirRoot}/${file.name}.${file.ext}`,
|
|
||||||
content: file.content,
|
|
||||||
ext: '',
|
|
||||||
}));
|
|
||||||
const filesInSub = dir.dirs.map((subDir) => flatFiles(`${dirRoot}`, subDir));
|
|
||||||
const result = files.concat(...filesInSub);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayResultInConsole(root, fileName) {
|
|
||||||
const files = flatFiles('.', root);
|
|
||||||
files.forEach((file) => {
|
|
||||||
if (!fileName || fileName === file.name) {
|
|
||||||
console.log(`========== ${file.name} Start ==========`);
|
|
||||||
console.log(file.content);
|
|
||||||
console.log(`========== ${file.name} End ==========`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function writeResultToDisk(root, path) {
|
|
||||||
const publisher = CodeGenerator.publishers.disk();
|
|
||||||
|
|
||||||
return publisher.publish({
|
|
||||||
project: root,
|
|
||||||
outputPath: path,
|
|
||||||
projectSlug: 'demo-project',
|
|
||||||
createProjectFolder: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getComponentsMap() {
|
|
||||||
const assetJson = fs.readFileSync('./demo/assets.json', { encoding: 'utf8' });
|
|
||||||
const assets = JSON.parse(assetJson);
|
|
||||||
const { components } = assets;
|
|
||||||
|
|
||||||
const componentsMap = components
|
|
||||||
.filter((c) => !!c.npm)
|
|
||||||
.map((c) => ({
|
|
||||||
componentName: c.componentName,
|
|
||||||
...(c.npm || {}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
return componentsMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
const schemaJson = fs.readFileSync('./demo/sampleSchema.json', { encoding: 'utf8' });
|
|
||||||
const createIceJsProjectBuilder = CodeGenerator.solutions.icejs;
|
|
||||||
const builder = createIceJsProjectBuilder();
|
|
||||||
|
|
||||||
builder.generateProject(schemaJson).then((result) => {
|
|
||||||
displayResultInConsole(result);
|
|
||||||
writeResultToDisk(result, 'output/lowcodeDemo').then((response) => console.log('Write to disk: ', JSON.stringify(response)));
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function demo() {
|
|
||||||
const schemaJson = fs.readFileSync('./demo/schema.json', { encoding: 'utf8' });
|
|
||||||
const createIceJsProjectBuilder = CodeGenerator.solutions.icejs;
|
|
||||||
const builder = createIceJsProjectBuilder();
|
|
||||||
|
|
||||||
const componentsMap = getComponentsMap();
|
|
||||||
const root = JSON.parse(schemaJson);
|
|
||||||
|
|
||||||
const fullSchema = {
|
|
||||||
version: '1.0.0',
|
|
||||||
config: {
|
|
||||||
historyMode: 'hash',
|
|
||||||
targetRootID: 'J_Container',
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
name: 'demoproject',
|
|
||||||
},
|
|
||||||
componentsTree: [root],
|
|
||||||
componentsMap,
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.generateProject(fullSchema).then((result) => {
|
|
||||||
displayResultInConsole(result);
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function demo() {
|
|
||||||
const schemaJson = fs.readFileSync('./demo/schema.json', { encoding: 'utf8' });
|
|
||||||
const createIceJsProjectBuilder = CodeGenerator.solutions.icejs;
|
|
||||||
const builder = createIceJsProjectBuilder();
|
|
||||||
|
|
||||||
const componentsMap = getComponentsMap();
|
|
||||||
const root = JSON.parse(schemaJson);
|
|
||||||
|
|
||||||
const fullSchema = {
|
|
||||||
version: '1.0.0',
|
|
||||||
config: {
|
|
||||||
historyMode: 'hash',
|
|
||||||
targetRootID: 'J_Container',
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
name: 'demoproject',
|
|
||||||
},
|
|
||||||
componentsTree: [root],
|
|
||||||
componentsMap,
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.generateProject(fullSchema).then((result) => {
|
|
||||||
displayResultInConsole(result);
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function exportModule() {
|
|
||||||
const schemaJson = fs.readFileSync('./demo/shenmaSample.json', { encoding: 'utf8' });
|
|
||||||
const moduleBuilder = CodeGenerator.createModuleBuilder({
|
|
||||||
plugins: [
|
|
||||||
CodeGenerator.plugins.react.reactCommonDeps(),
|
|
||||||
CodeGenerator.plugins.common.esmodule({
|
|
||||||
fileType: 'jsx',
|
|
||||||
}),
|
|
||||||
CodeGenerator.plugins.react.containerClass(),
|
|
||||||
CodeGenerator.plugins.react.containerInitState(),
|
|
||||||
CodeGenerator.plugins.react.containerLifeCycle(),
|
|
||||||
CodeGenerator.plugins.react.containerMethod(),
|
|
||||||
CodeGenerator.plugins.react.jsx(),
|
|
||||||
CodeGenerator.plugins.style.css(),
|
|
||||||
],
|
|
||||||
postProcessors: [CodeGenerator.postprocessor.prettier()],
|
|
||||||
mainFileName: 'index',
|
|
||||||
});
|
|
||||||
|
|
||||||
moduleBuilder.generateModuleCode(schemaJson).then((result) => {
|
|
||||||
displayResultInConsole(result);
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function exportProject() {
|
|
||||||
const schemaJson = fs.readFileSync('./demo/sampleSchema.json', { encoding: 'utf8' });
|
|
||||||
|
|
||||||
const builder = CodeGenerator.createProjectBuilder({
|
|
||||||
template: CodeGenerator.solutionParts.icejs.template,
|
|
||||||
plugins: {
|
|
||||||
components: [
|
|
||||||
CodeGenerator.plugins.react.reactCommonDeps(),
|
|
||||||
CodeGenerator.plugins.common.esmodule({
|
|
||||||
fileType: 'jsx',
|
|
||||||
}),
|
|
||||||
CodeGenerator.plugins.react.containerClass(),
|
|
||||||
CodeGenerator.plugins.react.containerInitState(),
|
|
||||||
CodeGenerator.plugins.react.containerLifeCycle(),
|
|
||||||
CodeGenerator.plugins.react.containerMethod(),
|
|
||||||
CodeGenerator.plugins.react.jsx(),
|
|
||||||
CodeGenerator.plugins.style.css(),
|
|
||||||
],
|
|
||||||
pages: [
|
|
||||||
CodeGenerator.plugins.react.reactCommonDeps(),
|
|
||||||
CodeGenerator.plugins.common.esmodule({
|
|
||||||
fileType: 'jsx',
|
|
||||||
}),
|
|
||||||
CodeGenerator.plugins.react.containerClass(),
|
|
||||||
CodeGenerator.plugins.react.containerInitState(),
|
|
||||||
CodeGenerator.plugins.react.containerLifeCycle(),
|
|
||||||
CodeGenerator.plugins.react.containerMethod(),
|
|
||||||
CodeGenerator.plugins.react.jsx(),
|
|
||||||
CodeGenerator.plugins.style.css(),
|
|
||||||
],
|
|
||||||
router: [CodeGenerator.plugins.common.esmodule(), CodeGenerator.solutionParts.icejs.plugins.router()],
|
|
||||||
entry: [CodeGenerator.solutionParts.icejs.plugins.entry()],
|
|
||||||
constants: [CodeGenerator.plugins.project.constants()],
|
|
||||||
utils: [CodeGenerator.plugins.common.esmodule(), CodeGenerator.plugins.project.utils()],
|
|
||||||
i18n: [CodeGenerator.plugins.project.i18n()],
|
|
||||||
globalStyle: [CodeGenerator.solutionParts.icejs.plugins.globalStyle()],
|
|
||||||
htmlEntry: [CodeGenerator.solutionParts.icejs.plugins.entryHtml()],
|
|
||||||
packageJSON: [CodeGenerator.solutionParts.icejs.plugins.packageJSON()],
|
|
||||||
},
|
|
||||||
postProcessors: [CodeGenerator.postprocessor.prettier()],
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.generateProject(schemaJson).then((result) => {
|
|
||||||
displayResultInConsole(result);
|
|
||||||
writeResultToDisk(result, 'output/lowcodeDemo').then((response) => console.log('Write to disk: ', JSON.stringify(response)));
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// main();
|
|
||||||
// exportModule();
|
|
||||||
// exportProject();
|
|
||||||
demo();
|
|
||||||
@ -1,243 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "1.0.0",
|
|
||||||
"componentsMap": [
|
|
||||||
{
|
|
||||||
"componentName": "Button",
|
|
||||||
"package": "@alifd/next",
|
|
||||||
"version": "1.19.18",
|
|
||||||
"destructuring": true,
|
|
||||||
"exportName": "Button"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"componentName": "Button.Group",
|
|
||||||
"package": "@alifd/next",
|
|
||||||
"version": "1.19.18",
|
|
||||||
"destructuring": true,
|
|
||||||
"exportName": "Button",
|
|
||||||
"subName": "Group"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"componentName": "Input",
|
|
||||||
"package": "@alifd/next",
|
|
||||||
"version": "1.19.18",
|
|
||||||
"destructuring": true,
|
|
||||||
"exportName": "Input"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"componentName": "Form",
|
|
||||||
"package": "@alifd/next",
|
|
||||||
"version": "1.19.18",
|
|
||||||
"destructuring": true,
|
|
||||||
"exportName": "Form"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"componentName": "Form.Item",
|
|
||||||
"package": "@alifd/next",
|
|
||||||
"version": "1.19.18",
|
|
||||||
"destructuring": true,
|
|
||||||
"exportName": "Form",
|
|
||||||
"subName": "Item"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"componentName": "NumberPicker",
|
|
||||||
"package": "@alifd/next",
|
|
||||||
"version": "1.19.18",
|
|
||||||
"destructuring": true,
|
|
||||||
"exportName": "NumberPicker"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"componentName": "Select",
|
|
||||||
"package": "@alifd/next",
|
|
||||||
"version": "1.19.18",
|
|
||||||
"destructuring": true,
|
|
||||||
"exportName": "Select"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"componentsTree": [
|
|
||||||
{
|
|
||||||
"componentName": "Page",
|
|
||||||
"id": "node$1",
|
|
||||||
"meta": {
|
|
||||||
"title": "测试",
|
|
||||||
"router": "/"
|
|
||||||
},
|
|
||||||
"props": {
|
|
||||||
"ref": "outterView",
|
|
||||||
"autoLoading": true
|
|
||||||
},
|
|
||||||
"fileName": "test",
|
|
||||||
"state": {
|
|
||||||
"text": "outter"
|
|
||||||
},
|
|
||||||
"lifeCycles": {
|
|
||||||
"componentDidMount": {
|
|
||||||
"type": "JSExpression",
|
|
||||||
"value": "function() { this.utils.request(this.props.url); }"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"componentName": "Form",
|
|
||||||
"id": "node$2",
|
|
||||||
"props": {
|
|
||||||
"labelCol": {
|
|
||||||
"type": "JSExpression",
|
|
||||||
"value": "this.state.colNum"
|
|
||||||
},
|
|
||||||
"style": {},
|
|
||||||
"ref": "testForm"
|
|
||||||
},
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"componentName": "Form.Item",
|
|
||||||
"id": "node$3",
|
|
||||||
"props": {
|
|
||||||
"label": "姓名:",
|
|
||||||
"name": "name",
|
|
||||||
"initValue": "李雷"
|
|
||||||
},
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"componentName": "Input",
|
|
||||||
"id": "node$4",
|
|
||||||
"props": {
|
|
||||||
"placeholder": "请输入",
|
|
||||||
"size": "medium",
|
|
||||||
"style": {
|
|
||||||
"width": 320
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"componentName": "Form.Item",
|
|
||||||
"id": "node$5",
|
|
||||||
"props": {
|
|
||||||
"label": "年龄:",
|
|
||||||
"name": "age",
|
|
||||||
"initValue": "22"
|
|
||||||
},
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"componentName": "NumberPicker",
|
|
||||||
"id": "node$6",
|
|
||||||
"props": {
|
|
||||||
"size": "medium",
|
|
||||||
"type": "normal"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"componentName": "Form.Item",
|
|
||||||
"id": "node$7",
|
|
||||||
"props": {
|
|
||||||
"label": "职业:",
|
|
||||||
"name": "profession"
|
|
||||||
},
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"componentName": "Select",
|
|
||||||
"id": "node$8",
|
|
||||||
"props": {
|
|
||||||
"dataSource": [
|
|
||||||
{
|
|
||||||
"label": "教师",
|
|
||||||
"value": "t"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "医生",
|
|
||||||
"value": "d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "歌手",
|
|
||||||
"value": "s"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"componentName": "Div",
|
|
||||||
"id": "node$9",
|
|
||||||
"props": {
|
|
||||||
"style": {
|
|
||||||
"textAlign": "center"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"componentName": "Button.Group",
|
|
||||||
"id": "node$a",
|
|
||||||
"props": {},
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"componentName": "Button",
|
|
||||||
"id": "node$b",
|
|
||||||
"props": {
|
|
||||||
"type": "primary",
|
|
||||||
"style": {
|
|
||||||
"margin": "0 5px 0 5px"
|
|
||||||
},
|
|
||||||
"htmlType": "submit"
|
|
||||||
},
|
|
||||||
"children": [
|
|
||||||
"提交"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"componentName": "Button",
|
|
||||||
"id": "node$d",
|
|
||||||
"props": {
|
|
||||||
"type": "normal",
|
|
||||||
"style": {
|
|
||||||
"margin": "0 5px 0 5px"
|
|
||||||
},
|
|
||||||
"htmlType": "reset"
|
|
||||||
},
|
|
||||||
"children": [
|
|
||||||
"重置"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"constants": {
|
|
||||||
"ENV": "prod",
|
|
||||||
"DOMAIN": "xxx.alibaba-inc.com"
|
|
||||||
},
|
|
||||||
"css": "body {font-size: 12px;} .table { width: 100px;}",
|
|
||||||
"config": {
|
|
||||||
"sdkVersion": "1.0.3",
|
|
||||||
"historyMode": "hash",
|
|
||||||
"targetRootID": "J_Container",
|
|
||||||
"layout": {
|
|
||||||
"componentName": "BasicLayout",
|
|
||||||
"props": {
|
|
||||||
"logo": "...",
|
|
||||||
"name": "测试网站"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"theme": {
|
|
||||||
"package": "@alife/theme-fusion",
|
|
||||||
"version": "^0.1.0",
|
|
||||||
"primary": "#ff9966"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
"name": "demo应用",
|
|
||||||
"git_group": "appGroup",
|
|
||||||
"project_name": "app_demo",
|
|
||||||
"description": "这是一个测试应用",
|
|
||||||
"spma": "spa23d",
|
|
||||||
"creator": "月飞"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,420 +0,0 @@
|
|||||||
{
|
|
||||||
"componentName": "Page",
|
|
||||||
"id": "node_dockcviv8fo1",
|
|
||||||
"props": {
|
|
||||||
"ref": "outterView",
|
|
||||||
"autoLoading": true,
|
|
||||||
"style": {
|
|
||||||
"padding": "0 5px 0 5px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fileName": "test",
|
|
||||||
"dataSource": {
|
|
||||||
"list": []
|
|
||||||
},
|
|
||||||
"state": {
|
|
||||||
"text": "outter",
|
|
||||||
"isShowDialog": false
|
|
||||||
},
|
|
||||||
"css": "body {font-size: 12px;} .botton{width:100px;color:#ff00ff}",
|
|
||||||
"lifeCycles": {
|
|
||||||
"componentDidMount": {
|
|
||||||
"type": "JSFunction",
|
|
||||||
"value": "function() {\n console.log('did mount');\n }"
|
|
||||||
},
|
|
||||||
"componentWillUnmount": {
|
|
||||||
"type": "JSFunction",
|
|
||||||
"value": "function() {\n console.log('will umount');\n }"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"methods": {
|
|
||||||
"testFunc": {
|
|
||||||
"type": "JSFunction",
|
|
||||||
"value": "function() {\n console.log('test func');\n }"
|
|
||||||
},
|
|
||||||
"onClick": {
|
|
||||||
"type": "JSFunction",
|
|
||||||
"value": "function(){\n this.setState({\n isShowDialog:true\n })\n\t}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Box",
|
|
||||||
"id": "node_dockcy8n9xed",
|
|
||||||
"props": {
|
|
||||||
"style": {
|
|
||||||
"backgroundColor": "rgba(31,56,88,0.1)",
|
|
||||||
"padding": "12px 12px 12px 12px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Box",
|
|
||||||
"id": "node_dockcy8n9xee",
|
|
||||||
"props": {
|
|
||||||
"style": {
|
|
||||||
"padding": "12px 12px 12px 12px",
|
|
||||||
"backgroundColor": "#ffffff"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Breadcrumb",
|
|
||||||
"id": "node_dockcy8n9xef",
|
|
||||||
"props": {
|
|
||||||
"prefix": "next-",
|
|
||||||
"maxNode": 100,
|
|
||||||
"component": "nav"
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Breadcrumb.Item",
|
|
||||||
"id": "node_dockcy8n9xeg",
|
|
||||||
"props": {
|
|
||||||
"prefix": "next-"
|
|
||||||
},
|
|
||||||
"children": ["首页"]
|
|
||||||
}, {
|
|
||||||
"componentName": "Breadcrumb.Item",
|
|
||||||
"id": "node_dockcy8n9xei",
|
|
||||||
"props": {
|
|
||||||
"prefix": "next-"
|
|
||||||
},
|
|
||||||
"children": ["品质中台"]
|
|
||||||
}, {
|
|
||||||
"componentName": "Breadcrumb.Item",
|
|
||||||
"id": "node_dockcy8n9xek",
|
|
||||||
"props": {
|
|
||||||
"prefix": "next-"
|
|
||||||
},
|
|
||||||
"children": ["商家品质页面管理"]
|
|
||||||
}, {
|
|
||||||
"componentName": "Breadcrumb.Item",
|
|
||||||
"id": "node_dockcy8n9xem",
|
|
||||||
"props": {
|
|
||||||
"prefix": "next-"
|
|
||||||
},
|
|
||||||
"children": ["质检知识条配置"]
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
"componentName": "Box",
|
|
||||||
"id": "node_dockcy8n9xeo",
|
|
||||||
"props": {
|
|
||||||
"style": {
|
|
||||||
"marginTop": "12px",
|
|
||||||
"backgroundColor": "#ffffff"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Form",
|
|
||||||
"id": "node_dockcy8n9xep",
|
|
||||||
"props": {
|
|
||||||
"inline": true,
|
|
||||||
"style": {
|
|
||||||
"marginTop": "12px",
|
|
||||||
"marginRight": "12px",
|
|
||||||
"marginLeft": "12px"
|
|
||||||
},
|
|
||||||
"__events": []
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Form.Item",
|
|
||||||
"id": "node_dockcy8n9xeq",
|
|
||||||
"props": {
|
|
||||||
"style": {
|
|
||||||
"marginBottom": "0"
|
|
||||||
},
|
|
||||||
"label": "类目名:"
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Select",
|
|
||||||
"id": "node_dockcy8n9xer",
|
|
||||||
"props": {
|
|
||||||
"mode": "single",
|
|
||||||
"hasArrow": true,
|
|
||||||
"cacheValue": true,
|
|
||||||
"style": {
|
|
||||||
"width": "150px"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
"componentName": "Form.Item",
|
|
||||||
"id": "node_dockcy8n9xes",
|
|
||||||
"props": {
|
|
||||||
"style": {
|
|
||||||
"marginBottom": "0"
|
|
||||||
},
|
|
||||||
"label": "项目类型:"
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Select",
|
|
||||||
"id": "node_dockcy8n9xet",
|
|
||||||
"props": {
|
|
||||||
"mode": "single",
|
|
||||||
"hasArrow": true,
|
|
||||||
"cacheValue": true,
|
|
||||||
"style": {
|
|
||||||
"width": "200px"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
"componentName": "Form.Item",
|
|
||||||
"id": "node_dockcy8n9xeu",
|
|
||||||
"props": {
|
|
||||||
"style": {
|
|
||||||
"marginBottom": "0"
|
|
||||||
},
|
|
||||||
"label": "项目 ID:"
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Input",
|
|
||||||
"id": "node_dockcy8n9xev",
|
|
||||||
"props": {
|
|
||||||
"hasBorder": true,
|
|
||||||
"size": "medium",
|
|
||||||
"autoComplete": "off",
|
|
||||||
"style": {
|
|
||||||
"width": "200px"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
"componentName": "Button.Group",
|
|
||||||
"id": "node_dockcy8n9xew",
|
|
||||||
"props": {},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Button",
|
|
||||||
"id": "node_dockcy8n9xex",
|
|
||||||
"props": {
|
|
||||||
"type": "primary",
|
|
||||||
"style": {
|
|
||||||
"margin": "0 5px 0 5px"
|
|
||||||
},
|
|
||||||
"htmlType": "submit"
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Icon",
|
|
||||||
"id": "node_dockcy8n9xey",
|
|
||||||
"props": {
|
|
||||||
"type": "success"
|
|
||||||
}
|
|
||||||
}, "搜索"]
|
|
||||||
}, {
|
|
||||||
"componentName": "Button",
|
|
||||||
"id": "node_dockcy8n9xe10",
|
|
||||||
"props": {
|
|
||||||
"type": "normal",
|
|
||||||
"style": {
|
|
||||||
"margin": "0 5px 0 5px"
|
|
||||||
},
|
|
||||||
"htmlType": "reset"
|
|
||||||
},
|
|
||||||
"children": ["清空"]
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
"componentName": "Box",
|
|
||||||
"id": "node_dockcy8n9xe12",
|
|
||||||
"props": {
|
|
||||||
"style": {
|
|
||||||
"justifyContent": "flex-end",
|
|
||||||
"display": "flex",
|
|
||||||
"backgroundColor": "#ffffff",
|
|
||||||
"flexDirection": "row",
|
|
||||||
"paddingRight": "24px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Button",
|
|
||||||
"id": "node_dockcy8n9xe13",
|
|
||||||
"props": {
|
|
||||||
"prefix": "next-",
|
|
||||||
"type": "primary",
|
|
||||||
"size": "medium",
|
|
||||||
"htmlType": "button",
|
|
||||||
"component": "button",
|
|
||||||
"style": {
|
|
||||||
"width": "100px"
|
|
||||||
},
|
|
||||||
"events": {
|
|
||||||
"onClick": {
|
|
||||||
"type": "JSFunction",
|
|
||||||
"value": "function(){ this.onClick() }",
|
|
||||||
"__eventData": {
|
|
||||||
"type": "componentEvent",
|
|
||||||
"name": "onClick",
|
|
||||||
"relatedEventName": "onClick"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"__events": [{
|
|
||||||
"type": "componentEvent",
|
|
||||||
"name": "onClick",
|
|
||||||
"relatedEventName": "onClick"
|
|
||||||
}],
|
|
||||||
"onClick": {
|
|
||||||
"type": "JSFunction",
|
|
||||||
"value": "function(){ this.onClick() }"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": ["新建配置"]
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
"componentName": "Box",
|
|
||||||
"id": "node_dockcy8n9xe15",
|
|
||||||
"props": {
|
|
||||||
"style": {
|
|
||||||
"backgroundColor": "#ffffff"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Table",
|
|
||||||
"id": "node_dockcy8n9xe16",
|
|
||||||
"props": {
|
|
||||||
"dataSource": [{
|
|
||||||
"firstCategory": "其他",
|
|
||||||
"secondCategory": "新品预览",
|
|
||||||
"leafCategory": "",
|
|
||||||
"projectType": "标识判断",
|
|
||||||
"projectId": "",
|
|
||||||
"title": "其他类目->新品预览类目类型知识库",
|
|
||||||
"url": "其他",
|
|
||||||
"operation": "编辑"
|
|
||||||
}, {
|
|
||||||
"firstCategory": "其他",
|
|
||||||
"secondCategory": "新品预览",
|
|
||||||
"leafCategory": "",
|
|
||||||
"projectType": "",
|
|
||||||
"projectId": "1",
|
|
||||||
"title": "其他类目->新品预览项目Id知识库",
|
|
||||||
"url": "其他",
|
|
||||||
"operation": "编辑"
|
|
||||||
}],
|
|
||||||
"size": "medium",
|
|
||||||
"prefix": "next-",
|
|
||||||
"hasBorder": true,
|
|
||||||
"hasHeader": true,
|
|
||||||
"isZebra": false,
|
|
||||||
"loading": false,
|
|
||||||
"expandedIndexSimulate": false,
|
|
||||||
"primaryKey": "id",
|
|
||||||
"locale": "zhCN.Table",
|
|
||||||
"crossline": false,
|
|
||||||
"style": {
|
|
||||||
"margin": "24px 12px 24px 12px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Table.Column",
|
|
||||||
"id": "node_dockcy8n9xe17",
|
|
||||||
"props": {
|
|
||||||
"title": "一级类目",
|
|
||||||
"dataIndex": "firstCategory"
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"componentName": "Table.Column",
|
|
||||||
"id": "node_dockcy8n9xe18",
|
|
||||||
"props": {
|
|
||||||
"title": "二级类目",
|
|
||||||
"dataIndex": "secondCategory"
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"componentName": "Table.Column",
|
|
||||||
"id": "node_dockcy8n9xe19",
|
|
||||||
"props": {
|
|
||||||
"title": "叶子类目",
|
|
||||||
"dataIndex": "leafCategory"
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"componentName": "Table.Column",
|
|
||||||
"id": "node_dockcy8n9xe1a",
|
|
||||||
"props": {
|
|
||||||
"title": "项目类型",
|
|
||||||
"dataIndex": "projectType"
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"componentName": "Table.Column",
|
|
||||||
"id": "node_dockcy8n9xe1b",
|
|
||||||
"props": {
|
|
||||||
"title": "项目 ID",
|
|
||||||
"dataIndex": "projectId"
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"componentName": "Table.Column",
|
|
||||||
"id": "node_dockcy8n9xe1c",
|
|
||||||
"props": {
|
|
||||||
"title": "知识条标题",
|
|
||||||
"dataIndex": "title"
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"componentName": "Table.Column",
|
|
||||||
"id": "node_dockcy8n9xe1d",
|
|
||||||
"props": {
|
|
||||||
"title": "知识条链接",
|
|
||||||
"dataIndex": "url"
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"componentName": "Table.Column",
|
|
||||||
"id": "node_dockcy8n9xe1e",
|
|
||||||
"props": {
|
|
||||||
"title": "操作",
|
|
||||||
"dataIndex": "operation"
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
"componentName": "Box",
|
|
||||||
"id": "node_dockcy8n9xe1f",
|
|
||||||
"props": {
|
|
||||||
"style": {
|
|
||||||
"backgroundColor": "#ffffff",
|
|
||||||
"paddingBottom": "24px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Pagination",
|
|
||||||
"id": "node_dockcy8n9xe1g",
|
|
||||||
"props": {
|
|
||||||
"prefix": "next-",
|
|
||||||
"type": "normal",
|
|
||||||
"shape": "normal",
|
|
||||||
"size": "medium",
|
|
||||||
"defaultCurrent": 1,
|
|
||||||
"total": 100,
|
|
||||||
"pageShowCount": 5,
|
|
||||||
"pageSize": 10,
|
|
||||||
"pageSizePosition": "start",
|
|
||||||
"showJump": true,
|
|
||||||
"style": {
|
|
||||||
"display": "flex",
|
|
||||||
"justifyContent": "flex-end"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
"componentName": "Dialog",
|
|
||||||
"id": "node_dockcy8n9xe1h",
|
|
||||||
"props": {
|
|
||||||
"prefix": "next-",
|
|
||||||
"footerAlign": "right",
|
|
||||||
"footerActions": ["ok", "cancel"],
|
|
||||||
"closeable": "esc,close",
|
|
||||||
"hasMask": true,
|
|
||||||
"align": "cc cc",
|
|
||||||
"minMargin": 40,
|
|
||||||
"visible": {
|
|
||||||
"type": "JSExpression",
|
|
||||||
"value": "this.state.isShowDialog"
|
|
||||||
},
|
|
||||||
"children": {
|
|
||||||
"type": "JSSlot"
|
|
||||||
},
|
|
||||||
"title": "标题",
|
|
||||||
"footer": {
|
|
||||||
"type": "JSSlot"
|
|
||||||
},
|
|
||||||
"events": []
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "1.0.0",
|
|
||||||
"componentsMap": [
|
|
||||||
{
|
|
||||||
"componentName": "Demo",
|
|
||||||
"package": "@ali/demo",
|
|
||||||
"version": "1.19.18",
|
|
||||||
"destructuring": true,
|
|
||||||
"exportName": "Demo"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"id": "page_kc326r8m",
|
|
||||||
"componentsTree": [{
|
|
||||||
"componentName": "Page",
|
|
||||||
"id": "node_kc326r8h",
|
|
||||||
"props": {},
|
|
||||||
"condition": true,
|
|
||||||
"loopArgs": ["item", "index"],
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Demo",
|
|
||||||
"id": "node_kc326r8i",
|
|
||||||
"props": {
|
|
||||||
"value": "文本内容",
|
|
||||||
"color": "#ffffff",
|
|
||||||
"ui_maxLine": 2,
|
|
||||||
"url": "",
|
|
||||||
"ui_type": "xs",
|
|
||||||
"style": {},
|
|
||||||
"className": ""
|
|
||||||
},
|
|
||||||
"condition": true,
|
|
||||||
"loopArgs": ["item", "index"]
|
|
||||||
}]
|
|
||||||
}],
|
|
||||||
"params": {}
|
|
||||||
}
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@ali/lowcode-code-generator",
|
|
||||||
"version": "1.0.22",
|
|
||||||
"description": "出码引擎 for LowCode Engine",
|
|
||||||
"main": "lib/index.js",
|
|
||||||
"module": "es/index.js",
|
|
||||||
"typings": "es/index.d.ts",
|
|
||||||
"files": [
|
|
||||||
"lib",
|
|
||||||
"es",
|
|
||||||
"demo"
|
|
||||||
],
|
|
||||||
"scripts": {
|
|
||||||
"start": "ava --watch",
|
|
||||||
"build": "npm run build:bs",
|
|
||||||
"build:bs": "rimraf lib && rimraf es && build-scripts build --skip-demo",
|
|
||||||
"build:tsc": "rimraf lib && tsc",
|
|
||||||
"demo": "node ./demo/demo.js",
|
|
||||||
"test": "ava",
|
|
||||||
"template": "node ./tools/createTemplate.js"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@ali/am-eslint-config": "*",
|
|
||||||
"@ali/lowcode-types": "^1.0.20",
|
|
||||||
"@ali/my-prettier": "^1.0.0",
|
|
||||||
"@babel/generator": "^7.9.5",
|
|
||||||
"@babel/parser": "^7.9.4",
|
|
||||||
"@babel/traverse": "^7.9.5",
|
|
||||||
"@babel/types": "^7.9.5",
|
|
||||||
"@types/prettier": "^1.19.1",
|
|
||||||
"change-case": "^3.1.0",
|
|
||||||
"html-entities": "^1.3.1",
|
|
||||||
"jszip": "^3.5.0",
|
|
||||||
"prettier": "^2.0.2",
|
|
||||||
"semver": "^7.3.2",
|
|
||||||
"short-uuid": "^3.1.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@alib/build-scripts": "^0.1.18",
|
|
||||||
"@types/babel__traverse": "^7.0.10",
|
|
||||||
"ava": "^1.0.1",
|
|
||||||
"rimraf": "^3.0.2",
|
|
||||||
"ts-loader": "^6.2.2",
|
|
||||||
"ts-node": "^8.10.2",
|
|
||||||
"tsconfig-paths": "^3.9.0"
|
|
||||||
},
|
|
||||||
"ava": {
|
|
||||||
"compileEnhancements": false,
|
|
||||||
"snapshotDir": "test/fixtures/__snapshots__",
|
|
||||||
"files": [
|
|
||||||
"test/**/*.test.ts"
|
|
||||||
],
|
|
||||||
"extensions": [
|
|
||||||
"ts"
|
|
||||||
],
|
|
||||||
"require": [
|
|
||||||
"ts-node/register/transpile-only"
|
|
||||||
],
|
|
||||||
"sources": [
|
|
||||||
"src/**/*",
|
|
||||||
"test/**/*",
|
|
||||||
"test-cases/**/expected/**/*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
|
||||||
"registry": "http://registry.npm.alibaba-inc.com"
|
|
||||||
},
|
|
||||||
"license": "MIT"
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
// / <reference types="node" />
|
|
||||||
|
|
||||||
declare module '@ali/my-prettier' {
|
|
||||||
function format(text: string, type: string): string;
|
|
||||||
export default format;
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import { FileType } from '../types/core';
|
|
||||||
|
|
||||||
export const FILE_TYPE_FAMILY = [[FileType.TSX, FileType.TS, FileType.JSX, FileType.JS]];
|
|
||||||
@ -1,125 +0,0 @@
|
|||||||
export const COMMON_CHUNK_NAME = {
|
|
||||||
ExternalDepsImport: 'CommonExternalDependencyImport',
|
|
||||||
InternalDepsImport: 'CommonInternalDependencyImport',
|
|
||||||
ImportAliasDefine: 'CommonImportAliasDefine',
|
|
||||||
FileVarDefine: 'CommonFileScopeVarDefine',
|
|
||||||
FileUtilDefine: 'CommonFileScopeMethodDefine',
|
|
||||||
FileMainContent: 'CommonFileMainContent',
|
|
||||||
FileExport: 'CommonFileExport',
|
|
||||||
StyleDepsImport: 'CommonStyleDepsImport',
|
|
||||||
StyleCssContent: 'CommonStyleCssContent',
|
|
||||||
HtmlContent: 'CommonHtmlContent',
|
|
||||||
CustomContent: 'CommonCustomContent',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const CLASS_DEFINE_CHUNK_NAME = {
|
|
||||||
Start: 'CommonClassDefineStart',
|
|
||||||
ConstructorStart: 'CommonClassDefineConstructorStart',
|
|
||||||
ConstructorContent: 'CommonClassDefineConstructorContent',
|
|
||||||
ConstructorEnd: 'CommonClassDefineConstructorEnd',
|
|
||||||
StaticVar: 'CommonClassDefineStaticVar',
|
|
||||||
StaticMethod: 'CommonClassDefineStaticMethod',
|
|
||||||
InsVar: 'CommonClassDefineInsVar',
|
|
||||||
InsVarMethod: 'CommonClassDefineInsVarMethod',
|
|
||||||
InsMethod: 'CommonClassDefineInsMethod',
|
|
||||||
InsPrivateMethod: 'CommonClassDefineInsPrivateMethod',
|
|
||||||
End: 'CommonClassDefineEnd',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DEFAULT_LINK_AFTER = {
|
|
||||||
[COMMON_CHUNK_NAME.ExternalDepsImport]: [],
|
|
||||||
[COMMON_CHUNK_NAME.InternalDepsImport]: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
|
||||||
[COMMON_CHUNK_NAME.ImportAliasDefine]: [COMMON_CHUNK_NAME.ExternalDepsImport, COMMON_CHUNK_NAME.InternalDepsImport],
|
|
||||||
[COMMON_CHUNK_NAME.FileVarDefine]: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
],
|
|
||||||
[COMMON_CHUNK_NAME.FileUtilDefine]: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
],
|
|
||||||
[CLASS_DEFINE_CHUNK_NAME.Start]: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
],
|
|
||||||
[CLASS_DEFINE_CHUNK_NAME.ConstructorStart]: [
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticVar,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticMethod,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsVarMethod,
|
|
||||||
],
|
|
||||||
[CLASS_DEFINE_CHUNK_NAME.ConstructorContent]: [CLASS_DEFINE_CHUNK_NAME.ConstructorStart],
|
|
||||||
[CLASS_DEFINE_CHUNK_NAME.ConstructorEnd]: [
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.ConstructorStart,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
|
||||||
],
|
|
||||||
[CLASS_DEFINE_CHUNK_NAME.StaticVar]: [CLASS_DEFINE_CHUNK_NAME.Start],
|
|
||||||
[CLASS_DEFINE_CHUNK_NAME.StaticMethod]: [CLASS_DEFINE_CHUNK_NAME.Start, CLASS_DEFINE_CHUNK_NAME.StaticVar],
|
|
||||||
[CLASS_DEFINE_CHUNK_NAME.InsVar]: [
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticVar,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticMethod,
|
|
||||||
],
|
|
||||||
[CLASS_DEFINE_CHUNK_NAME.InsVarMethod]: [
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticVar,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticMethod,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
],
|
|
||||||
[CLASS_DEFINE_CHUNK_NAME.InsMethod]: [
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticVar,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticMethod,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsVarMethod,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
|
|
||||||
],
|
|
||||||
[CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod]: [
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticVar,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticMethod,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsVarMethod,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
|
|
||||||
],
|
|
||||||
[CLASS_DEFINE_CHUNK_NAME.End]: [
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticVar,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.StaticMethod,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsVarMethod,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
|
|
||||||
],
|
|
||||||
[COMMON_CHUNK_NAME.FileMainContent]: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.End,
|
|
||||||
],
|
|
||||||
[COMMON_CHUNK_NAME.FileExport]: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.End,
|
|
||||||
COMMON_CHUNK_NAME.FileMainContent,
|
|
||||||
],
|
|
||||||
[COMMON_CHUNK_NAME.StyleDepsImport]: [],
|
|
||||||
[COMMON_CHUNK_NAME.StyleCssContent]: [COMMON_CHUNK_NAME.StyleDepsImport],
|
|
||||||
[COMMON_CHUNK_NAME.HtmlContent]: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
export const COMMON_SUB_MODULE_NAME = 'index';
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
export const NATIVE_ELE_PKG = 'native';
|
|
||||||
|
|
||||||
export const CONTAINER_TYPE = {
|
|
||||||
COMPONENT: 'Component',
|
|
||||||
BLOCK: 'Block',
|
|
||||||
PAGE: 'Page',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SUPPORT_SCHEMA_VERSION_LIST = ['0.0.1'];
|
|
||||||
@ -1,118 +0,0 @@
|
|||||||
import { BuilderComponentPlugin, IChunkBuilder, ICodeChunk, ICodeStruct, FileType } from '../types';
|
|
||||||
|
|
||||||
import { COMMON_SUB_MODULE_NAME } from '../const/generator';
|
|
||||||
import { FILE_TYPE_FAMILY } from '../const/file';
|
|
||||||
|
|
||||||
type ChunkGroupInfo = {
|
|
||||||
chunk: ICodeChunk;
|
|
||||||
familyIdx?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
function whichFamily(type: FileType): [number, FileType[]] | undefined {
|
|
||||||
const idx = FILE_TYPE_FAMILY.findIndex((family) => family.indexOf(type) >= 0);
|
|
||||||
if (idx < 0) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return [idx, FILE_TYPE_FAMILY[idx]];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const groupChunks = (chunks: ICodeChunk[]): ICodeChunk[][] => {
|
|
||||||
const tmp: Record<string, Record<number, number>> = {};
|
|
||||||
const col = chunks.reduce((chunksSet: Record<string, ChunkGroupInfo[]>, chunk) => {
|
|
||||||
const fileKey = chunk.subModule || COMMON_SUB_MODULE_NAME;
|
|
||||||
if (!chunksSet[fileKey]) {
|
|
||||||
chunksSet[fileKey] = [];
|
|
||||||
}
|
|
||||||
const res = whichFamily(chunk.fileType as FileType);
|
|
||||||
const info: ChunkGroupInfo = {
|
|
||||||
chunk,
|
|
||||||
};
|
|
||||||
if (res) {
|
|
||||||
const [familyIdx, family] = res;
|
|
||||||
const rank = family.indexOf(chunk.fileType as FileType);
|
|
||||||
if (tmp[fileKey]) {
|
|
||||||
if (tmp[fileKey][familyIdx] !== undefined) {
|
|
||||||
if (tmp[fileKey][familyIdx] > rank) {
|
|
||||||
tmp[fileKey][familyIdx] = rank;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tmp[fileKey][familyIdx] = rank;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tmp[fileKey] = {};
|
|
||||||
tmp[fileKey][familyIdx] = rank;
|
|
||||||
}
|
|
||||||
info.familyIdx = familyIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunksSet[fileKey].push(info);
|
|
||||||
return chunksSet;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
const result: ICodeChunk[][] = [];
|
|
||||||
Object.keys(col).forEach((key) => {
|
|
||||||
const byType: Record<string, ICodeChunk[]> = {};
|
|
||||||
col[key].forEach((info) => {
|
|
||||||
let t: string = info.chunk.fileType;
|
|
||||||
if (info.familyIdx !== undefined) {
|
|
||||||
t = FILE_TYPE_FAMILY[info.familyIdx][tmp[key][info.familyIdx]];
|
|
||||||
info.chunk.fileType = t;
|
|
||||||
}
|
|
||||||
if (!byType[t]) {
|
|
||||||
byType[t] = [];
|
|
||||||
}
|
|
||||||
byType[t].push(info.chunk);
|
|
||||||
});
|
|
||||||
result.push(...Object.keys(byType).map((t) => byType[t]));
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 代码片段构建器
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @class ChunkBuilder
|
|
||||||
* @template T
|
|
||||||
*/
|
|
||||||
export default class ChunkBuilder implements IChunkBuilder {
|
|
||||||
private plugins: BuilderComponentPlugin[];
|
|
||||||
|
|
||||||
constructor(plugins: BuilderComponentPlugin[] = []) {
|
|
||||||
this.plugins = plugins;
|
|
||||||
}
|
|
||||||
|
|
||||||
async run(
|
|
||||||
ir: unknown,
|
|
||||||
initialStructure: ICodeStruct = {
|
|
||||||
ir,
|
|
||||||
chunks: [],
|
|
||||||
depNames: [],
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
const structure = initialStructure;
|
|
||||||
|
|
||||||
const finalStructure: ICodeStruct = await this.plugins.reduce(
|
|
||||||
async (previousPluginOperation: Promise<ICodeStruct>, plugin) => {
|
|
||||||
const modifiedStructure = await previousPluginOperation;
|
|
||||||
return plugin(modifiedStructure);
|
|
||||||
},
|
|
||||||
Promise.resolve(structure),
|
|
||||||
);
|
|
||||||
|
|
||||||
const chunks = groupChunks(finalStructure.chunks);
|
|
||||||
|
|
||||||
return {
|
|
||||||
chunks,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
getPlugins() {
|
|
||||||
return this.plugins;
|
|
||||||
}
|
|
||||||
|
|
||||||
addPlugin(plugin: BuilderComponentPlugin) {
|
|
||||||
this.plugins.push(plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
import { ChunkContent, ChunkType, CodeGeneratorError, CodeGeneratorFunction, ICodeBuilder, ICodeChunk } from '../types';
|
|
||||||
|
|
||||||
export default class Builder implements ICodeBuilder {
|
|
||||||
private chunkDefinitions: ICodeChunk[] = [];
|
|
||||||
|
|
||||||
private generators: { [key: string]: CodeGeneratorFunction<ChunkContent> } = {
|
|
||||||
[ChunkType.STRING]: (str: string) => str, // no-op for string chunks
|
|
||||||
[ChunkType.JSON]: (json: Record<string, unknown>) => JSON.stringify(json), // stringify json to string
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(chunkDefinitions: ICodeChunk[] = []) {
|
|
||||||
this.chunkDefinitions = chunkDefinitions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Links all chunks together based on their requirements. Returns an array
|
|
||||||
* of ordered chunk names which need to be compiled and glued together.
|
|
||||||
*/
|
|
||||||
link(chunkDefinitions: ICodeChunk[] = []): string {
|
|
||||||
const chunks = chunkDefinitions || this.chunkDefinitions;
|
|
||||||
if (chunks.length <= 0) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const unprocessedChunks = chunks.map((chunk) => {
|
|
||||||
return {
|
|
||||||
name: chunk.name,
|
|
||||||
type: chunk.type,
|
|
||||||
content: chunk.content,
|
|
||||||
linkAfter: this.cleanupInvalidChunks(chunk.linkAfter, chunks),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const resultingString: string[] = [];
|
|
||||||
|
|
||||||
while (unprocessedChunks.length > 0) {
|
|
||||||
let indexToRemove = 0;
|
|
||||||
for (let index = 0; index < unprocessedChunks.length; index++) {
|
|
||||||
if (unprocessedChunks[index].linkAfter.length <= 0) {
|
|
||||||
indexToRemove = index;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unprocessedChunks[indexToRemove].linkAfter.length > 0) {
|
|
||||||
throw new CodeGeneratorError('Operation aborted. Reason: cyclic dependency between chunks.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { type, content, name } = unprocessedChunks[indexToRemove];
|
|
||||||
const compiledContent = this.generateByType(type, content);
|
|
||||||
if (compiledContent) {
|
|
||||||
resultingString.push(`${compiledContent }\n`);
|
|
||||||
}
|
|
||||||
|
|
||||||
unprocessedChunks.splice(indexToRemove, 1);
|
|
||||||
if (!unprocessedChunks.some((ch) => ch.name === name)) {
|
|
||||||
unprocessedChunks.forEach(
|
|
||||||
// remove the processed chunk from all the linkAfter arrays from the remaining chunks
|
|
||||||
(ch) => {
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
ch.linkAfter = ch.linkAfter.filter((after) => after !== name);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultingString.join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
generateByType(type: string, content: unknown): string {
|
|
||||||
if (!content) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
if (Array.isArray(content)) {
|
|
||||||
return content.map((contentItem) => this.generateByType(type, contentItem)).join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.generators[type]) {
|
|
||||||
throw new Error(
|
|
||||||
`Attempted to generate unknown type ${type}. Please register a generator for this type in builder/index.ts`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.generators[type](content);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove invalid chunks (which did not end up being created) from the linkAfter fields
|
|
||||||
// one use-case is when you want to remove the import plugin
|
|
||||||
private cleanupInvalidChunks(linkAfter: string[], chunks: ICodeChunk[]) {
|
|
||||||
return linkAfter.filter((chunkName) => chunks.some((chunk) => chunk.name === chunkName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,99 +0,0 @@
|
|||||||
import { ProjectSchema, ResultFile, ResultDir } from '@ali/lowcode-types';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
CodeGeneratorError,
|
|
||||||
ICodeChunk,
|
|
||||||
ICompiledModule,
|
|
||||||
IModuleBuilder,
|
|
||||||
IParseResult,
|
|
||||||
ISchemaParser,
|
|
||||||
PostProcessor,
|
|
||||||
} from '../types';
|
|
||||||
|
|
||||||
import { COMMON_SUB_MODULE_NAME } from '../const/generator';
|
|
||||||
|
|
||||||
import SchemaParser from '../parser/SchemaParser';
|
|
||||||
import ChunkBuilder from './ChunkBuilder';
|
|
||||||
import CodeBuilder from './CodeBuilder';
|
|
||||||
import { createResultFile, createResultDir, addFile } from '../utils/resultHelper';
|
|
||||||
|
|
||||||
export function createModuleBuilder(
|
|
||||||
options: {
|
|
||||||
plugins: BuilderComponentPlugin[];
|
|
||||||
postProcessors: PostProcessor[];
|
|
||||||
mainFileName?: string;
|
|
||||||
} = {
|
|
||||||
plugins: [],
|
|
||||||
postProcessors: [],
|
|
||||||
},
|
|
||||||
): IModuleBuilder {
|
|
||||||
const chunkGenerator = new ChunkBuilder(options.plugins);
|
|
||||||
const linker = new CodeBuilder();
|
|
||||||
|
|
||||||
const generateModule = async (input: unknown): Promise<ICompiledModule> => {
|
|
||||||
const moduleMainName = options.mainFileName || COMMON_SUB_MODULE_NAME;
|
|
||||||
if (chunkGenerator.getPlugins().length <= 0) {
|
|
||||||
throw new CodeGeneratorError('No plugins found. Component generation cannot work without any plugins!');
|
|
||||||
}
|
|
||||||
|
|
||||||
let files: ResultFile[] = [];
|
|
||||||
|
|
||||||
const { chunks } = await chunkGenerator.run(input);
|
|
||||||
chunks.forEach((fileChunkList) => {
|
|
||||||
const content = linker.link(fileChunkList);
|
|
||||||
const file = createResultFile(fileChunkList[0].subModule || moduleMainName, fileChunkList[0].fileType, content);
|
|
||||||
files.push(file);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (options.postProcessors.length > 0) {
|
|
||||||
files = files.map((file) => {
|
|
||||||
let { content } = file;
|
|
||||||
const type = file.ext;
|
|
||||||
options.postProcessors.forEach((processer) => {
|
|
||||||
content = processer(content, type);
|
|
||||||
});
|
|
||||||
|
|
||||||
return createResultFile(file.name, type, content);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
files,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const generateModuleCode = async (schema: ProjectSchema | string): Promise<ResultDir> => {
|
|
||||||
// Init
|
|
||||||
const schemaParser: ISchemaParser = new SchemaParser();
|
|
||||||
const parseResult: IParseResult = schemaParser.parse(schema);
|
|
||||||
|
|
||||||
const containerInfo = parseResult.containers[0];
|
|
||||||
const { files } = await generateModule(containerInfo);
|
|
||||||
|
|
||||||
const dir = createResultDir(containerInfo.moduleName);
|
|
||||||
files.forEach((file) => addFile(dir, file));
|
|
||||||
|
|
||||||
return dir;
|
|
||||||
};
|
|
||||||
|
|
||||||
const linkCodeChunks = (chunks: Record<string, ICodeChunk[]>, fileName: string) => {
|
|
||||||
const files: ResultFile[] = [];
|
|
||||||
|
|
||||||
Object.keys(chunks).forEach((fileKey) => {
|
|
||||||
const fileChunkList = chunks[fileKey];
|
|
||||||
const content = linker.link(fileChunkList);
|
|
||||||
const file = createResultFile(fileChunkList[0].subModule || fileName, fileChunkList[0].fileType, content);
|
|
||||||
files.push(file);
|
|
||||||
});
|
|
||||||
|
|
||||||
return files;
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
generateModule,
|
|
||||||
generateModuleCode,
|
|
||||||
linkCodeChunks,
|
|
||||||
addPlugin: chunkGenerator.addPlugin.bind(chunkGenerator),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,255 +0,0 @@
|
|||||||
import { ResultDir, ResultFile, ProjectSchema } from '@ali/lowcode-types';
|
|
||||||
|
|
||||||
import {
|
|
||||||
IModuleBuilder,
|
|
||||||
IParseResult,
|
|
||||||
IProjectBuilder,
|
|
||||||
IProjectPlugins,
|
|
||||||
IProjectTemplate,
|
|
||||||
ISchemaParser,
|
|
||||||
PostProcessor,
|
|
||||||
} from '../types';
|
|
||||||
|
|
||||||
import SchemaParser from '../parser/SchemaParser';
|
|
||||||
import { createResultDir, addDirectory, addFile } from '../utils/resultHelper';
|
|
||||||
|
|
||||||
import { createModuleBuilder } from '../generator/ModuleBuilder';
|
|
||||||
|
|
||||||
interface IModuleInfo {
|
|
||||||
moduleName?: string;
|
|
||||||
path: string[];
|
|
||||||
files: ResultFile[];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDirFromRoot(root: ResultDir, path: string[]): ResultDir {
|
|
||||||
let current: ResultDir = root;
|
|
||||||
path.forEach((p) => {
|
|
||||||
const exist = current.dirs.find((d) => d.name === p);
|
|
||||||
if (exist) {
|
|
||||||
current = exist;
|
|
||||||
} else {
|
|
||||||
const newDir = createResultDir(p);
|
|
||||||
addDirectory(current, newDir);
|
|
||||||
current = newDir;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ProjectBuilder implements IProjectBuilder {
|
|
||||||
private template: IProjectTemplate;
|
|
||||||
|
|
||||||
private plugins: IProjectPlugins;
|
|
||||||
|
|
||||||
private postProcessors: PostProcessor[];
|
|
||||||
|
|
||||||
constructor({
|
|
||||||
template,
|
|
||||||
plugins,
|
|
||||||
postProcessors,
|
|
||||||
}: {
|
|
||||||
template: IProjectTemplate;
|
|
||||||
plugins: IProjectPlugins;
|
|
||||||
postProcessors: PostProcessor[];
|
|
||||||
}) {
|
|
||||||
this.template = template;
|
|
||||||
this.plugins = plugins;
|
|
||||||
this.postProcessors = postProcessors;
|
|
||||||
}
|
|
||||||
|
|
||||||
async generateProject(schema: ProjectSchema | string): Promise<ResultDir> {
|
|
||||||
// Init
|
|
||||||
const schemaParser: ISchemaParser = new SchemaParser();
|
|
||||||
const builders = this.createModuleBuilders();
|
|
||||||
const projectRoot = this.template.generateTemplate();
|
|
||||||
|
|
||||||
// Validate
|
|
||||||
// Parse / Format
|
|
||||||
|
|
||||||
// Preprocess
|
|
||||||
// Collect Deps
|
|
||||||
// Parse JSExpression
|
|
||||||
const parseResult: IParseResult = schemaParser.parse(schema);
|
|
||||||
let buildResult: IModuleInfo[] = [];
|
|
||||||
|
|
||||||
// Generator Code module
|
|
||||||
// components
|
|
||||||
// pages
|
|
||||||
const containerBuildResult: IModuleInfo[] = await Promise.all<IModuleInfo>(
|
|
||||||
parseResult.containers.map(async (containerInfo) => {
|
|
||||||
let builder: IModuleBuilder;
|
|
||||||
let path: string[];
|
|
||||||
if (containerInfo.containerType === 'Page') {
|
|
||||||
builder = builders.pages;
|
|
||||||
path = this.template.slots.pages.path;
|
|
||||||
} else {
|
|
||||||
builder = builders.components;
|
|
||||||
path = this.template.slots.components.path;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { files } = await builder.generateModule(containerInfo);
|
|
||||||
|
|
||||||
return {
|
|
||||||
moduleName: containerInfo.moduleName,
|
|
||||||
path,
|
|
||||||
files,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
buildResult = buildResult.concat(containerBuildResult);
|
|
||||||
|
|
||||||
// router
|
|
||||||
if (parseResult.globalRouter && builders.router) {
|
|
||||||
const { files } = await builders.router.generateModule(parseResult.globalRouter);
|
|
||||||
|
|
||||||
buildResult.push({
|
|
||||||
path: this.template.slots.router.path,
|
|
||||||
files,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// entry
|
|
||||||
if (parseResult.project && builders.entry) {
|
|
||||||
const { files } = await builders.entry.generateModule(parseResult.project);
|
|
||||||
|
|
||||||
buildResult.push({
|
|
||||||
path: this.template.slots.entry.path,
|
|
||||||
files,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// appConfig
|
|
||||||
if (builders.appConfig) {
|
|
||||||
const { files } = await builders.appConfig.generateModule(parseResult);
|
|
||||||
|
|
||||||
buildResult.push({
|
|
||||||
path: this.template.slots.appConfig.path,
|
|
||||||
files,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildConfig
|
|
||||||
if (builders.buildConfig) {
|
|
||||||
const { files } = await builders.buildConfig.generateModule(parseResult);
|
|
||||||
|
|
||||||
buildResult.push({
|
|
||||||
path: this.template.slots.buildConfig.path,
|
|
||||||
files,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// constants?
|
|
||||||
if (parseResult.project && builders.constants && this.template.slots.constants) {
|
|
||||||
const { files } = await builders.constants.generateModule(parseResult.project);
|
|
||||||
|
|
||||||
buildResult.push({
|
|
||||||
path: this.template.slots.constants.path,
|
|
||||||
files,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// utils?
|
|
||||||
if (parseResult.globalUtils && builders.utils && this.template.slots.utils) {
|
|
||||||
const { files } = await builders.utils.generateModule(parseResult.globalUtils);
|
|
||||||
|
|
||||||
buildResult.push({
|
|
||||||
path: this.template.slots.utils.path,
|
|
||||||
files,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// i18n?
|
|
||||||
if (builders.i18n && this.template.slots.i18n) {
|
|
||||||
const { files } = await builders.i18n.generateModule(parseResult.project);
|
|
||||||
|
|
||||||
buildResult.push({
|
|
||||||
path: this.template.slots.i18n.path,
|
|
||||||
files,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// globalStyle
|
|
||||||
if (parseResult.project && builders.globalStyle) {
|
|
||||||
const { files } = await builders.globalStyle.generateModule(parseResult.project);
|
|
||||||
|
|
||||||
buildResult.push({
|
|
||||||
path: this.template.slots.globalStyle.path,
|
|
||||||
files,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// htmlEntry
|
|
||||||
if (parseResult.project && builders.htmlEntry) {
|
|
||||||
const { files } = await builders.htmlEntry.generateModule(parseResult.project);
|
|
||||||
|
|
||||||
buildResult.push({
|
|
||||||
path: this.template.slots.htmlEntry.path,
|
|
||||||
files,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// packageJSON
|
|
||||||
if (parseResult.project && builders.packageJSON) {
|
|
||||||
const { files } = await builders.packageJSON.generateModule(parseResult.project);
|
|
||||||
|
|
||||||
buildResult.push({
|
|
||||||
path: this.template.slots.packageJSON.path,
|
|
||||||
files,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: 更多 slots 的处理??是不是可以考虑把 template 中所有的 slots 都处理下?
|
|
||||||
|
|
||||||
// Post Process
|
|
||||||
|
|
||||||
// Combine Modules
|
|
||||||
buildResult.forEach((moduleInfo) => {
|
|
||||||
let targetDir = getDirFromRoot(projectRoot, moduleInfo.path);
|
|
||||||
if (moduleInfo.moduleName) {
|
|
||||||
const dir = createResultDir(moduleInfo.moduleName);
|
|
||||||
addDirectory(targetDir, dir);
|
|
||||||
targetDir = dir;
|
|
||||||
}
|
|
||||||
moduleInfo.files.forEach((file) => addFile(targetDir, file));
|
|
||||||
});
|
|
||||||
|
|
||||||
return projectRoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
private createModuleBuilders(): Record<string, IModuleBuilder> {
|
|
||||||
const builders: Record<string, IModuleBuilder> = {};
|
|
||||||
|
|
||||||
Object.keys(this.plugins).forEach((pluginName) => {
|
|
||||||
if (this.plugins[pluginName].length > 0) {
|
|
||||||
const options: { mainFileName?: string } = {};
|
|
||||||
if (this.template.slots[pluginName] && this.template.slots[pluginName].fileName) {
|
|
||||||
options.mainFileName = this.template.slots[pluginName].fileName;
|
|
||||||
}
|
|
||||||
builders[pluginName] = createModuleBuilder({
|
|
||||||
plugins: this.plugins[pluginName],
|
|
||||||
postProcessors: this.postProcessors,
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return builders;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createProjectBuilder({
|
|
||||||
template,
|
|
||||||
plugins,
|
|
||||||
postProcessors,
|
|
||||||
}: {
|
|
||||||
template: IProjectTemplate;
|
|
||||||
plugins: IProjectPlugins;
|
|
||||||
postProcessors: PostProcessor[];
|
|
||||||
}): IProjectBuilder {
|
|
||||||
return new ProjectBuilder({
|
|
||||||
template,
|
|
||||||
plugins,
|
|
||||||
postProcessors,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,111 +0,0 @@
|
|||||||
/**
|
|
||||||
* 低代码引擎的出码模块,负责将编排产出的 Schema 转换成实际可执行的代码。
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
import { createProjectBuilder } from './generator/ProjectBuilder';
|
|
||||||
import { createModuleBuilder } from './generator/ModuleBuilder';
|
|
||||||
import { createDiskPublisher } from './publisher/disk';
|
|
||||||
import { createZipPublisher } from './publisher/zip';
|
|
||||||
import createIceJsProjectBuilder from './solutions/icejs';
|
|
||||||
// import createRecoreProjectBuilder from './solutions/recore';
|
|
||||||
import createRaxAppProjectBuilder from './solutions/rax-app';
|
|
||||||
|
|
||||||
// 引入说明
|
|
||||||
import { REACT_CHUNK_NAME } from './plugins/component/react/const';
|
|
||||||
import { COMMON_CHUNK_NAME, CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from './const/generator';
|
|
||||||
|
|
||||||
// 引入通用插件组
|
|
||||||
import esmodule from './plugins/common/esmodule';
|
|
||||||
import requireUtils from './plugins/common/requireUtils';
|
|
||||||
import containerClass from './plugins/component/react/containerClass';
|
|
||||||
import containerDataSource from './plugins/component/react/containerDataSource';
|
|
||||||
import containerInitState from './plugins/component/react/containerInitState';
|
|
||||||
import containerInjectUtils from './plugins/component/react/containerInjectUtils';
|
|
||||||
import containerLifeCycle from './plugins/component/react/containerLifeCycle';
|
|
||||||
import containerMethod from './plugins/component/react/containerMethod';
|
|
||||||
import jsx from './plugins/component/react/jsx';
|
|
||||||
import reactCommonDeps from './plugins/component/react/reactCommonDeps';
|
|
||||||
import css from './plugins/component/style/css';
|
|
||||||
import constants from './plugins/project/constants';
|
|
||||||
import i18n from './plugins/project/i18n';
|
|
||||||
import utils from './plugins/project/utils';
|
|
||||||
import prettier from './postprocessor/prettier';
|
|
||||||
|
|
||||||
// 引入常用工具
|
|
||||||
import * as utilsCommon from './utils/common';
|
|
||||||
import * as utilsCompositeType from './utils/compositeType';
|
|
||||||
import * as utilsJsExpression from './utils/jsExpression';
|
|
||||||
import * as utilsJsSlot from './utils/jsSlot';
|
|
||||||
import * as utilsNodeToJSX from './utils/nodeToJSX';
|
|
||||||
import * as utilsResultHelper from './utils/resultHelper';
|
|
||||||
import * as utilsTemplateHelper from './utils/templateHelper';
|
|
||||||
import * as utilsValidate from './utils/validate';
|
|
||||||
|
|
||||||
// 引入内置解决方案模块
|
|
||||||
import icejs from './plugins/project/framework/icejs';
|
|
||||||
import rax from './plugins/project/framework/rax';
|
|
||||||
|
|
||||||
export * from './types';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
createProjectBuilder,
|
|
||||||
createModuleBuilder,
|
|
||||||
solutions: {
|
|
||||||
icejs: createIceJsProjectBuilder,
|
|
||||||
// recore: createRecoreProjectBuilder,
|
|
||||||
rax: createRaxAppProjectBuilder,
|
|
||||||
},
|
|
||||||
solutionParts: {
|
|
||||||
icejs,
|
|
||||||
rax,
|
|
||||||
},
|
|
||||||
publishers: {
|
|
||||||
disk: createDiskPublisher,
|
|
||||||
zip: createZipPublisher,
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
common: {
|
|
||||||
esmodule,
|
|
||||||
requireUtils,
|
|
||||||
},
|
|
||||||
react: {
|
|
||||||
containerClass,
|
|
||||||
containerDataSource,
|
|
||||||
containerInitState,
|
|
||||||
containerInjectUtils,
|
|
||||||
containerLifeCycle,
|
|
||||||
containerMethod,
|
|
||||||
jsx,
|
|
||||||
reactCommonDeps,
|
|
||||||
},
|
|
||||||
style: {
|
|
||||||
css,
|
|
||||||
},
|
|
||||||
project: {
|
|
||||||
constants,
|
|
||||||
i18n,
|
|
||||||
utils,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
postprocessor: {
|
|
||||||
prettier,
|
|
||||||
},
|
|
||||||
utils: {
|
|
||||||
common: utilsCommon,
|
|
||||||
compositeType: utilsCompositeType,
|
|
||||||
jsExpression: utilsJsExpression,
|
|
||||||
jsSlot: utilsJsSlot,
|
|
||||||
nodeToJSX: utilsNodeToJSX,
|
|
||||||
resultHelper: utilsResultHelper,
|
|
||||||
templateHelper: utilsTemplateHelper,
|
|
||||||
validate: utilsValidate,
|
|
||||||
},
|
|
||||||
chunkNames: {
|
|
||||||
COMMON_CHUNK_NAME,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME,
|
|
||||||
REACT_CHUNK_NAME,
|
|
||||||
},
|
|
||||||
defaultLinkAfter: {
|
|
||||||
COMMON_DEFAULT_LINK_AFTER: DEFAULT_LINK_AFTER,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@ -1,297 +0,0 @@
|
|||||||
/**
|
|
||||||
* 解析器是对输入的固定格式数据做拆解,使其符合引擎后续步骤预期,完成统一处理逻辑的步骤。
|
|
||||||
* 本解析器面向的是标准 schema 协议。
|
|
||||||
*/
|
|
||||||
import changeCase from 'change-case';
|
|
||||||
import { UtilItem, NodeDataType, NodeSchema, ContainerSchema, ProjectSchema, PropsMap, NodeData } from '@ali/lowcode-types';
|
|
||||||
import { IPageMeta,
|
|
||||||
CodeGeneratorError,
|
|
||||||
CompatibilityError,
|
|
||||||
DependencyType,
|
|
||||||
IContainerInfo,
|
|
||||||
IDependency,
|
|
||||||
IExternalDependency,
|
|
||||||
IInternalDependency,
|
|
||||||
InternalDependencyType,
|
|
||||||
IParseResult,
|
|
||||||
ISchemaParser,
|
|
||||||
INpmPackage,
|
|
||||||
IRouterInfo,
|
|
||||||
} from '../types';
|
|
||||||
|
|
||||||
import { SUPPORT_SCHEMA_VERSION_LIST } from '../const';
|
|
||||||
|
|
||||||
import { handleSubNodes } from '../utils/schema';
|
|
||||||
import { uniqueArray } from '../utils/common';
|
|
||||||
|
|
||||||
|
|
||||||
const defaultContainer: IContainerInfo = {
|
|
||||||
containerType: 'Component',
|
|
||||||
componentName: 'Component',
|
|
||||||
moduleName: 'Index',
|
|
||||||
fileName: 'Index',
|
|
||||||
css: '',
|
|
||||||
props: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
function getRootComponentName(typeName: string, maps: Record<string, IExternalDependency>): string {
|
|
||||||
if (maps[typeName]) {
|
|
||||||
const rec = maps[typeName];
|
|
||||||
const peerName = Object.keys(maps).find((depName: string) => {
|
|
||||||
const depInfo = maps[depName];
|
|
||||||
return depName !== typeName && depInfo.package === rec.package && depInfo.version === rec.version;
|
|
||||||
});
|
|
||||||
return peerName || typeName;
|
|
||||||
}
|
|
||||||
return typeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
function processChildren(schema: NodeSchema): void {
|
|
||||||
if (schema.props) {
|
|
||||||
if (Array.isArray(schema.props)) {
|
|
||||||
// FIXME: is array type props description
|
|
||||||
} else {
|
|
||||||
const nodeProps = schema.props as PropsMap;
|
|
||||||
if (nodeProps.children) {
|
|
||||||
if (!schema.children) {
|
|
||||||
schema.children = nodeProps.children as NodeDataType;
|
|
||||||
} else {
|
|
||||||
let _children: NodeData[] = [];
|
|
||||||
|
|
||||||
if (Array.isArray(schema.children)) {
|
|
||||||
_children = _children.concat(schema.children);
|
|
||||||
} else {
|
|
||||||
_children.push(schema.children);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(nodeProps.children)) {
|
|
||||||
_children = _children.concat(nodeProps.children as NodeData[]);
|
|
||||||
} else {
|
|
||||||
_children.push(nodeProps.children as NodeData);
|
|
||||||
}
|
|
||||||
|
|
||||||
schema.children = _children;
|
|
||||||
}
|
|
||||||
delete nodeProps.children;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SchemaParser implements ISchemaParser {
|
|
||||||
validate(schema: ProjectSchema): boolean {
|
|
||||||
if (SUPPORT_SCHEMA_VERSION_LIST.indexOf(schema.version) < 0) {
|
|
||||||
throw new CompatibilityError(`Not support schema with version [${schema.version}]`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
parse(schemaSrc: ProjectSchema | string): IParseResult {
|
|
||||||
// TODO: collect utils depends in JSExpression
|
|
||||||
const compDeps: Record<string, IExternalDependency> = {};
|
|
||||||
const internalDeps: Record<string, IInternalDependency> = {};
|
|
||||||
let utilsDeps: IExternalDependency[] = [];
|
|
||||||
|
|
||||||
let schema: ProjectSchema;
|
|
||||||
if (typeof schemaSrc === 'string') {
|
|
||||||
try {
|
|
||||||
schema = JSON.parse(schemaSrc);
|
|
||||||
} catch (error) {
|
|
||||||
throw new CodeGeneratorError(`Parse schema failed: ${error.message || 'unknown reason'}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
schema = schemaSrc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解析三方组件依赖
|
|
||||||
schema.componentsMap.forEach((info) => {
|
|
||||||
if (info.componentName) {
|
|
||||||
compDeps[info.componentName] = {
|
|
||||||
...info,
|
|
||||||
dependencyType: DependencyType.External,
|
|
||||||
componentName: info.componentName,
|
|
||||||
exportName: info.exportName ?? info.componentName,
|
|
||||||
version: info.version || '*',
|
|
||||||
destructuring: info.destructuring ?? false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let containers: IContainerInfo[];
|
|
||||||
// Test if this is a lowcode component without container
|
|
||||||
if (schema.componentsTree.length > 0) {
|
|
||||||
const firstRoot: ContainerSchema = schema.componentsTree[0] as ContainerSchema;
|
|
||||||
|
|
||||||
if (!('fileName' in firstRoot) || !firstRoot.fileName) {
|
|
||||||
// 整个 schema 描述一个容器,且无根节点定义
|
|
||||||
const container: IContainerInfo = {
|
|
||||||
...defaultContainer,
|
|
||||||
children: schema.componentsTree as NodeSchema[],
|
|
||||||
};
|
|
||||||
containers = [container];
|
|
||||||
} else {
|
|
||||||
// 普通带 1 到多个容器的 schema
|
|
||||||
containers = schema.componentsTree.map((n) => {
|
|
||||||
const subRoot = n as ContainerSchema;
|
|
||||||
const container: IContainerInfo = {
|
|
||||||
...subRoot,
|
|
||||||
componentName: getRootComponentName(subRoot.componentName, compDeps),
|
|
||||||
containerType: subRoot.componentName,
|
|
||||||
moduleName: changeCase.pascalCase(subRoot.fileName),
|
|
||||||
};
|
|
||||||
return container;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new CodeGeneratorError('Can\'t find anything to generate.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 建立所有容器的内部依赖索引
|
|
||||||
containers.forEach((container) => {
|
|
||||||
let type;
|
|
||||||
switch (container.containerType) {
|
|
||||||
case 'Page':
|
|
||||||
type = InternalDependencyType.PAGE;
|
|
||||||
break;
|
|
||||||
case 'Block':
|
|
||||||
type = InternalDependencyType.BLOCK;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
type = InternalDependencyType.COMPONENT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dep: IInternalDependency = {
|
|
||||||
type,
|
|
||||||
moduleName: container.moduleName,
|
|
||||||
destructuring: false,
|
|
||||||
exportName: container.moduleName,
|
|
||||||
dependencyType: DependencyType.Internal,
|
|
||||||
};
|
|
||||||
|
|
||||||
internalDeps[dep.moduleName] = dep;
|
|
||||||
});
|
|
||||||
|
|
||||||
const containersDeps = ([] as IDependency[]).concat(...containers.map((c) => c.deps || []));
|
|
||||||
// TODO: 不应该在出码部分解决?
|
|
||||||
// 处理 children 写在了 props 里的情况
|
|
||||||
containers.forEach((container) => {
|
|
||||||
if (container.children) {
|
|
||||||
handleSubNodes<void>(
|
|
||||||
container.children,
|
|
||||||
{
|
|
||||||
node: (i: NodeSchema) => processChildren(i),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rerun: true,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 分析容器内部组件依赖
|
|
||||||
containers.forEach((container) => {
|
|
||||||
const depNames = this.getComponentNames(container);
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
container.deps = uniqueArray<string>(depNames, (i: string) => i)
|
|
||||||
.map((depName) => internalDeps[depName] || compDeps[depName])
|
|
||||||
.filter(Boolean);
|
|
||||||
// container.deps = Object.keys(compDeps).map((depName) => compDeps[depName]);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 分析路由配置
|
|
||||||
const routes: IRouterInfo['routes'] = containers
|
|
||||||
.filter((container) => container.containerType === 'Page')
|
|
||||||
.map((page) => {
|
|
||||||
const meta = page.meta;
|
|
||||||
if (meta) {
|
|
||||||
return {
|
|
||||||
path: (meta as IPageMeta).router || `/${page.fileName}`, // 如果无法找到页面路由信息,则用 fileName 做兜底
|
|
||||||
fileName: page.fileName,
|
|
||||||
componentName: page.moduleName,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
path: '',
|
|
||||||
fileName: page.fileName,
|
|
||||||
componentName: page.moduleName,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const routerDeps = routes
|
|
||||||
.map((r) => internalDeps[r.componentName] || compDeps[r.componentName])
|
|
||||||
.filter((dep) => !!dep);
|
|
||||||
|
|
||||||
// 分析 Utils 依赖
|
|
||||||
let utils: UtilItem[];
|
|
||||||
if (schema.utils) {
|
|
||||||
utils = schema.utils;
|
|
||||||
utilsDeps = schema.utils.filter((u) => u.type !== 'function').map((u) => u.content as IExternalDependency);
|
|
||||||
} else {
|
|
||||||
utils = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分析项目 npm 依赖
|
|
||||||
let npms: INpmPackage[] = [];
|
|
||||||
containers.forEach((con) => {
|
|
||||||
const p = (con.deps || [])
|
|
||||||
.map((dep) => {
|
|
||||||
return dep.dependencyType === DependencyType.External ? dep : null;
|
|
||||||
})
|
|
||||||
.filter((dep) => dep !== null);
|
|
||||||
const npmInfos: INpmPackage[] = p
|
|
||||||
.filter(Boolean)
|
|
||||||
.map((i) => ({
|
|
||||||
package: (i as IExternalDependency).package,
|
|
||||||
version: (i as IExternalDependency).version,
|
|
||||||
}));
|
|
||||||
npms.push(...npmInfos);
|
|
||||||
});
|
|
||||||
|
|
||||||
npms.push(...(utilsDeps.map(utilsDep => ({
|
|
||||||
package: utilsDep.package,
|
|
||||||
version: utilsDep.version,
|
|
||||||
}))));
|
|
||||||
|
|
||||||
npms = uniqueArray<INpmPackage>(npms, (i) => i.package).filter(Boolean);
|
|
||||||
|
|
||||||
return {
|
|
||||||
containers,
|
|
||||||
globalUtils: {
|
|
||||||
utils,
|
|
||||||
deps: utilsDeps,
|
|
||||||
},
|
|
||||||
globalI18n: schema.i18n,
|
|
||||||
globalRouter: {
|
|
||||||
routes,
|
|
||||||
deps: routerDeps,
|
|
||||||
},
|
|
||||||
project: {
|
|
||||||
css: schema.css,
|
|
||||||
constants: schema.constants,
|
|
||||||
config: schema.config || {},
|
|
||||||
meta: schema.meta || {},
|
|
||||||
i18n: schema.i18n,
|
|
||||||
containersDeps,
|
|
||||||
utilsDeps,
|
|
||||||
packages: npms || [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
getComponentNames(children: NodeDataType): string[] {
|
|
||||||
return handleSubNodes<string>(
|
|
||||||
children,
|
|
||||||
{
|
|
||||||
node: (i: NodeSchema) => i.componentName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rerun: true,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SchemaParser;
|
|
||||||
@ -1,189 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
CodeGeneratorError,
|
|
||||||
DependencyType,
|
|
||||||
FileType,
|
|
||||||
ICodeChunk,
|
|
||||||
ICodeStruct,
|
|
||||||
IDependency,
|
|
||||||
IExternalDependency,
|
|
||||||
IInternalDependency,
|
|
||||||
IWithDependency,
|
|
||||||
} from '../../types';
|
|
||||||
|
|
||||||
import { isValidIdentifier } from '../../utils/validate';
|
|
||||||
|
|
||||||
function groupDepsByPack(deps: IDependency[]): Record<string, IDependency[]> {
|
|
||||||
const depMap: Record<string, IDependency[]> = {};
|
|
||||||
|
|
||||||
const addDep = (pkg: string, dep: IDependency) => {
|
|
||||||
if (!depMap[pkg]) {
|
|
||||||
depMap[pkg] = [];
|
|
||||||
}
|
|
||||||
depMap[pkg].push(dep);
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: main 这个信息到底怎么用,是不是外部包不需要使用?
|
|
||||||
const depMainBlackList = ['lib', 'lib/index', 'es', 'es/index', 'main'];
|
|
||||||
deps.forEach((dep) => {
|
|
||||||
if (dep.dependencyType === DependencyType.Internal) {
|
|
||||||
addDep(`${(dep as IInternalDependency).moduleName}${dep.main ? `/${dep.main}` : ''}`, dep);
|
|
||||||
} else {
|
|
||||||
let depMain = '';
|
|
||||||
// TODO: 部分类型的 main 暂时认为没用
|
|
||||||
if (dep.main && depMainBlackList.indexOf(dep.main) < 0) {
|
|
||||||
depMain = dep.main;
|
|
||||||
}
|
|
||||||
if (depMain.substring(0, 1) === '/') {
|
|
||||||
depMain = depMain.substring(1);
|
|
||||||
}
|
|
||||||
addDep(`${(dep as IExternalDependency).package}${depMain ? `/${depMain}` : ''}`, dep);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return depMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildPackageImport(
|
|
||||||
pkg: string,
|
|
||||||
deps: IDependency[],
|
|
||||||
targetFileType: string,
|
|
||||||
useAliasName: boolean,
|
|
||||||
): ICodeChunk[] {
|
|
||||||
const chunks: ICodeChunk[] = [];
|
|
||||||
let defaultImport = '';
|
|
||||||
let defaultImportAs = '';
|
|
||||||
const imports: Record<string, string> = {};
|
|
||||||
|
|
||||||
deps.forEach((dep) => {
|
|
||||||
const srcName = dep.exportName;
|
|
||||||
let targetName = dep.componentName || dep.exportName;
|
|
||||||
|
|
||||||
// 如果是子组件,则导出父组件,并且根据自组件命名规则,判断是否需要定义标识符
|
|
||||||
if (dep.subName) {
|
|
||||||
if (targetName !== `${srcName}.${dep.subName}`) {
|
|
||||||
if (!isValidIdentifier(targetName)) {
|
|
||||||
throw new CodeGeneratorError(`Invalid Identifier [${targetName}]`);
|
|
||||||
}
|
|
||||||
|
|
||||||
chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: targetFileType,
|
|
||||||
name: COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
content: `const ${targetName} = ${srcName}.${dep.subName};`,
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport, COMMON_CHUNK_NAME.InternalDepsImport],
|
|
||||||
ext: {
|
|
||||||
originalName: `${srcName}.${dep.subName}`,
|
|
||||||
aliasName: targetName,
|
|
||||||
dependency: dep,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
targetName = srcName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dep.destructuring) {
|
|
||||||
imports[srcName] = targetName;
|
|
||||||
} else if (defaultImport) {
|
|
||||||
throw new CodeGeneratorError(`[${pkg}] has more than one default export.`);
|
|
||||||
} else {
|
|
||||||
defaultImport = srcName;
|
|
||||||
defaultImportAs = targetName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetName !== srcName) {
|
|
||||||
chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: targetFileType,
|
|
||||||
name: COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
content: '',
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport, COMMON_CHUNK_NAME.InternalDepsImport],
|
|
||||||
ext: {
|
|
||||||
originalName: srcName,
|
|
||||||
aliasName: targetName,
|
|
||||||
dependency: dep,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const items = Object.keys(imports).map((src) => {
|
|
||||||
return src === imports[src] || !useAliasName ? src : `${src} as ${imports[src]}`;
|
|
||||||
});
|
|
||||||
|
|
||||||
const statementL = ['import'];
|
|
||||||
if (defaultImport) {
|
|
||||||
statementL.push(useAliasName ? defaultImportAs : defaultImport);
|
|
||||||
if (items.length > 0) {
|
|
||||||
statementL.push(',');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (items.length > 0) {
|
|
||||||
statementL.push(`{ ${items.join(', ')} }`);
|
|
||||||
}
|
|
||||||
statementL.push('from');
|
|
||||||
|
|
||||||
if (deps[0].dependencyType === DependencyType.Internal) {
|
|
||||||
// TODO: Internal Deps path use project slot setting
|
|
||||||
statementL.push(`'@/${(deps[0] as IInternalDependency).type}/${pkg}';`);
|
|
||||||
chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: targetFileType,
|
|
||||||
name: COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
content: statementL.join(' '),
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
statementL.push(`'${pkg}';`);
|
|
||||||
chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: targetFileType,
|
|
||||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
content: statementL.join(' '),
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return chunks;
|
|
||||||
}
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType?: string; // 导出的文件类型
|
|
||||||
useAliasName?: boolean; // 是否使用 componentName 重命名组件 identifier
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?: PluginConfig) => {
|
|
||||||
const cfg = {
|
|
||||||
fileType: FileType.JS,
|
|
||||||
useAliasName: true,
|
|
||||||
...(config || {}),
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IWithDependency;
|
|
||||||
|
|
||||||
if (ir && ir.deps && ir.deps.length > 0) {
|
|
||||||
const packs = groupDepsByPack(ir.deps);
|
|
||||||
|
|
||||||
Object.keys(packs).forEach((pkg) => {
|
|
||||||
const chunks = buildPackageImport(pkg, packs[pkg], cfg.fileType, cfg.useAliasName);
|
|
||||||
next.chunks.push(...chunks);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../const/generator';
|
|
||||||
|
|
||||||
import { BuilderComponentPlugin, BuilderComponentPluginFactory, ChunkType, FileType, ICodeStruct } from '../../types';
|
|
||||||
|
|
||||||
// TODO: How to merge this logic to common deps
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
content: 'import * from \'react\';',
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
content: `
|
|
||||||
// 注意: 出码引擎注入的临时变量默认都以 "__$$" 开头,禁止在搭建的代码中直接访问。
|
|
||||||
// 例外:rax 框架的导出名和各种组件名除外。
|
|
||||||
import { createElement, Component } from 'rax';
|
|
||||||
import { withRouter as __$$withRouter } from 'rax-app';
|
|
||||||
`,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
export const RAX_CHUNK_NAME = {
|
|
||||||
ClassDidMountBegin: 'RaxComponentClassDidMountBegin',
|
|
||||||
ClassDidMountContent: 'RaxComponentClassDidMountContent',
|
|
||||||
ClassDidMountEnd: 'RaxComponentClassDidMountEnd',
|
|
||||||
ClassWillUnmountBegin: 'RaxComponentClassWillUnmountBegin',
|
|
||||||
ClassWillUnmountContent: 'RaxComponentClassWillUnmountContent',
|
|
||||||
ClassWillUnmountEnd: 'RaxComponentClassWillUnmountEnd',
|
|
||||||
ClassRenderBegin: 'RaxComponentClassRenderBegin',
|
|
||||||
ClassRenderPre: 'RaxComponentClassRenderPre',
|
|
||||||
ClassRenderJSX: 'RaxComponentClassRenderJSX',
|
|
||||||
ClassRenderEnd: 'RaxComponentClassRenderEnd',
|
|
||||||
MethodsBegin: 'RaxComponentMethodsBegin',
|
|
||||||
MethodsContent: 'RaxComponentMethodsContent',
|
|
||||||
MethodsEnd: 'RaxComponentMethodsEnd',
|
|
||||||
LifeCyclesBegin: 'RaxComponentLifeCyclesBegin',
|
|
||||||
LifeCyclesContent: 'RaxComponentLifeCyclesContent',
|
|
||||||
LifeCyclesEnd: 'RaxComponentLifeCyclesEnd',
|
|
||||||
};
|
|
||||||
@ -1,144 +0,0 @@
|
|||||||
import changeCase from 'change-case';
|
|
||||||
import { COMMON_CHUNK_NAME, CLASS_DEFINE_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
import { RAX_CHUNK_NAME } from './const';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
|
|
||||||
// 将模块名转换成 PascalCase 的格式,并添加特定后缀,防止命名冲突
|
|
||||||
const componentClassName = `${changeCase.pascalCase(ir.moduleName)}$$Page`;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
content: `class ${componentClassName} extends Component {`,
|
|
||||||
linkAfter: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.End,
|
|
||||||
content: '}',
|
|
||||||
linkAfter: [
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
|
|
||||||
RAX_CHUNK_NAME.ClassRenderEnd,
|
|
||||||
RAX_CHUNK_NAME.MethodsEnd,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
// next.chunks.push({
|
|
||||||
// type: ChunkType.STRING,
|
|
||||||
// fileType: FileType.JSX,
|
|
||||||
// name: CLASS_DEFINE_CHUNK_NAME.ConstructorStart,
|
|
||||||
// content: 'constructor(props, context) { super(props); ',
|
|
||||||
// linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
|
|
||||||
// });
|
|
||||||
|
|
||||||
// next.chunks.push({
|
|
||||||
// type: ChunkType.STRING,
|
|
||||||
// fileType: FileType.JSX,
|
|
||||||
// name: CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
|
|
||||||
// content: '}',
|
|
||||||
// linkAfter: [
|
|
||||||
// CLASS_DEFINE_CHUNK_NAME.ConstructorStart,
|
|
||||||
// CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
|
||||||
// ],
|
|
||||||
// });
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: RAX_CHUNK_NAME.ClassDidMountBegin,
|
|
||||||
content: 'componentDidMount() {',
|
|
||||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start, CLASS_DEFINE_CHUNK_NAME.InsVar, CLASS_DEFINE_CHUNK_NAME.InsMethod],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: RAX_CHUNK_NAME.ClassDidMountEnd,
|
|
||||||
content: '}',
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassDidMountBegin, RAX_CHUNK_NAME.ClassDidMountContent],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: RAX_CHUNK_NAME.ClassWillUnmountBegin,
|
|
||||||
content: 'componentWillUnmount() {',
|
|
||||||
linkAfter: [
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
|
||||||
RAX_CHUNK_NAME.ClassDidMountEnd,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: RAX_CHUNK_NAME.ClassWillUnmountEnd,
|
|
||||||
content: '}',
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassWillUnmountBegin, RAX_CHUNK_NAME.ClassWillUnmountContent],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: RAX_CHUNK_NAME.ClassRenderBegin,
|
|
||||||
content: 'render() {',
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassDidMountEnd, RAX_CHUNK_NAME.ClassWillUnmountEnd],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: RAX_CHUNK_NAME.ClassRenderEnd,
|
|
||||||
content: '}',
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassRenderBegin, RAX_CHUNK_NAME.ClassRenderPre, RAX_CHUNK_NAME.ClassRenderJSX],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: COMMON_CHUNK_NAME.FileExport,
|
|
||||||
content: `export default __$$withRouter(${componentClassName});`,
|
|
||||||
linkAfter: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.End,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
|
||||||
|
|
||||||
import { generateCompositeType } from '../../../utils/compositeType';
|
|
||||||
import Scope from '../../../utils/Scope';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
implementType: 'inConstructor' | 'insMember' | 'hooks';
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
implementType: 'insMember',
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
const scope = Scope.createRootScope();
|
|
||||||
|
|
||||||
const state = ir.state || {};
|
|
||||||
const fields = Object.keys(state).map<string>((stateName) => {
|
|
||||||
// TODO: 这里用什么 handlers?
|
|
||||||
const value = generateCompositeType(state[stateName], scope);
|
|
||||||
return `${stateName}: ${value}`;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (cfg.implementType === 'inConstructor') {
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
|
||||||
content: `this.state = { ${fields.join(',')} };`,
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorContent]],
|
|
||||||
});
|
|
||||||
} else if (cfg.implementType === 'insMember') {
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
content: `state = { ${fields.join(',')} };`,
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsVar]],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// TODO: hooks state??
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME, COMMON_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
} from '../../../types';
|
|
||||||
import { RAX_CHUNK_NAME } from './const';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
content: 'import __$$constants from \'../../constants\';',
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: i18n 是可选的,如果没有 i18n 这个文件怎么办?该怎么判断?
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
content: 'import * as __$$i18n from \'../../i18n\';',
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
content: `
|
|
||||||
_context = this._createContext();
|
|
||||||
`,
|
|
||||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
|
|
||||||
content: `
|
|
||||||
_createContext() {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
// 保存下最新的状态,这样 setState 可以搞成同步一样的了
|
|
||||||
self._latestState = self.state;
|
|
||||||
|
|
||||||
const context = {
|
|
||||||
get state() {
|
|
||||||
// 这里直接获取最新的 state,从而能避免一些 React/Rax 这样的框架因为异步 setState 而导致的一些问题
|
|
||||||
return self._latestState;
|
|
||||||
},
|
|
||||||
setState(newState) {
|
|
||||||
self._latestState = { ...self._latestState, ...newState };
|
|
||||||
self.setState(newState);
|
|
||||||
},
|
|
||||||
get dataSourceMap() {
|
|
||||||
return self._dataSourceEngine.dataSourceMap || {};
|
|
||||||
},
|
|
||||||
async reloadDataSource() {
|
|
||||||
await self._dataSourceEngine.reloadDataSource();
|
|
||||||
},
|
|
||||||
get utils() {
|
|
||||||
return self._utils;
|
|
||||||
},
|
|
||||||
get page() {
|
|
||||||
return context;
|
|
||||||
},
|
|
||||||
get component() {
|
|
||||||
return context;
|
|
||||||
},
|
|
||||||
get props() {
|
|
||||||
return self.props;
|
|
||||||
},
|
|
||||||
get constants() {
|
|
||||||
return __$$constants;
|
|
||||||
},
|
|
||||||
i18n: __$$i18n.i18n,
|
|
||||||
i18nFormat: __$$i18n.i18nFormat,
|
|
||||||
getLocale: __$$i18n.getLocale,
|
|
||||||
setLocale(locale) {
|
|
||||||
__$$i18n.setLocale(locale);
|
|
||||||
self.forceUpdate();
|
|
||||||
},
|
|
||||||
...this._methods,
|
|
||||||
};
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassRenderEnd],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,157 +0,0 @@
|
|||||||
/* eslint-disable @typescript-eslint/indent */
|
|
||||||
|
|
||||||
import { CompositeValue, JSExpression, DataSourceConfig, isJSExpression, isJSFunction } from '@ali/lowcode-types';
|
|
||||||
import changeCase from 'change-case';
|
|
||||||
|
|
||||||
import { CLASS_DEFINE_CHUNK_NAME, COMMON_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
import Scope from '../../../utils/Scope';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IScope,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
import { generateCompositeType } from '../../../utils/compositeType';
|
|
||||||
import { parseExpressionConvertThis2Context } from '../../../utils/expressionParser';
|
|
||||||
import { isContainerSchema } from '../../../utils/schema';
|
|
||||||
import { RAX_CHUNK_NAME } from './const';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const scope = Scope.createRootScope();
|
|
||||||
const dataSourceConfig = isContainerSchema(pre.ir) ? pre.ir.dataSource : null;
|
|
||||||
const dataSourceItems: DataSourceConfig[] = (dataSourceConfig && dataSourceConfig.list) || [];
|
|
||||||
const dataSourceEngineOptions = { runtimeConfig: true };
|
|
||||||
if (dataSourceItems.length > 0) {
|
|
||||||
const requestHandlersMap = {} as Record<string, JSExpression>;
|
|
||||||
|
|
||||||
dataSourceItems.forEach((ds) => {
|
|
||||||
const dsType = ds.type || 'fetch';
|
|
||||||
if (!(dsType in requestHandlersMap) && dsType !== 'custom') {
|
|
||||||
const handlerFactoryName = '__$$create' + changeCase.pascal(dsType) + 'RequestHandler';
|
|
||||||
|
|
||||||
requestHandlersMap[dsType] = {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: handlerFactoryName + (dsType === 'urlParams' ? '(this.props.location.search)' : '()'),
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlerFactoryExportName = `create${changeCase.pascal(dsType)}Handler`;
|
|
||||||
const handlerPkgName = `@ali/lowcode-datasource-${changeCase.kebab(dsType)}-handler`;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
content: `
|
|
||||||
import { ${handlerFactoryExportName} as ${handlerFactoryName} } from '${handlerPkgName}';
|
|
||||||
`,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.assign(dataSourceEngineOptions, { requestHandlersMap });
|
|
||||||
}
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
content: `
|
|
||||||
import { create as __$$createDataSourceEngine } from '@ali/lowcode-datasource-engine/runtime';
|
|
||||||
`,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
content: `
|
|
||||||
_dataSourceConfig = this._defineDataSourceConfig();
|
|
||||||
_dataSourceEngine = __$$createDataSourceEngine(
|
|
||||||
this._dataSourceConfig,
|
|
||||||
this._context,
|
|
||||||
${generateCompositeType(dataSourceEngineOptions, scope)}
|
|
||||||
);`,
|
|
||||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: RAX_CHUNK_NAME.ClassDidMountContent,
|
|
||||||
content: `
|
|
||||||
this._dataSourceEngine.reloadDataSource();
|
|
||||||
`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassDidMountBegin],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
|
|
||||||
content: `
|
|
||||||
_defineDataSourceConfig() {
|
|
||||||
const __$$context = this._context;
|
|
||||||
return (${generateCompositeType(
|
|
||||||
{
|
|
||||||
...dataSourceConfig,
|
|
||||||
list: [
|
|
||||||
...dataSourceItems.map((item) => ({
|
|
||||||
...item,
|
|
||||||
isInit: wrapAsFunction(item.isInit, scope),
|
|
||||||
options: wrapAsFunction(item.options, scope),
|
|
||||||
})),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
scope,
|
|
||||||
{
|
|
||||||
handlers: {
|
|
||||||
function: (jsFunc) => parseExpressionConvertThis2Context(jsFunc.value, '__$$context'),
|
|
||||||
expression: (jsExpr) => parseExpressionConvertThis2Context(jsExpr.value, '__$$context'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)});
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassRenderEnd],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
|
|
||||||
function wrapAsFunction(value: CompositeValue, scope: IScope): CompositeValue {
|
|
||||||
if (isJSExpression(value) || isJSFunction(value)) {
|
|
||||||
return {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: `function(){ return ((${value.value}))}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: `function(){return((${generateCompositeType(value, scope)}))}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME, COMMON_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
} from '../../../types';
|
|
||||||
import { RAX_CHUNK_NAME } from './const';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
// TODO: 下面这个路径有没有更好的方式来获取?而非写死
|
|
||||||
content: `
|
|
||||||
import __$$projectUtils from '../../utils';
|
|
||||||
`,
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
content: '_utils = this._defineUtils();',
|
|
||||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
|
|
||||||
|
|
||||||
// 绑定下上下文,这样在所有的 utils 里面都能通过 this.xxx 来访问上下文了
|
|
||||||
content: `
|
|
||||||
_defineUtils() {
|
|
||||||
const utils = {
|
|
||||||
...__$$projectUtils,
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.entries(utils).forEach(([name, util]) => {
|
|
||||||
if (typeof util === 'function') {
|
|
||||||
utils[name] = util.bind(this._context);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return utils;
|
|
||||||
}`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassRenderEnd],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,120 +0,0 @@
|
|||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
import { CLASS_DEFINE_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
import { RAX_CHUNK_NAME } from './const';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
FileType,
|
|
||||||
ChunkType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
exportNameMapping: Record<string, string>;
|
|
||||||
normalizeNameMapping: Record<string, string>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
exportNameMapping: {},
|
|
||||||
normalizeNameMapping: {},
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Rax 先只支持 didMount 和 willUnmount 吧
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
const lifeCycles = ir.lifeCycles;
|
|
||||||
|
|
||||||
if (lifeCycles && !_.isEmpty(lifeCycles)) {
|
|
||||||
Object.entries(lifeCycles).forEach(([lifeCycleName, lifeCycleMethodExpr]) => {
|
|
||||||
const normalizeName = cfg.normalizeNameMapping[lifeCycleName] || lifeCycleName;
|
|
||||||
const exportName = cfg.exportNameMapping[lifeCycleName] || lifeCycleName;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: RAX_CHUNK_NAME.LifeCyclesContent,
|
|
||||||
content: `${exportName}: (${lifeCycleMethodExpr.value}),`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.LifeCyclesBegin],
|
|
||||||
});
|
|
||||||
|
|
||||||
if (normalizeName === 'didMount') {
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: RAX_CHUNK_NAME.ClassDidMountContent,
|
|
||||||
content: `this._lifeCycles.${exportName}();`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassDidMountBegin],
|
|
||||||
});
|
|
||||||
} else if (normalizeName === 'willUnmount') {
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: RAX_CHUNK_NAME.ClassWillUnmountContent,
|
|
||||||
content: `this._lifeCycles.${exportName}();`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassWillUnmountBegin],
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// TODO: print warnings? Unknown life cycle
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
content: '_lifeCycles = this._defineLifeCycles();',
|
|
||||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: RAX_CHUNK_NAME.LifeCyclesBegin,
|
|
||||||
content: `
|
|
||||||
_defineLifeCycles() {
|
|
||||||
const __$$lifeCycles = ({
|
|
||||||
`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassRenderEnd, CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: RAX_CHUNK_NAME.LifeCyclesEnd,
|
|
||||||
content: `
|
|
||||||
});
|
|
||||||
|
|
||||||
// 为所有的方法绑定上下文
|
|
||||||
Object.entries(__$$lifeCycles).forEach(([lifeCycleName, lifeCycleMethod]) => {
|
|
||||||
if (typeof lifeCycleMethod === 'function') {
|
|
||||||
__$$lifeCycles[lifeCycleName] = (...args) => {
|
|
||||||
return lifeCycleMethod.apply(this._context, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return __$$lifeCycles;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.LifeCyclesBegin, RAX_CHUNK_NAME.LifeCyclesContent],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
import { RAX_CHUNK_NAME } from './const';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
content: `
|
|
||||||
_methods = this._defineMethods();
|
|
||||||
`,
|
|
||||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: RAX_CHUNK_NAME.MethodsBegin,
|
|
||||||
content: `
|
|
||||||
_defineMethods() {
|
|
||||||
const __$$methods = ({
|
|
||||||
`,
|
|
||||||
linkAfter: [
|
|
||||||
RAX_CHUNK_NAME.ClassRenderEnd,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
|
|
||||||
RAX_CHUNK_NAME.LifeCyclesEnd,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: RAX_CHUNK_NAME.MethodsEnd,
|
|
||||||
content: `
|
|
||||||
});
|
|
||||||
|
|
||||||
// 为所有的方法绑定上下文
|
|
||||||
Object.entries(__$$methods).forEach(([methodName, method]) => {
|
|
||||||
if (typeof method === 'function') {
|
|
||||||
__$$methods[methodName] = (...args) => {
|
|
||||||
return method.apply(this._context, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return __$$methods;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.MethodsBegin, RAX_CHUNK_NAME.MethodsContent],
|
|
||||||
});
|
|
||||||
|
|
||||||
if (ir.methods && Object.keys(ir.methods).length > 0) {
|
|
||||||
Object.entries(ir.methods).forEach(([methodName, methodDefine]) => {
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: RAX_CHUNK_NAME.MethodsContent,
|
|
||||||
content: `${methodName}: (${methodDefine.value}),`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.MethodsBegin],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,350 +0,0 @@
|
|||||||
import { NodeSchema, JSExpression, NpmInfo, CompositeValue, isJSExpression } from '@ali/lowcode-types';
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
import changeCase from 'change-case';
|
|
||||||
import { Expression } from '@babel/types';
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
CodePiece,
|
|
||||||
FileType,
|
|
||||||
ICodeChunk,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
PIECE_TYPE,
|
|
||||||
HandlerSet,
|
|
||||||
IScope,
|
|
||||||
NodeGeneratorConfig,
|
|
||||||
NodePlugin,
|
|
||||||
AttrPlugin,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
import { RAX_CHUNK_NAME } from './const';
|
|
||||||
import { COMMON_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
|
|
||||||
import { generateExpression } from '../../../utils/jsExpression';
|
|
||||||
import { createNodeGenerator, generateConditionReactCtrl, generateReactExprInJS } from '../../../utils/nodeToJSX';
|
|
||||||
import { generateCompositeType } from '../../../utils/compositeType';
|
|
||||||
import Scope from '../../../utils/Scope';
|
|
||||||
import {
|
|
||||||
parseExpression,
|
|
||||||
parseExpressionConvertThis2Context,
|
|
||||||
parseExpressionGetGlobalVariables,
|
|
||||||
} from '../../../utils/expressionParser';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: componentName 若并非大写字符打头,甚至并非是一个有效的 JS 标识符怎么办??
|
|
||||||
// FIXME: 我想了下,这块应该放到解析阶段就去做掉,对所有 componentName 做 identifier validate,然后对不合法的做统一替换。
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
const rootScope = Scope.createRootScope();
|
|
||||||
|
|
||||||
// Rax 构建到小程序的时候,不能给组件起起别名,得直接引用,故这里将所有的别名替换掉
|
|
||||||
// 先收集下所有的 alias 的映射
|
|
||||||
const componentsNameAliasMap = new Map<string, string>();
|
|
||||||
next.chunks.forEach((chunk) => {
|
|
||||||
if (isImportAliasDefineChunk(chunk)) {
|
|
||||||
componentsNameAliasMap.set(chunk.ext.aliasName, chunk.ext.originalName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 注意:这里其实隐含了一个假设:schema 中的 componentName 应该是一个有效的 JS 标识符,而且是大写字母打头的
|
|
||||||
// FIXME: 为了快速修复临时加的逻辑,需要用 pre-process 的方式替代处理。
|
|
||||||
const mapComponentNameToAliasOrKeepIt = (componentName: string) => componentsNameAliasMap.get(componentName) || componentName;
|
|
||||||
|
|
||||||
// 然后过滤掉所有的别名 chunks
|
|
||||||
next.chunks = next.chunks.filter((chunk) => !isImportAliasDefineChunk(chunk));
|
|
||||||
|
|
||||||
// 如果直接按目前的 React 的方式之间出码 JSX 的话,会有 3 个问题:
|
|
||||||
// 1. 小程序出码的时候,循环变量没法拿到
|
|
||||||
// 2. 小程序出码的时候,很容易出现 Uncaught TypeError: Cannot read property 'avatar' of undefined 这样的异常(如下图的 50 行) -- 因为若直接出码,Rax 构建到小程序的时候会立即计算所有在视图中用到的变量
|
|
||||||
// 3. 通过 this.xxx 能拿到的东西太多了,而且自定义的 methods 可能会无意间破坏 Rax 框架或小程序框架在页面 this 上的东东
|
|
||||||
const customHandlers: HandlerSet<string> = {
|
|
||||||
expression(input: JSExpression, scope: IScope) {
|
|
||||||
return transformJsExpr(generateExpression(input), scope);
|
|
||||||
},
|
|
||||||
function(input, scope: IScope) {
|
|
||||||
return transformThis2Context(input.value || 'null', scope);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// 创建代码生成器
|
|
||||||
const commonNodeGenerator = createNodeGenerator({
|
|
||||||
handlers: customHandlers,
|
|
||||||
tagMapping: mapComponentNameToAliasOrKeepIt,
|
|
||||||
nodePlugins: [generateReactExprInJS, generateConditionReactCtrl, generateRaxLoopCtrl],
|
|
||||||
attrPlugins: [generateNodeAttrForRax],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 生成 JSX 代码
|
|
||||||
const jsxContent = commonNodeGenerator(ir, rootScope);
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
content: 'import { isMiniApp as __$$isMiniApp } from \'universal-env\';',
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: RAX_CHUNK_NAME.ClassRenderPre,
|
|
||||||
// TODO: setState, dataSourceMap, reloadDataSource, utils, i18n, i18nFormat, getLocale, setLocale 这些在 Rax 的编译模式下不能在视图中直接访问,需要转化成 this.xxx
|
|
||||||
content: `
|
|
||||||
const __$$context = this._context;
|
|
||||||
const { state, setState, dataSourceMap, reloadDataSource, utils, constants, i18n, i18nFormat, getLocale, setLocale } = __$$context;
|
|
||||||
`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassRenderBegin],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: RAX_CHUNK_NAME.ClassRenderJSX,
|
|
||||||
content: `return ${jsxContent};`,
|
|
||||||
linkAfter: [RAX_CHUNK_NAME.ClassRenderBegin, RAX_CHUNK_NAME.ClassRenderPre],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: COMMON_CHUNK_NAME.CustomContent,
|
|
||||||
content: `
|
|
||||||
|
|
||||||
function __$$eval(expr) {
|
|
||||||
try {
|
|
||||||
return expr();
|
|
||||||
} catch (err) {
|
|
||||||
console.warn('Failed to evaluate: ', expr, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function __$$evalArray(expr) {
|
|
||||||
const res = __$$eval(expr);
|
|
||||||
return Array.isArray(res) ? res : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
`,
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.FileExport],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
|
|
||||||
function transformJsExpr(expr: string, scope: IScope) {
|
|
||||||
if (!expr) {
|
|
||||||
return 'undefined';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLiteralAtomicExpr(expr)) {
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const exprAst = parseExpression(expr);
|
|
||||||
|
|
||||||
// 对于下面这些比较安全的字面值,可以直接返回对应的表达式,而非包一层
|
|
||||||
if (isSimpleStraightLiteral(exprAst)) {
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (exprAst.type) {
|
|
||||||
// 对于直接写个函数的,则不用再包下,因为这样不会抛出异常的
|
|
||||||
case 'ArrowFunctionExpression':
|
|
||||||
case 'FunctionExpression':
|
|
||||||
return transformThis2Context(exprAst, scope);
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其他的都需要包一层
|
|
||||||
return `__$$eval(() => (${transformThis2Context(exprAst, scope)}))`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 判断是非是一些简单直接的字面值 */
|
|
||||||
function isSimpleStraightLiteral(expr: Expression): boolean {
|
|
||||||
switch (expr.type) {
|
|
||||||
case 'BigIntLiteral':
|
|
||||||
case 'BooleanLiteral':
|
|
||||||
case 'DecimalLiteral':
|
|
||||||
case 'NullLiteral':
|
|
||||||
case 'NumericLiteral':
|
|
||||||
case 'RegExpLiteral':
|
|
||||||
case 'StringLiteral':
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isImportAliasDefineChunk(
|
|
||||||
chunk: ICodeChunk,
|
|
||||||
): chunk is ICodeChunk & {
|
|
||||||
ext: {
|
|
||||||
aliasName: string;
|
|
||||||
originalName: string;
|
|
||||||
dependency: NpmInfo;
|
|
||||||
};
|
|
||||||
} {
|
|
||||||
return (
|
|
||||||
chunk.name === COMMON_CHUNK_NAME.ImportAliasDefine &&
|
|
||||||
!!chunk.ext &&
|
|
||||||
typeof chunk.ext.aliasName === 'string' &&
|
|
||||||
typeof chunk.ext.originalName === 'string' &&
|
|
||||||
!!(chunk.ext.dependency as NpmInfo | null)?.componentName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否是原子类型的表达式
|
|
||||||
*/
|
|
||||||
function isLiteralAtomicExpr(expr: string): boolean {
|
|
||||||
return expr === 'null' || expr === 'undefined' || expr === 'true' || expr === 'false' || /^-?\d+(\.\d+)?$/.test(expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将所有的 this.xxx 替换为 __$$context.xxx
|
|
||||||
* @param expr
|
|
||||||
*/
|
|
||||||
function transformThis2Context(expr: string | Expression, scope: IScope): string {
|
|
||||||
// 下面这种字符串替换的方式虽然简单直接,但是对于复杂场景会误匹配,故后期改成了解析 AST 然后修改 AST 最后再重新生成代码的方式
|
|
||||||
// return expr
|
|
||||||
// .replace(/\bthis\.item\./g, () => 'item.')
|
|
||||||
// .replace(/\bthis\.index\./g, () => 'index.')
|
|
||||||
// .replace(/\bthis\./g, () => '__$$context.');
|
|
||||||
|
|
||||||
return parseExpressionConvertThis2Context(expr, '__$$context', scope.bindings?.getAllBindings() || []);
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateRaxLoopCtrl(
|
|
||||||
nodeItem: NodeSchema,
|
|
||||||
scope: IScope,
|
|
||||||
config?: NodeGeneratorConfig,
|
|
||||||
next?: NodePlugin,
|
|
||||||
): CodePiece[] {
|
|
||||||
if (nodeItem.loop) {
|
|
||||||
const loopItemName = nodeItem.loopArgs?.[0] || 'item';
|
|
||||||
const loopIndexName = nodeItem.loopArgs?.[1] || 'index';
|
|
||||||
const subScope = scope.createSubScope([loopItemName, loopIndexName]);
|
|
||||||
const pieces: CodePiece[] = next ? next(nodeItem, subScope, config) : [];
|
|
||||||
|
|
||||||
const loopDataExpr = `__$$evalArray(() => (${transformThis2Context(
|
|
||||||
generateCompositeType(nodeItem.loop, scope, { handlers: config?.handlers }),
|
|
||||||
scope,
|
|
||||||
)}))`;
|
|
||||||
|
|
||||||
pieces.unshift({
|
|
||||||
value: `${loopDataExpr}.map((${loopItemName}, ${loopIndexName}) => (`,
|
|
||||||
type: PIECE_TYPE.BEFORE,
|
|
||||||
});
|
|
||||||
|
|
||||||
pieces.push({
|
|
||||||
value: '))',
|
|
||||||
type: PIECE_TYPE.AFTER,
|
|
||||||
});
|
|
||||||
|
|
||||||
return pieces;
|
|
||||||
}
|
|
||||||
|
|
||||||
return next ? next(nodeItem, scope, config) : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateNodeAttrForRax(
|
|
||||||
attrData: { attrName: string; attrValue: CompositeValue },
|
|
||||||
scope: IScope,
|
|
||||||
config?: NodeGeneratorConfig,
|
|
||||||
next?: AttrPlugin,
|
|
||||||
): CodePiece[] {
|
|
||||||
if (!/^on/.test(attrData.attrName)) {
|
|
||||||
return next ? next(attrData, scope, config) : [];
|
|
||||||
}
|
|
||||||
// else: onXxx 的都是事件处理函数需要特殊处理下
|
|
||||||
return generateEventHandlerAttrForRax(attrData.attrName, attrData.attrValue, scope, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateEventHandlerAttrForRax(
|
|
||||||
attrName: string,
|
|
||||||
attrValue: CompositeValue,
|
|
||||||
scope: IScope,
|
|
||||||
config?: NodeGeneratorConfig,
|
|
||||||
): CodePiece[] {
|
|
||||||
// -- 事件处理函数中 JSExpression 转成 JSFunction 来处理,避免当 JSExpression 处理的时候多包一层 eval 而导致 Rax 转码成小程序的时候出问题
|
|
||||||
const valueExpr = generateCompositeType(
|
|
||||||
isJSExpression(attrValue) ? { type: 'JSFunction', value: attrValue.value } : attrValue,
|
|
||||||
scope,
|
|
||||||
{
|
|
||||||
handlers: config?.handlers,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// 查询当前作用域下的变量
|
|
||||||
const currentScopeVariables = scope.bindings?.getAllBindings() || [];
|
|
||||||
if (currentScopeVariables.length <= 0) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
type: PIECE_TYPE.ATTR,
|
|
||||||
name: attrName,
|
|
||||||
value: valueExpr,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提取出所有的未定义的全局变量
|
|
||||||
const undeclaredVariablesInValueExpr = parseExpressionGetGlobalVariables(valueExpr);
|
|
||||||
const referencedLocalVariables = _.intersection(undeclaredVariablesInValueExpr, currentScopeVariables);
|
|
||||||
if (referencedLocalVariables.length <= 0) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
type: PIECE_TYPE.ATTR,
|
|
||||||
name: attrName,
|
|
||||||
value: valueExpr,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
const wrappedAttrValueExpr = [
|
|
||||||
'(...__$$args) => {',
|
|
||||||
' if (__$$isMiniApp) {',
|
|
||||||
' const __$$event = __$$args[0];',
|
|
||||||
...referencedLocalVariables.map((localVar) => `const ${localVar} = __$$event.target.dataset.${localVar};`),
|
|
||||||
` return (${valueExpr}).apply(this, __$$args);`,
|
|
||||||
' } else {',
|
|
||||||
` return (${valueExpr}).apply(this, __$$args);`,
|
|
||||||
' }',
|
|
||||||
'}',
|
|
||||||
].join('\n');
|
|
||||||
|
|
||||||
return [
|
|
||||||
...referencedLocalVariables.map((localVar) => ({
|
|
||||||
type: PIECE_TYPE.ATTR,
|
|
||||||
name: `data-${changeCase.snake(localVar)}`,
|
|
||||||
value: localVar,
|
|
||||||
})),
|
|
||||||
{
|
|
||||||
type: PIECE_TYPE.ATTR,
|
|
||||||
name: attrName,
|
|
||||||
value: wrappedAttrValueExpr,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
export const REACT_CHUNK_NAME = {
|
|
||||||
ClassRenderStart: 'ReactComponentClassRenderStart',
|
|
||||||
ClassRenderPre: 'ReactComponentClassRenderPre',
|
|
||||||
ClassRenderEnd: 'ReactComponentClassRenderEnd',
|
|
||||||
ClassRenderJSX: 'ReactComponentClassRenderJSX',
|
|
||||||
ClassDidMountStart: 'ReactComponentClassDidMountStart',
|
|
||||||
ClassDidMountEnd: 'ReactComponentClassDidMountEnd',
|
|
||||||
ClassDidMountContent: 'ReactComponentClassDidMountContent',
|
|
||||||
};
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
import changeCase from 'change-case';
|
|
||||||
import { COMMON_CHUNK_NAME, CLASS_DEFINE_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
import { REACT_CHUNK_NAME } from './const';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
|
|
||||||
// 将模块名转换成 PascalCase 的格式,并添加特定后缀,防止命名冲突
|
|
||||||
const componentClassName = `${changeCase.pascalCase(ir.moduleName)}$$Page`;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
content: `class ${componentClassName} extends React.Component {`,
|
|
||||||
linkAfter: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.End,
|
|
||||||
content: '}',
|
|
||||||
linkAfter: [
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
REACT_CHUNK_NAME.ClassRenderEnd,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorStart,
|
|
||||||
content: 'constructor(props, context) { super(props); ',
|
|
||||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
|
|
||||||
content: '}',
|
|
||||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.ConstructorStart, CLASS_DEFINE_CHUNK_NAME.ConstructorContent],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: REACT_CHUNK_NAME.ClassRenderStart,
|
|
||||||
content: 'render() {',
|
|
||||||
linkAfter: [
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: REACT_CHUNK_NAME.ClassRenderEnd,
|
|
||||||
content: '}',
|
|
||||||
linkAfter: [REACT_CHUNK_NAME.ClassRenderStart, REACT_CHUNK_NAME.ClassRenderPre, REACT_CHUNK_NAME.ClassRenderJSX],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: COMMON_CHUNK_NAME.FileExport,
|
|
||||||
content: `export default ${componentClassName};`,
|
|
||||||
linkAfter: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.End,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
|
|
||||||
import { generateCompositeType } from '../../../utils/compositeType';
|
|
||||||
import Scope from '../../../utils/Scope';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
|
|
||||||
const scope = Scope.createRootScope();
|
|
||||||
|
|
||||||
if (ir.state) {
|
|
||||||
const { state } = ir;
|
|
||||||
const fields = Object.keys(state).map<string>((stateName) => {
|
|
||||||
const value = generateCompositeType(state[stateName], scope);
|
|
||||||
return `${stateName}: ${value},`;
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
|
||||||
content: `this.state = { ${fields.join('')} };`,
|
|
||||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.ConstructorStart],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
|
||||||
|
|
||||||
import { generateCompositeType } from '../../../utils/compositeType';
|
|
||||||
import Scope from '../../../utils/Scope';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
implementType: 'inConstructor' | 'insMember' | 'hooks';
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
implementType: 'inConstructor',
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
const scope = Scope.createRootScope();
|
|
||||||
|
|
||||||
const state = ir.state || {};
|
|
||||||
const fields = Object.keys(state).map<string>((stateName) => {
|
|
||||||
const value = generateCompositeType(state[stateName], scope);
|
|
||||||
return `${stateName}: ${value},`;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (cfg.implementType === 'inConstructor') {
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
|
||||||
content: `this.state = { ${fields.join('')} };`,
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorContent]],
|
|
||||||
});
|
|
||||||
} else if (cfg.implementType === 'insMember') {
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
content: `state = { ${fields.join('')} };`,
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsVar]],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
|
||||||
content: 'this.utils = utils;',
|
|
||||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.ConstructorStart],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
|
||||||
import { REACT_CHUNK_NAME } from './const';
|
|
||||||
|
|
||||||
import { generateFunction } from '../../../utils/jsExpression';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeChunk,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
exportNameMapping: Record<string, string>;
|
|
||||||
normalizeNameMapping: Record<string, string>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
exportNameMapping: {},
|
|
||||||
normalizeNameMapping: {},
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
|
|
||||||
if (ir.lifeCycles) {
|
|
||||||
const { lifeCycles } = ir;
|
|
||||||
const chunks = Object.keys(lifeCycles).map<ICodeChunk>((lifeCycleName) => {
|
|
||||||
const normalizeName = cfg.normalizeNameMapping[lifeCycleName] || lifeCycleName;
|
|
||||||
const exportName = cfg.exportNameMapping[lifeCycleName] || lifeCycleName;
|
|
||||||
if (normalizeName === 'constructor') {
|
|
||||||
return {
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
|
||||||
content: generateFunction(lifeCycles[lifeCycleName], { isBlock: true }),
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorStart]],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (normalizeName === 'render') {
|
|
||||||
return {
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: REACT_CHUNK_NAME.ClassRenderPre,
|
|
||||||
content: generateFunction(lifeCycles[lifeCycleName], { isBlock: true }),
|
|
||||||
linkAfter: [REACT_CHUNK_NAME.ClassRenderStart],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
|
||||||
content: generateFunction(lifeCycles[lifeCycleName], { name: exportName, isMember: true }),
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push(...chunks);
|
|
||||||
}
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
|
||||||
|
|
||||||
import { generateFunction } from '../../../utils/jsExpression';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeChunk,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
|
|
||||||
if (ir.methods) {
|
|
||||||
const { methods } = ir;
|
|
||||||
const chunks = Object.keys(methods).map<ICodeChunk>((methodName) => ({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
|
||||||
content: generateFunction(methods[methodName], { name: methodName, isMember: true }),
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
|
|
||||||
}));
|
|
||||||
|
|
||||||
next.chunks.push(...chunks);
|
|
||||||
}
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
IScope,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
import { REACT_CHUNK_NAME } from './const';
|
|
||||||
|
|
||||||
import { createReactNodeGenerator } from '../../../utils/nodeToJSX';
|
|
||||||
import Scope from '../../../utils/Scope';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType?: string;
|
|
||||||
nodeTypeMapping?: Record<string, string>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg = {
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
nodeTypeMapping: {},
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const { nodeTypeMapping } = cfg;
|
|
||||||
|
|
||||||
const generator = createReactNodeGenerator({
|
|
||||||
tagMapping: (v) => nodeTypeMapping[v] || v,
|
|
||||||
});
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
const scope: IScope = Scope.createRootScope();
|
|
||||||
const jsxContent = generator(ir, scope);
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: REACT_CHUNK_NAME.ClassRenderJSX,
|
|
||||||
content: `return ${jsxContent};`,
|
|
||||||
linkAfter: [REACT_CHUNK_NAME.ClassRenderStart, REACT_CHUNK_NAME.ClassRenderPre],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
content: 'import React from \'react\';',
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
import { JSExpression, CompositeValue } from '@ali/lowcode-types';
|
|
||||||
|
|
||||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
|
||||||
import Scope from '../../../utils/Scope';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
import { generateCompositeType } from '../../../utils/compositeType';
|
|
||||||
import { generateExpression } from '../../../utils/jsExpression';
|
|
||||||
|
|
||||||
function packJsExpression(exp: unknown): string {
|
|
||||||
const expression = exp as JSExpression;
|
|
||||||
const funcStr = generateExpression(expression);
|
|
||||||
return `function() { return (${funcStr}); }`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
const scope = Scope.createRootScope();
|
|
||||||
|
|
||||||
if (ir.dataSource) {
|
|
||||||
const { dataSource } = ir;
|
|
||||||
const { list, ...rest } = dataSource;
|
|
||||||
|
|
||||||
let attrs: string[] = [];
|
|
||||||
|
|
||||||
const extConfigs = Object.keys(rest).map((extConfigName) => {
|
|
||||||
const value = (rest as Record<string, CompositeValue>)[extConfigName];
|
|
||||||
const valueStr = generateCompositeType(value, scope);
|
|
||||||
return `${extConfigName}: ${valueStr}`;
|
|
||||||
});
|
|
||||||
|
|
||||||
attrs = [...attrs, ...extConfigs];
|
|
||||||
|
|
||||||
const listProp = generateCompositeType((list as unknown) as CompositeValue, scope, {
|
|
||||||
handlers: {
|
|
||||||
expression: packJsExpression,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
attrs.push(`list: ${listProp}`);
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.TS,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
content: `dataSourceOptions = { ${attrs.join(',\n')} };`,
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsVar]],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME, CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.TS,
|
|
||||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
content: 'import { BaseController } from \'@ali/recore-renderer\';',
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.TS,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.Start,
|
|
||||||
content: `class ${ir.moduleName} extends BaseController {`,
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.Start]],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.TS,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.End,
|
|
||||||
content: '}',
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.End]],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.TS,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorStart,
|
|
||||||
content: 'init() {',
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorStart]],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.TS,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
|
|
||||||
content: '}',
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorEnd]],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.TS,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
|
||||||
content: 'globalProps = (window as any)?.g_config?.globalProps || {};',
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsVar]],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.TS,
|
|
||||||
name: COMMON_CHUNK_NAME.FileExport,
|
|
||||||
content: `export default ${ir.moduleName};`,
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[COMMON_CHUNK_NAME.FileExport]],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
ICodeStruct,
|
|
||||||
FileType,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
|
|
||||||
if (ir.css) {
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.TS,
|
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.StaticVar,
|
|
||||||
content: `static cssText = '${ir.css.replace(/'/g, "\\'")}';`,
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.StaticVar]],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
import { NodeSchema } from '@ali/lowcode-types';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
IScope,
|
|
||||||
CodePiece,
|
|
||||||
PIECE_TYPE,
|
|
||||||
} from '../../../types';
|
|
||||||
import { COMMON_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
|
|
||||||
import { createNodeGenerator } from '../../../utils/nodeToJSX';
|
|
||||||
import { generateCompositeType } from '../../../utils/compositeType';
|
|
||||||
import Scope from '../../../utils/Scope';
|
|
||||||
|
|
||||||
const generateGlobalProps = (nodeItem: NodeSchema): CodePiece[] => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
value: `{...globalProps.${nodeItem.componentName}}`,
|
|
||||||
type: PIECE_TYPE.ATTR,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
const generateCtrlLine = (nodeItem: NodeSchema, scope: IScope): CodePiece[] => {
|
|
||||||
const pieces: CodePiece[] = [];
|
|
||||||
|
|
||||||
if (nodeItem.loop && nodeItem.loopArgs) {
|
|
||||||
const loopDataExp = generateCompositeType(nodeItem.loop, scope);
|
|
||||||
pieces.push({
|
|
||||||
type: PIECE_TYPE.ATTR,
|
|
||||||
value: `x-for={${loopDataExp}}`,
|
|
||||||
});
|
|
||||||
|
|
||||||
pieces.push({
|
|
||||||
type: PIECE_TYPE.ATTR,
|
|
||||||
value: `x-each="${nodeItem.loopArgs[0]},${nodeItem.loopArgs[1]}"`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeItem.condition) {
|
|
||||||
const conditionExp = generateCompositeType(nodeItem.condition, scope);
|
|
||||||
pieces.push({
|
|
||||||
type: PIECE_TYPE.ATTR,
|
|
||||||
value: `x-if={${conditionExp}}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return pieces;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const generator = createNodeGenerator({
|
|
||||||
nodePlugins: [generateGlobalProps, generateCtrlLine],
|
|
||||||
});
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
const scope = Scope.createRootScope();
|
|
||||||
|
|
||||||
const vxContent = generator(ir, scope);
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: 'vx',
|
|
||||||
name: COMMON_CHUNK_NAME.CustomContent,
|
|
||||||
content: vxContent,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
|
|
||||||
import { BuilderComponentPlugin, BuilderComponentPluginFactory, ChunkType, ICodeStruct } from '../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: 'vx',
|
|
||||||
name: COMMON_CHUNK_NAME.CustomContent,
|
|
||||||
content: '<div {...globalProps.div} className="recore-loading" x-if={this.__loading} />',
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IContainerInfo,
|
|
||||||
} from '../../../types';
|
|
||||||
|
|
||||||
type PluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
moduleFileType: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
|
||||||
const cfg: PluginConfig = {
|
|
||||||
fileType: FileType.CSS,
|
|
||||||
moduleFileType: FileType.JSX,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IContainerInfo;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: COMMON_CHUNK_NAME.StyleCssContent,
|
|
||||||
content: ir.css,
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.StyleDepsImport],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.moduleFileType,
|
|
||||||
name: COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
content: `import './index.${cfg.fileType}';`,
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../const/generator';
|
|
||||||
import { generateCompositeType } from '../../utils/compositeType';
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IProjectInfo,
|
|
||||||
} from '../../types';
|
|
||||||
import Scope from '../../utils/Scope';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IProjectInfo;
|
|
||||||
const scope = Scope.createRootScope();
|
|
||||||
const constantStr = generateCompositeType(ir.constants || {}, scope);
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JS,
|
|
||||||
name: COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
content: `
|
|
||||||
const __$$constants = (${constantStr});
|
|
||||||
`,
|
|
||||||
linkAfter: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JS,
|
|
||||||
name: COMMON_CHUNK_NAME.FileExport,
|
|
||||||
content: `
|
|
||||||
export default __$$constants;
|
|
||||||
`,
|
|
||||||
linkAfter: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileMainContent,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
import template from './template';
|
|
||||||
import entry from './plugins/entry';
|
|
||||||
import entryHtml from './plugins/entryHtml';
|
|
||||||
import globalStyle from './plugins/globalStyle';
|
|
||||||
import packageJSON from './plugins/packageJSON';
|
|
||||||
import router from './plugins/router';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
template,
|
|
||||||
plugins: {
|
|
||||||
entry,
|
|
||||||
entryHtml,
|
|
||||||
globalStyle,
|
|
||||||
packageJSON,
|
|
||||||
router,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
} from '../../../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JS,
|
|
||||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
content: `
|
|
||||||
import { createApp } from 'ice';
|
|
||||||
`,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JS,
|
|
||||||
name: COMMON_CHUNK_NAME.FileMainContent,
|
|
||||||
content: `
|
|
||||||
const appConfig = {
|
|
||||||
app: {
|
|
||||||
rootId: 'app',
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
type: 'hash',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
createApp(appConfig);
|
|
||||||
`,
|
|
||||||
linkAfter: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IProjectInfo,
|
|
||||||
} from '../../../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IProjectInfo;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.HTML,
|
|
||||||
name: COMMON_CHUNK_NAME.HtmlContent,
|
|
||||||
content: `
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1" />
|
|
||||||
<meta name="viewport" content="width=device-width" />
|
|
||||||
<title>${ir?.meta?.name || 'Ice App'}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IProjectInfo,
|
|
||||||
} from '../../../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IProjectInfo;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.SCSS,
|
|
||||||
name: COMMON_CHUNK_NAME.StyleDepsImport,
|
|
||||||
content: `
|
|
||||||
// 引入默认全局样式
|
|
||||||
@import '@alifd/next/reset.scss';
|
|
||||||
`,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.SCSS,
|
|
||||||
name: COMMON_CHUNK_NAME.StyleCssContent,
|
|
||||||
content: `
|
|
||||||
body {
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.StyleDepsImport],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.SCSS,
|
|
||||||
name: COMMON_CHUNK_NAME.StyleCssContent,
|
|
||||||
content: ir.css || '',
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.StyleDepsImport],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,94 +0,0 @@
|
|||||||
import { PackageJSON } from '@ali/lowcode-types';
|
|
||||||
|
|
||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IProjectInfo,
|
|
||||||
} from '../../../../../types';
|
|
||||||
|
|
||||||
interface IIceJsPackageJSON extends PackageJSON {
|
|
||||||
ideMode: {
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
iceworks: {
|
|
||||||
type: string;
|
|
||||||
adapter: string;
|
|
||||||
};
|
|
||||||
originTemplate: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IProjectInfo;
|
|
||||||
|
|
||||||
const packageJson: IIceJsPackageJSON = {
|
|
||||||
name: '@alifd/scaffold-lite-js',
|
|
||||||
version: '0.1.5',
|
|
||||||
description: '轻量级模板,使用 JavaScript,仅包含基础的 Layout。',
|
|
||||||
dependencies: {
|
|
||||||
moment: '^2.24.0',
|
|
||||||
react: '^16.4.1',
|
|
||||||
'react-dom': '^16.4.1',
|
|
||||||
'@alifd/theme-design-pro': '^0.x',
|
|
||||||
},
|
|
||||||
devDependencies: {
|
|
||||||
'@ice/spec': '^1.0.0',
|
|
||||||
'build-plugin-fusion': '^0.1.0',
|
|
||||||
'build-plugin-moment-locales': '^0.1.0',
|
|
||||||
eslint: '^6.0.1',
|
|
||||||
'ice.js': '^1.0.0',
|
|
||||||
stylelint: '^13.2.0',
|
|
||||||
'@ali/build-plugin-ice-def': '^0.1.0',
|
|
||||||
},
|
|
||||||
scripts: {
|
|
||||||
start: 'icejs start',
|
|
||||||
build: 'icejs build',
|
|
||||||
lint: 'npm run eslint && npm run stylelint',
|
|
||||||
eslint: 'eslint --cache --ext .js,.jsx ./',
|
|
||||||
stylelint: 'stylelint ./**/*.scss',
|
|
||||||
},
|
|
||||||
ideMode: {
|
|
||||||
name: 'ice-react',
|
|
||||||
},
|
|
||||||
iceworks: {
|
|
||||||
type: 'react',
|
|
||||||
adapter: 'adapter-react-v3',
|
|
||||||
},
|
|
||||||
engines: {
|
|
||||||
node: '>=8.0.0',
|
|
||||||
},
|
|
||||||
repository: {
|
|
||||||
type: 'git',
|
|
||||||
url: 'http://gitlab.alibaba-inc.com/msd/leak-scan/tree/master',
|
|
||||||
},
|
|
||||||
private: true,
|
|
||||||
originTemplate: '@alifd/scaffold-lite-js',
|
|
||||||
};
|
|
||||||
|
|
||||||
ir.packages.forEach((packageInfo) => {
|
|
||||||
packageJson.dependencies[packageInfo.package] = packageInfo.version;
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.JSON,
|
|
||||||
fileType: FileType.JSON,
|
|
||||||
name: COMMON_CHUNK_NAME.FileMainContent,
|
|
||||||
content: packageJson,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IRouterInfo,
|
|
||||||
} from '../../../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IRouterInfo;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JS,
|
|
||||||
name: COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
content: `
|
|
||||||
import BasicLayout from '@/layouts/BasicLayout';
|
|
||||||
`,
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JS,
|
|
||||||
name: COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
content: `
|
|
||||||
const routerConfig = [
|
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
component: BasicLayout,
|
|
||||||
children: [
|
|
||||||
${ir.routes
|
|
||||||
.map(
|
|
||||||
(route) => `
|
|
||||||
{
|
|
||||||
path: '${route.path}',
|
|
||||||
component: ${route.componentName},
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
)
|
|
||||||
.join(',')}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
`,
|
|
||||||
linkAfter: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JS,
|
|
||||||
name: COMMON_CHUNK_NAME.FileExport,
|
|
||||||
content: `
|
|
||||||
export default routerConfig;
|
|
||||||
`,
|
|
||||||
linkAfter: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileMainContent,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'README',
|
|
||||||
'md',
|
|
||||||
`
|
|
||||||
## Scaffold Lite
|
|
||||||
|
|
||||||
> 轻量级模板,使用 JavaScript,仅包含基础的 Layout。
|
|
||||||
|
|
||||||
## 使用
|
|
||||||
|
|
||||||
\`\`\`bash
|
|
||||||
# 安装依赖
|
|
||||||
$ npm install
|
|
||||||
|
|
||||||
# 启动服务
|
|
||||||
$ npm start # visit http://localhost:3333
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
[More docs](https://ice.work/docs/guide/about).
|
|
||||||
|
|
||||||
## 目录
|
|
||||||
|
|
||||||
\`\`\`md
|
|
||||||
├── build/ # 构建产物
|
|
||||||
├── mock/ # 本地模拟数据
|
|
||||||
│ ├── index.[j,t]s
|
|
||||||
├── public/
|
|
||||||
│ ├── index.html # 应用入口 HTML
|
|
||||||
│ └── favicon.png # Favicon
|
|
||||||
├── src/ # 源码路径
|
|
||||||
│ ├── components/ # 自定义业务组件
|
|
||||||
│ │ └── Guide/
|
|
||||||
│ │ ├── index.[j,t]sx
|
|
||||||
│ │ ├── index.module.scss
|
|
||||||
│ ├── layouts/ # 布局组件
|
|
||||||
│ │ └── BasicLayout/
|
|
||||||
│ │ ├── index.[j,t]sx
|
|
||||||
│ │ └── index.module.scss
|
|
||||||
│ ├── pages/ # 页面
|
|
||||||
│ │ └── Home/ # home 页面,约定路由转成小写
|
|
||||||
│ │ ├── components/ # 页面级自定义业务组件
|
|
||||||
│ │ ├── models.[j,t]sx # 页面级数据状态
|
|
||||||
│ │ ├── index.[j,t]sx # 页面入口
|
|
||||||
│ │ └── index.module.scss # 页面样式文件
|
|
||||||
│ ├── configs/ # [可选] 配置文件
|
|
||||||
│ │ └── menu.[j,t]s # [可选] 菜单配置
|
|
||||||
│ ├── models/ # [可选] 应用级数据状态
|
|
||||||
│ │ └── user.[j,t]s
|
|
||||||
│ ├── utils/ # [可选] 工具库
|
|
||||||
│ ├── global.scss # 全局样式
|
|
||||||
│ ├── routes.[j,t]s # 路由配置
|
|
||||||
│ └── app.[j,t]s[x] # 应用入口脚本
|
|
||||||
├── build.json # 工程配置
|
|
||||||
├── README.md
|
|
||||||
├── package.json
|
|
||||||
├── .editorconfig
|
|
||||||
├── .eslintignore
|
|
||||||
├── .eslintrc.[j,t]s
|
|
||||||
├── .gitignore
|
|
||||||
├── .stylelintignore
|
|
||||||
├── .stylelintrc.[j,t]s
|
|
||||||
├── .gitignore
|
|
||||||
└── [j,t]sconfig.json
|
|
||||||
\`\`\`
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
return [
|
|
||||||
[],
|
|
||||||
{
|
|
||||||
name: 'abc',
|
|
||||||
ext: 'json',
|
|
||||||
content: `
|
|
||||||
{
|
|
||||||
"type": "ice-app",
|
|
||||||
"builder": "@ali/builder-ice-app"
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
return [
|
|
||||||
[],
|
|
||||||
{
|
|
||||||
name: 'build',
|
|
||||||
ext: 'json',
|
|
||||||
content: `
|
|
||||||
{
|
|
||||||
"entry": "src/app.js",
|
|
||||||
"plugins": [
|
|
||||||
[
|
|
||||||
"build-plugin-fusion",
|
|
||||||
{
|
|
||||||
"themePackage": "@alifd/theme-design-pro"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"build-plugin-moment-locales",
|
|
||||||
{
|
|
||||||
"locales": [
|
|
||||||
"zh-cn"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@ali/build-plugin-ice-def"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.editorconfig',
|
|
||||||
'',
|
|
||||||
`
|
|
||||||
# http://editorconfig.org
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.eslintignore',
|
|
||||||
'',
|
|
||||||
`
|
|
||||||
# 忽略目录
|
|
||||||
build/
|
|
||||||
tests/
|
|
||||||
demo/
|
|
||||||
.ice/
|
|
||||||
|
|
||||||
# node 覆盖率文件
|
|
||||||
coverage/
|
|
||||||
|
|
||||||
# 忽略文件
|
|
||||||
**/*-min.js
|
|
||||||
**/*.min.js
|
|
||||||
|
|
||||||
package-lock.json
|
|
||||||
yarn.lock
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.eslintrc',
|
|
||||||
'js',
|
|
||||||
`
|
|
||||||
const { eslint } = require('@ice/spec');
|
|
||||||
|
|
||||||
module.exports = eslint;
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.gitignore',
|
|
||||||
'',
|
|
||||||
`
|
|
||||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
node_modules/
|
|
||||||
|
|
||||||
# production
|
|
||||||
build/
|
|
||||||
dist/
|
|
||||||
tmp/
|
|
||||||
lib/
|
|
||||||
|
|
||||||
# misc
|
|
||||||
.idea/
|
|
||||||
.happypack
|
|
||||||
.DS_Store
|
|
||||||
*.swp
|
|
||||||
*.dia~
|
|
||||||
.ice
|
|
||||||
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
index.module.scss.d.ts
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'jsconfig',
|
|
||||||
'json',
|
|
||||||
`
|
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": ".",
|
|
||||||
"jsx": "react",
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./src/*"],
|
|
||||||
"ice": [".ice/index.ts"],
|
|
||||||
"ice/*": [".ice/pages/*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.prettierignore',
|
|
||||||
'',
|
|
||||||
`
|
|
||||||
build/
|
|
||||||
tests/
|
|
||||||
demo/
|
|
||||||
.ice/
|
|
||||||
coverage/
|
|
||||||
**/*-min.js
|
|
||||||
**/*.min.js
|
|
||||||
package-lock.json
|
|
||||||
yarn.lock
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.prettierrc',
|
|
||||||
'js',
|
|
||||||
`
|
|
||||||
const { prettier } = require('@ice/spec');
|
|
||||||
|
|
||||||
module.exports = prettier;
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'index',
|
|
||||||
'jsx',
|
|
||||||
`
|
|
||||||
import React from 'react';
|
|
||||||
import styles from './index.module.scss';
|
|
||||||
|
|
||||||
export default function Footer() {
|
|
||||||
return (
|
|
||||||
<p className={styles.footer}>
|
|
||||||
<span className={styles.logo}>Alibaba Fusion</span>
|
|
||||||
<br />
|
|
||||||
<span className={styles.copyright}>© 2019-现在 Alibaba Fusion & ICE</span>
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [['src', 'layouts', 'BasicLayout', 'components', 'Footer'], file];
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'index',
|
|
||||||
'module.scss',
|
|
||||||
`
|
|
||||||
.footer {
|
|
||||||
line-height: 20px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copyright {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [['src', 'layouts', 'BasicLayout', 'components', 'Footer'], file];
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'index',
|
|
||||||
'jsx',
|
|
||||||
`
|
|
||||||
import React from 'react';
|
|
||||||
import { Link } from 'ice';
|
|
||||||
import styles from './index.module.scss';
|
|
||||||
|
|
||||||
export default function Logo({ image, text, url }) {
|
|
||||||
return (
|
|
||||||
<div className="logo">
|
|
||||||
<Link to={url || '/'} className={styles.logo}>
|
|
||||||
{image && <img src={image} alt="logo" />}
|
|
||||||
<span>{text}</span>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [['src', 'layouts', 'BasicLayout', 'components', 'Logo'], file];
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'index',
|
|
||||||
'module.scss',
|
|
||||||
`
|
|
||||||
.logo{
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: $color-text1-1;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 22px;
|
|
||||||
|
|
||||||
&:visited, &:link {
|
|
||||||
color: $color-text1-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
height: 24px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [['src', 'layouts', 'BasicLayout', 'components', 'Logo'], file];
|
|
||||||
}
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'index',
|
|
||||||
'jsx',
|
|
||||||
`
|
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Link, withRouter } from 'ice';
|
|
||||||
import { Nav } from '@alifd/next';
|
|
||||||
import { asideMenuConfig } from '../../menuConfig';
|
|
||||||
|
|
||||||
const { SubNav } = Nav;
|
|
||||||
const NavItem = Nav.Item;
|
|
||||||
|
|
||||||
function getNavMenuItems(menusData) {
|
|
||||||
if (!menusData) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return menusData
|
|
||||||
.filter(item => item.name && !item.hideInMenu)
|
|
||||||
.map((item, index) => getSubMenuOrItem(item, index));
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSubMenuOrItem(item, index) {
|
|
||||||
if (item.children && item.children.some(child => child.name)) {
|
|
||||||
const childrenItems = getNavMenuItems(item.children);
|
|
||||||
|
|
||||||
if (childrenItems && childrenItems.length > 0) {
|
|
||||||
const subNav = (
|
|
||||||
<SubNav key={index} icon={item.icon} label={item.name}>
|
|
||||||
{childrenItems}
|
|
||||||
</SubNav>
|
|
||||||
);
|
|
||||||
return subNav;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const navItem = (
|
|
||||||
<NavItem key={item.path} icon={item.icon}>
|
|
||||||
<Link to={item.path}>{item.name}</Link>
|
|
||||||
</NavItem>
|
|
||||||
);
|
|
||||||
return navItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Navigation = (props, context) => {
|
|
||||||
const { location } = props;
|
|
||||||
const { pathname } = location;
|
|
||||||
const { isCollapse } = context;
|
|
||||||
return (
|
|
||||||
<Nav
|
|
||||||
type="primary"
|
|
||||||
selectedKeys={[pathname]}
|
|
||||||
defaultSelectedKeys={[pathname]}
|
|
||||||
embeddable
|
|
||||||
openMode="single"
|
|
||||||
iconOnly={isCollapse}
|
|
||||||
hasArrow={false}
|
|
||||||
mode={isCollapse ? 'popup' : 'inline'}
|
|
||||||
>
|
|
||||||
{getNavMenuItems(asideMenuConfig)}
|
|
||||||
</Nav>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Navigation.contextTypes = {
|
|
||||||
isCollapse: PropTypes.bool,
|
|
||||||
};
|
|
||||||
const PageNav = withRouter(Navigation);
|
|
||||||
export default PageNav;
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [['src', 'layouts', 'BasicLayout', 'components', 'PageNav'], file];
|
|
||||||
}
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'index',
|
|
||||||
'jsx',
|
|
||||||
`
|
|
||||||
import React, { useState } from 'react';
|
|
||||||
import { Shell, ConfigProvider } from '@alifd/next';
|
|
||||||
import PageNav from './components/PageNav';
|
|
||||||
import Logo from './components/Logo';
|
|
||||||
import Footer from './components/Footer';
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
const throttle = function(type, name, obj = window) {
|
|
||||||
let running = false;
|
|
||||||
|
|
||||||
const func = () => {
|
|
||||||
if (running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
running = true;
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
obj.dispatchEvent(new CustomEvent(name));
|
|
||||||
running = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
obj.addEventListener(type, func);
|
|
||||||
};
|
|
||||||
|
|
||||||
throttle('resize', 'optimizedResize');
|
|
||||||
})();
|
|
||||||
|
|
||||||
export default function BasicLayout({ children }) {
|
|
||||||
const getDevice = width => {
|
|
||||||
const isPhone =
|
|
||||||
typeof navigator !== 'undefined' && navigator && navigator.userAgent.match(/phone/gi);
|
|
||||||
|
|
||||||
if (width < 680 || isPhone) {
|
|
||||||
return 'phone';
|
|
||||||
}
|
|
||||||
if (width < 1280 && width > 680) {
|
|
||||||
return 'tablet';
|
|
||||||
}
|
|
||||||
return 'desktop';
|
|
||||||
};
|
|
||||||
|
|
||||||
const [device, setDevice] = useState(getDevice(NaN));
|
|
||||||
window.addEventListener('optimizedResize', e => {
|
|
||||||
setDevice(getDevice(e && e.target && e.target.innerWidth));
|
|
||||||
});
|
|
||||||
return (
|
|
||||||
<ConfigProvider device={device}>
|
|
||||||
<Shell
|
|
||||||
type="dark"
|
|
||||||
style={{
|
|
||||||
minHeight: '100vh',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Shell.Branding>
|
|
||||||
<Logo
|
|
||||||
image="https://img.alicdn.com/tfs/TB1.ZBecq67gK0jSZFHXXa9jVXa-904-826.png"
|
|
||||||
text="Logo"
|
|
||||||
/>
|
|
||||||
</Shell.Branding>
|
|
||||||
<Shell.Navigation
|
|
||||||
direction="hoz"
|
|
||||||
style={{
|
|
||||||
marginRight: 10,
|
|
||||||
}}
|
|
||||||
></Shell.Navigation>
|
|
||||||
<Shell.Action></Shell.Action>
|
|
||||||
<Shell.Navigation>
|
|
||||||
<PageNav />
|
|
||||||
</Shell.Navigation>
|
|
||||||
|
|
||||||
<Shell.Content>{children}</Shell.Content>
|
|
||||||
<Shell.Footer>
|
|
||||||
<Footer />
|
|
||||||
</Shell.Footer>
|
|
||||||
</Shell>
|
|
||||||
</ConfigProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [['src', 'layouts', 'BasicLayout'], file];
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'menuConfig',
|
|
||||||
'js',
|
|
||||||
`
|
|
||||||
const headerMenuConfig = [];
|
|
||||||
const asideMenuConfig = [
|
|
||||||
{
|
|
||||||
name: 'Dashboard',
|
|
||||||
path: '/',
|
|
||||||
icon: 'smile',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
export { headerMenuConfig, asideMenuConfig };
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [['src', 'layouts', 'BasicLayout'], file];
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.stylelintignore',
|
|
||||||
'',
|
|
||||||
`
|
|
||||||
# 忽略目录
|
|
||||||
build/
|
|
||||||
tests/
|
|
||||||
demo/
|
|
||||||
|
|
||||||
# node 覆盖率文件
|
|
||||||
coverage/
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.stylelintrc',
|
|
||||||
'js',
|
|
||||||
`
|
|
||||||
const { stylelint } = require('@ice/spec');
|
|
||||||
|
|
||||||
module.exports = stylelint;
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'tsconfig',
|
|
||||||
'json',
|
|
||||||
`
|
|
||||||
{
|
|
||||||
"compileOnSave": false,
|
|
||||||
"buildOnSave": false,
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": ".",
|
|
||||||
"outDir": "build",
|
|
||||||
"module": "esnext",
|
|
||||||
"target": "es6",
|
|
||||||
"jsx": "react",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"lib": ["es6", "dom"],
|
|
||||||
"sourceMap": true,
|
|
||||||
"allowJs": true,
|
|
||||||
"rootDir": "./",
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"noImplicitReturns": true,
|
|
||||||
"noImplicitThis": true,
|
|
||||||
"noImplicitAny": false,
|
|
||||||
"importHelpers": true,
|
|
||||||
"strictNullChecks": true,
|
|
||||||
"suppressImplicitAnyIndexErrors": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./src/*"],
|
|
||||||
"ice": [".ice/index.ts"],
|
|
||||||
"ice/*": [".ice/pages/*"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"include": ["src/*", ".ice"],
|
|
||||||
"exclude": ["node_modules", "build", "public"]
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,98 +0,0 @@
|
|||||||
import { ResultDir } from '@ali/lowcode-types';
|
|
||||||
import { IProjectTemplate } from '../../../../../types';
|
|
||||||
|
|
||||||
import { createResultDir } from '../../../../../utils/resultHelper';
|
|
||||||
import { runFileGenerator } from '../../../../../utils/templateHelper';
|
|
||||||
|
|
||||||
import file12 from './files/abc.json';
|
|
||||||
import file11 from './files/build.json';
|
|
||||||
import file10 from './files/editorconfig';
|
|
||||||
import file9 from './files/eslintignore';
|
|
||||||
import file8 from './files/eslintrc.js';
|
|
||||||
import file7 from './files/gitignore';
|
|
||||||
import file6 from './files/jsconfig.json';
|
|
||||||
import file5 from './files/prettierignore';
|
|
||||||
import file4 from './files/prettierrc.js';
|
|
||||||
import file13 from './files/README.md';
|
|
||||||
import file16 from './files/src/layouts/BasicLayout/components/Footer/index.jsx';
|
|
||||||
import file17 from './files/src/layouts/BasicLayout/components/Footer/index.module.scss';
|
|
||||||
import file18 from './files/src/layouts/BasicLayout/components/Logo/index.jsx';
|
|
||||||
import file19 from './files/src/layouts/BasicLayout/components/Logo/index.module.scss';
|
|
||||||
import file20 from './files/src/layouts/BasicLayout/components/PageNav/index.jsx';
|
|
||||||
import file14 from './files/src/layouts/BasicLayout/index.jsx';
|
|
||||||
import file15 from './files/src/layouts/BasicLayout/menuConfig.js';
|
|
||||||
import file3 from './files/stylelintignore';
|
|
||||||
import file2 from './files/stylelintrc.js';
|
|
||||||
import file1 from './files/tsconfig.json';
|
|
||||||
|
|
||||||
const icejsTemplate: IProjectTemplate = {
|
|
||||||
slots: {
|
|
||||||
components: {
|
|
||||||
path: ['src', 'components'],
|
|
||||||
},
|
|
||||||
pages: {
|
|
||||||
path: ['src', 'pages'],
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'routes',
|
|
||||||
},
|
|
||||||
entry: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'app',
|
|
||||||
},
|
|
||||||
constants: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'constants',
|
|
||||||
},
|
|
||||||
utils: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'utils',
|
|
||||||
},
|
|
||||||
i18n: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'i18n',
|
|
||||||
},
|
|
||||||
globalStyle: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'global',
|
|
||||||
},
|
|
||||||
htmlEntry: {
|
|
||||||
path: ['public'],
|
|
||||||
fileName: 'index',
|
|
||||||
},
|
|
||||||
packageJSON: {
|
|
||||||
path: [],
|
|
||||||
fileName: 'package',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
generateTemplate(): ResultDir {
|
|
||||||
const root = createResultDir('.');
|
|
||||||
|
|
||||||
runFileGenerator(root, file1);
|
|
||||||
runFileGenerator(root, file2);
|
|
||||||
runFileGenerator(root, file3);
|
|
||||||
runFileGenerator(root, file4);
|
|
||||||
runFileGenerator(root, file5);
|
|
||||||
runFileGenerator(root, file6);
|
|
||||||
runFileGenerator(root, file7);
|
|
||||||
runFileGenerator(root, file8);
|
|
||||||
runFileGenerator(root, file9);
|
|
||||||
runFileGenerator(root, file10);
|
|
||||||
runFileGenerator(root, file11);
|
|
||||||
runFileGenerator(root, file12);
|
|
||||||
runFileGenerator(root, file13);
|
|
||||||
runFileGenerator(root, file14);
|
|
||||||
runFileGenerator(root, file15);
|
|
||||||
runFileGenerator(root, file16);
|
|
||||||
runFileGenerator(root, file17);
|
|
||||||
runFileGenerator(root, file18);
|
|
||||||
runFileGenerator(root, file19);
|
|
||||||
runFileGenerator(root, file20);
|
|
||||||
|
|
||||||
return root;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default icejsTemplate;
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
import template from './template';
|
|
||||||
import entry from './plugins/entry';
|
|
||||||
import appConfig from './plugins/appConfig';
|
|
||||||
import buildConfig from './plugins/buildConfig';
|
|
||||||
import entryDocument from './plugins/entryDocument';
|
|
||||||
import globalStyle from './plugins/globalStyle';
|
|
||||||
import packageJSON from './plugins/packageJSON';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
template,
|
|
||||||
plugins: {
|
|
||||||
appConfig,
|
|
||||||
buildConfig,
|
|
||||||
entry,
|
|
||||||
entryDocument,
|
|
||||||
globalStyle,
|
|
||||||
packageJSON,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
import changeCase from 'change-case';
|
|
||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IParseResult,
|
|
||||||
} from '../../../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IParseResult;
|
|
||||||
|
|
||||||
const routes = ir.globalRouter?.routes?.map((route) => ({
|
|
||||||
path: route.path,
|
|
||||||
source: `pages/${changeCase.pascalCase(route.fileName)}/index`,
|
|
||||||
})) || [{ path: '/', source: 'pages/Home/index' }];
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSON,
|
|
||||||
name: COMMON_CHUNK_NAME.CustomContent,
|
|
||||||
content: `
|
|
||||||
{
|
|
||||||
"routes": ${JSON.stringify(routes, null, 2)},
|
|
||||||
"window": {
|
|
||||||
"title": ${JSON.stringify(ir.project?.meta?.title || ir.project?.meta?.name || '')}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IParseResult,
|
|
||||||
} from '../../../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IParseResult;
|
|
||||||
// TODO: miniAppBuildType 这个东西是不是不应该在 schema 里面,而是应该由 plugin 的构造参数传入
|
|
||||||
const miniAppBuildType = ir.project?.config?.miniAppBuildType;
|
|
||||||
|
|
||||||
const buildCfg = {
|
|
||||||
inlineStyle: false,
|
|
||||||
plugins: [
|
|
||||||
[
|
|
||||||
'build-plugin-rax-app',
|
|
||||||
{
|
|
||||||
targets: ['web', 'miniapp'],
|
|
||||||
miniapp: miniAppBuildType
|
|
||||||
? {
|
|
||||||
buildType: miniAppBuildType,
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@ali/build-plugin-rax-app-def',
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSON,
|
|
||||||
name: COMMON_CHUNK_NAME.CustomContent,
|
|
||||||
content: JSON.stringify(buildCfg, null, 2) + '\n',
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
} from '../../../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JS,
|
|
||||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
content: `
|
|
||||||
import { runApp } from 'rax-app';
|
|
||||||
import appConfig from './app.json';
|
|
||||||
|
|
||||||
import './global.scss';
|
|
||||||
`,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JS,
|
|
||||||
name: COMMON_CHUNK_NAME.FileMainContent,
|
|
||||||
content: `
|
|
||||||
runApp(appConfig);
|
|
||||||
`,
|
|
||||||
linkAfter: [
|
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.ImportAliasDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileVarDefine,
|
|
||||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IProjectInfo,
|
|
||||||
} from '../../../../../types';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IProjectInfo;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: FileType.JSX,
|
|
||||||
name: COMMON_CHUNK_NAME.CustomContent,
|
|
||||||
content: `
|
|
||||||
import { createElement } from 'rax';
|
|
||||||
import { Root, Style, Script } from 'rax-document';
|
|
||||||
|
|
||||||
function Document() {
|
|
||||||
return (
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta
|
|
||||||
name="viewport"
|
|
||||||
content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,viewport-fit=cover"
|
|
||||||
/>
|
|
||||||
<title>${ir?.meta?.name || 'Rax App'}</title>
|
|
||||||
<Style />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
{/* root container */}
|
|
||||||
<Root />
|
|
||||||
<Script />
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Document;
|
|
||||||
`,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IProjectInfo,
|
|
||||||
} from '../../../../../types';
|
|
||||||
|
|
||||||
export type GlobalStylePluginConfig = {
|
|
||||||
fileType: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<GlobalStylePluginConfig> = (
|
|
||||||
config?: Partial<GlobalStylePluginConfig>,
|
|
||||||
) => {
|
|
||||||
const cfg: GlobalStylePluginConfig = {
|
|
||||||
fileType: FileType.SCSS,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IProjectInfo;
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: COMMON_CHUNK_NAME.StyleDepsImport,
|
|
||||||
content: '',
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: COMMON_CHUNK_NAME.StyleCssContent,
|
|
||||||
content: `
|
|
||||||
body {
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.StyleDepsImport],
|
|
||||||
});
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.STRING,
|
|
||||||
fileType: cfg.fileType,
|
|
||||||
name: COMMON_CHUNK_NAME.StyleCssContent,
|
|
||||||
content: ir.css || '',
|
|
||||||
linkAfter: [COMMON_CHUNK_NAME.StyleDepsImport],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
@ -1,115 +0,0 @@
|
|||||||
import { NpmInfo, PackageJSON } from '@ali/lowcode-types';
|
|
||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
|
||||||
|
|
||||||
import {
|
|
||||||
BuilderComponentPlugin,
|
|
||||||
BuilderComponentPluginFactory,
|
|
||||||
ChunkType,
|
|
||||||
FileType,
|
|
||||||
ICodeStruct,
|
|
||||||
IProjectInfo,
|
|
||||||
} from '../../../../../types';
|
|
||||||
import { isNpmInfo } from '../../../../../utils/schema';
|
|
||||||
import { calcCompatibleVersion } from '../../../../../utils/version';
|
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
||||||
const next: ICodeStruct = {
|
|
||||||
...pre,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ir = next.ir as IProjectInfo;
|
|
||||||
|
|
||||||
const npmDeps = getNpmDependencies(ir);
|
|
||||||
|
|
||||||
const packageJson: PackageJSON = {
|
|
||||||
name: '@ali/rax-app-demo',
|
|
||||||
private: true,
|
|
||||||
version: '1.0.0',
|
|
||||||
scripts: {
|
|
||||||
build: 'build-scripts build',
|
|
||||||
start: 'build-scripts start',
|
|
||||||
lint: 'eslint --ext .js --ext .jsx ./',
|
|
||||||
},
|
|
||||||
dependencies: {
|
|
||||||
'@ali/lowcode-datasource-engine': '*',
|
|
||||||
// TODO: 如何动态获取下面这些依赖?
|
|
||||||
'@ali/lowcode-datasource-url-params-handler': '*',
|
|
||||||
'@ali/lowcode-datasource-fetch-handler': '*',
|
|
||||||
'@ali/lowcode-datasource-mtop-handler': '*',
|
|
||||||
'@ali/lowcode-datasource-mopen-handler': '*',
|
|
||||||
'universal-env': '^3.2.0',
|
|
||||||
'intl-messageformat': '^9.3.6',
|
|
||||||
rax: '^1.1.0',
|
|
||||||
'rax-app': '^2.0.0',
|
|
||||||
'rax-document': '^0.1.0',
|
|
||||||
...npmDeps.reduce(
|
|
||||||
(acc, npm) => ({
|
|
||||||
...acc,
|
|
||||||
[npm.package]: npm.version || '*',
|
|
||||||
}),
|
|
||||||
{} as Record<string, string>,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
devDependencies: {
|
|
||||||
'build-plugin-rax-app': '^5.0.0',
|
|
||||||
'@alib/build-scripts': '^0.1.0',
|
|
||||||
'@typescript-eslint/eslint-plugin': '^2.11.0',
|
|
||||||
'@typescript-eslint/parser': '^2.11.0',
|
|
||||||
'babel-eslint': '^10.0.3',
|
|
||||||
eslint: '^6.8.0',
|
|
||||||
'eslint-config-rax': '^0.1.0',
|
|
||||||
'eslint-plugin-import': '^2.20.0',
|
|
||||||
'eslint-plugin-module': '^0.1.0',
|
|
||||||
'eslint-plugin-react': '^7.18.0',
|
|
||||||
'@ali/build-plugin-rax-app-def': '^1.0.0',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
next.chunks.push({
|
|
||||||
type: ChunkType.JSON,
|
|
||||||
fileType: FileType.JSON,
|
|
||||||
name: COMMON_CHUNK_NAME.FileMainContent,
|
|
||||||
content: packageJson,
|
|
||||||
linkAfter: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default pluginFactory;
|
|
||||||
|
|
||||||
function getNpmDependencies(project: IProjectInfo): NpmInfo[] {
|
|
||||||
const npmDeps: NpmInfo[] = [];
|
|
||||||
const npmNameToPkgMap = new Map<string, NpmInfo>();
|
|
||||||
|
|
||||||
const allDeps = project.packages;
|
|
||||||
|
|
||||||
allDeps.forEach((dep) => {
|
|
||||||
if (!isNpmInfo(dep)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const existing = npmNameToPkgMap.get(dep.package);
|
|
||||||
if (!existing) {
|
|
||||||
npmNameToPkgMap.set(dep.package, dep);
|
|
||||||
npmDeps.push(dep);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existing.version !== dep.version) {
|
|
||||||
try {
|
|
||||||
npmNameToPkgMap.set(dep.package, {
|
|
||||||
...existing,
|
|
||||||
version: calcCompatibleVersion(existing.version, dep.version),
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(`Cannot find compatible version for ${dep.package}. Detail: ${e.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return npmDeps;
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'README',
|
|
||||||
'md',
|
|
||||||
`# @ali/rax-component-demo
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
### \`npm run start\`
|
|
||||||
|
|
||||||
Runs the app in development mode.
|
|
||||||
|
|
||||||
Open [http://localhost:9999](http://localhost:9999) to view it in the browser.
|
|
||||||
|
|
||||||
The page will reload if you make edits.
|
|
||||||
|
|
||||||
### \`npm run build\`
|
|
||||||
|
|
||||||
Builds the app for production to the \`build\` folder.
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'abc',
|
|
||||||
'json',
|
|
||||||
`{
|
|
||||||
"type": "rax",
|
|
||||||
"builder": "@ali/builder-rax-v1",
|
|
||||||
"info": {
|
|
||||||
"raxVersion": "1.x"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'build',
|
|
||||||
'json',
|
|
||||||
`{
|
|
||||||
"inlineStyle": false,
|
|
||||||
"plugins": [
|
|
||||||
[
|
|
||||||
"build-plugin-rax-app",
|
|
||||||
{
|
|
||||||
"targets": ["web", "miniapp"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@ali/build-plugin-rax-app-def"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
|
|
||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.editorconfig',
|
|
||||||
'',
|
|
||||||
`# http://editorconfig.org
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.eslintignore',
|
|
||||||
'',
|
|
||||||
`# 忽略目录
|
|
||||||
build/
|
|
||||||
tests/
|
|
||||||
demo/
|
|
||||||
|
|
||||||
# node 覆盖率文件
|
|
||||||
coverage/
|
|
||||||
|
|
||||||
# 忽略文件
|
|
||||||
**/*-min.js
|
|
||||||
**/*.min.js
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.eslintrc',
|
|
||||||
'js',
|
|
||||||
`module.exports = {
|
|
||||||
extends: ['rax'],
|
|
||||||
};
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.gitignore',
|
|
||||||
'',
|
|
||||||
`# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
|
||||||
|
|
||||||
*~
|
|
||||||
*.swp
|
|
||||||
*.log
|
|
||||||
|
|
||||||
.DS_Store
|
|
||||||
.idea/
|
|
||||||
.temp/
|
|
||||||
|
|
||||||
build/
|
|
||||||
dist/
|
|
||||||
lib/
|
|
||||||
coverage/
|
|
||||||
node_modules/
|
|
||||||
|
|
||||||
template.yml
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
import { ResultDir } from '@ali/lowcode-types';
|
|
||||||
import { IProjectTemplate } from '../../../../../types';
|
|
||||||
|
|
||||||
import { runFileGenerator } from '../../../../../utils/templateHelper';
|
|
||||||
import { createResultDir } from '../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
import file0 from './files/editorconfig';
|
|
||||||
import file1 from './files/eslintignore';
|
|
||||||
import file2 from './files/eslintrc.js';
|
|
||||||
import file3 from './files/gitignore';
|
|
||||||
import file4 from './files/README.md';
|
|
||||||
import file5 from './files/abc.json';
|
|
||||||
|
|
||||||
const raxAppTemplate: IProjectTemplate = {
|
|
||||||
slots: {
|
|
||||||
components: {
|
|
||||||
path: ['src', 'components'],
|
|
||||||
},
|
|
||||||
pages: {
|
|
||||||
path: ['src', 'pages'],
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'router',
|
|
||||||
},
|
|
||||||
entry: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'app',
|
|
||||||
},
|
|
||||||
appConfig: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'app',
|
|
||||||
},
|
|
||||||
buildConfig: {
|
|
||||||
path: [],
|
|
||||||
fileName: 'build',
|
|
||||||
},
|
|
||||||
constants: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'constants',
|
|
||||||
},
|
|
||||||
utils: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'utils',
|
|
||||||
},
|
|
||||||
i18n: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'i18n',
|
|
||||||
},
|
|
||||||
globalStyle: {
|
|
||||||
path: ['src'],
|
|
||||||
fileName: 'global',
|
|
||||||
},
|
|
||||||
htmlEntry: {
|
|
||||||
path: ['src', 'document'],
|
|
||||||
fileName: 'index',
|
|
||||||
},
|
|
||||||
packageJSON: {
|
|
||||||
path: [],
|
|
||||||
fileName: 'package',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
generateTemplate(): ResultDir {
|
|
||||||
const root = createResultDir('.');
|
|
||||||
|
|
||||||
runFileGenerator(root, file0);
|
|
||||||
runFileGenerator(root, file1);
|
|
||||||
runFileGenerator(root, file2);
|
|
||||||
runFileGenerator(root, file3);
|
|
||||||
runFileGenerator(root, file4);
|
|
||||||
runFileGenerator(root, file5);
|
|
||||||
|
|
||||||
return root;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default raxAppTemplate;
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.editorconfig',
|
|
||||||
'',
|
|
||||||
`
|
|
||||||
# EditorConfig is awesome: http://EditorConfig.org
|
|
||||||
|
|
||||||
# top-most EditorConfig file
|
|
||||||
root = true
|
|
||||||
|
|
||||||
# Tab indentation
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
end_of_line = lf
|
|
||||||
indent_size = 2
|
|
||||||
indent_style = space
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
|
|
||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.eslintignore',
|
|
||||||
'',
|
|
||||||
`
|
|
||||||
.idea
|
|
||||||
.vscode
|
|
||||||
.theia
|
|
||||||
.recore
|
|
||||||
build/
|
|
||||||
.*
|
|
||||||
~*
|
|
||||||
node_modules
|
|
||||||
|
|
||||||
packages/solution
|
|
||||||
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.gitignore',
|
|
||||||
'',
|
|
||||||
`
|
|
||||||
node_modules/
|
|
||||||
coverage/
|
|
||||||
build/
|
|
||||||
dist/
|
|
||||||
.idea/
|
|
||||||
.vscode/
|
|
||||||
.theia/
|
|
||||||
.recore/
|
|
||||||
.Trash-*/
|
|
||||||
~*
|
|
||||||
package-lock.json
|
|
||||||
|
|
||||||
# Packages #
|
|
||||||
############
|
|
||||||
# it's better to unpack these files and commit the raw source
|
|
||||||
# git has its own built in compression methods
|
|
||||||
*.7z
|
|
||||||
*.dmg
|
|
||||||
*.gz
|
|
||||||
*.iso
|
|
||||||
*.jar
|
|
||||||
*.rar
|
|
||||||
*.tar
|
|
||||||
*.zip
|
|
||||||
|
|
||||||
# Logs and databases #
|
|
||||||
######################
|
|
||||||
*.log
|
|
||||||
*.sql
|
|
||||||
*.sqlite
|
|
||||||
|
|
||||||
# OS generated files #
|
|
||||||
######################
|
|
||||||
.DS_Store
|
|
||||||
*.swp
|
|
||||||
.DS_Store?
|
|
||||||
._*
|
|
||||||
.Spotlight-V100
|
|
||||||
.Trashes
|
|
||||||
ehthumbs.db
|
|
||||||
Thumbs.db
|
|
||||||
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'.prettierrc',
|
|
||||||
'',
|
|
||||||
`
|
|
||||||
{
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": true,
|
|
||||||
"printWidth": 120,
|
|
||||||
"trailingComma": "all"
|
|
||||||
}
|
|
||||||
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'README',
|
|
||||||
'md',
|
|
||||||
`
|
|
||||||
# runtime-code
|
|
||||||
|
|
||||||
乐高接出码模块测试项目
|
|
||||||
|
|
||||||
|
|
||||||
## 安装运行
|
|
||||||
|
|
||||||
\`\`\`bash
|
|
||||||
# install dependencies
|
|
||||||
tnpm install
|
|
||||||
|
|
||||||
# serve with hot reload at localhost:8080
|
|
||||||
npm start
|
|
||||||
|
|
||||||
# test projects
|
|
||||||
npm test
|
|
||||||
|
|
||||||
# local build
|
|
||||||
npm run build
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'abc',
|
|
||||||
'json',
|
|
||||||
`
|
|
||||||
{
|
|
||||||
"name": "test",
|
|
||||||
"assets": {
|
|
||||||
"type": "command",
|
|
||||||
"command": {
|
|
||||||
"cmd": [
|
|
||||||
"tnpm ii",
|
|
||||||
"tnpm run build"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'build',
|
|
||||||
'json',
|
|
||||||
`
|
|
||||||
{
|
|
||||||
"entry": "src/index",
|
|
||||||
"alias": {
|
|
||||||
"@": "./src"
|
|
||||||
},
|
|
||||||
"publicPath": "./",
|
|
||||||
"outputAssetsPath": {
|
|
||||||
"js": "",
|
|
||||||
"css": ""
|
|
||||||
},
|
|
||||||
"plugins": [
|
|
||||||
"build-plugin-react-app",
|
|
||||||
"@ali/build-plugin-recore-lowcode"
|
|
||||||
],
|
|
||||||
"externals": { "react": "window.React", "react-dom": "window.ReactDOM", "@ali/recore": "window.Recore" }
|
|
||||||
}
|
|
||||||
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'package',
|
|
||||||
'json',
|
|
||||||
`
|
|
||||||
{
|
|
||||||
"name": "test",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "test",
|
|
||||||
"scripts": {
|
|
||||||
"start": "build-scripts start",
|
|
||||||
"build": "build-scripts build",
|
|
||||||
"test": "build-scripts test"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8.9.0",
|
|
||||||
"npm": ">=6.1.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@ali/lowcode-runtime": "^0.8.0",
|
|
||||||
"@ali/recore": "^1.6.10",
|
|
||||||
"@ali/recore-renderer": "^0.0.3",
|
|
||||||
"@ali/vc-block": "^3.0.3-beta.1",
|
|
||||||
"@ali/vc-deep": "1.2.38",
|
|
||||||
"@ali/vc-div": "^1.0.1",
|
|
||||||
"@ali/vc-page": "^1.0.5",
|
|
||||||
"@ali/vc-shell": "1.3.1",
|
|
||||||
"@ali/vc-slot": "^2.0.1",
|
|
||||||
"@ali/vc-text": "^4.0.1",
|
|
||||||
"@ali/vu-dataSource": "^1.0.4",
|
|
||||||
"@ali/vu-formatter": "^2.0.0",
|
|
||||||
"@ali/vu-fusion": "^2.0.1-beta.0",
|
|
||||||
"@ali/vu-legao-builtin": "^1.4.0-beta.2",
|
|
||||||
"@ali/vu-toolkit": "^1.0.5",
|
|
||||||
"react": "^16"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@ali/build-plugin-recore-lowcode": "^0.0.3",
|
|
||||||
"@ali/recore-lowcode-loader": "^0.0.4",
|
|
||||||
"@alib/build-scripts": "^0.1.0",
|
|
||||||
"@types/node": "^7",
|
|
||||||
"@types/react": "^16",
|
|
||||||
"build-plugin-react-app": "^1.0.15",
|
|
||||||
"eslint": "^6.5.1",
|
|
||||||
"prettier": "^1.18.2",
|
|
||||||
"tslib": "^1.9.3",
|
|
||||||
"typescript": "^3.1.3"
|
|
||||||
},
|
|
||||||
"lint-staged": {
|
|
||||||
"./src/**/*.{ts,tsx}": [
|
|
||||||
"tslint --fix",
|
|
||||||
"git add"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[], file];
|
|
||||||
}
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'index',
|
|
||||||
'html',
|
|
||||||
`
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, maximum-scale=1.0, user-scalable=no" />
|
|
||||||
<title>lowcode-runtime-test</title>
|
|
||||||
<link rel="shortcut icon" type="image/png" href="https://img.alicdn.com/tfs/TB1zgoCemrqK1RjSZK9XXXyypXa-96-96.png" />
|
|
||||||
<link rel="stylesheet" id="" href="//g.alicdn.com/legao-comp/csxs/1.0.2/web.css?t=1f">
|
|
||||||
<script
|
|
||||||
src="https://g.alicdn.com/code/lib/??react/16.9.0/umd/react.production.min.js,react-dom/16.9.0/umd/react-dom.production.min.js,prop-types/15.7.2/prop-types.js"></script>
|
|
||||||
<!-- React 非压缩版代码,可根据需要替换或通过代理替换后方便调试 -->
|
|
||||||
<!-- <script src="https://g.alicdn.com/code/lib/??react/16.9.0/umd/react.development.js,react-dom/16.9.0/umd/react-dom.development.js,prop-types/15.7.2/prop-types.js"></script> -->
|
|
||||||
<script src="https://g.alicdn.com/mylib/@ali/recore/1.6.8/umd/recore.min.js"></script>
|
|
||||||
<script>
|
|
||||||
React.PropTypes = PropTypes;
|
|
||||||
</script>
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<script>
|
|
||||||
window.g_config = {
|
|
||||||
appKey: 'test', // 乐高应用的 AppKey
|
|
||||||
// isSectionalRender: true, // 必填,标记当前为局部使用
|
|
||||||
// autoRender: true,
|
|
||||||
// index: 'search_form',
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [['public'], file];
|
|
||||||
}
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
import { ResultFile } from '@ali/lowcode-types';
|
|
||||||
import { createResultFile } from '../../../../../../../../utils/resultHelper';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], ResultFile] {
|
|
||||||
const file = createResultFile(
|
|
||||||
'app',
|
|
||||||
'ts',
|
|
||||||
`
|
|
||||||
export default {
|
|
||||||
"sdkVersion": "1.0.3",
|
|
||||||
"history": "hash", // 浏览器路由:brower 哈希路由:hash
|
|
||||||
"containerId": "app",
|
|
||||||
"layout": {
|
|
||||||
"componentName": "BasicLayout",
|
|
||||||
"props": {
|
|
||||||
"navConfig": {
|
|
||||||
"showLanguageChange": true,
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"navUuid": "FORM-CP5669B1-3AW9DCLHZAY8EIY6WE6X1-GFZM3V1K-6",
|
|
||||||
"children": [],
|
|
||||||
"icon": "",
|
|
||||||
"targetNew": false,
|
|
||||||
"title": "测试基础表格",
|
|
||||||
"inner": true,
|
|
||||||
"relateUuid": "FORM-CP5669B1-3AW9DCLHZAY8EIY6WE6X1-GFZM3V1K-6",
|
|
||||||
"slug": "qihfg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"navUuid": "FORM-CP5669B1-8AW9XCUT4PCH15SMDWUM3-ZPQP3V1K-1",
|
|
||||||
"children": [],
|
|
||||||
"icon": "",
|
|
||||||
"targetNew": false,
|
|
||||||
"title": "测试查询表格",
|
|
||||||
"inner": true,
|
|
||||||
"relateUuid": "zqhej",
|
|
||||||
"slug": "zqhej"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"systemLink": "/my_dev_center_code/0.1.0",
|
|
||||||
"appName": "乐高转码demo",
|
|
||||||
"isFoldHorizontal": "n",
|
|
||||||
"showAppTitle": true,
|
|
||||||
"isFold": "n",
|
|
||||||
"searchBarType": "icon",
|
|
||||||
"singletons": {},
|
|
||||||
"navTheme": "default",
|
|
||||||
"type": "top_side_fold",
|
|
||||||
"navStyle": "orange",
|
|
||||||
"layout": "auto",
|
|
||||||
"bgColor": "white",
|
|
||||||
"languageChangeUrl": "/common/account/changeAccountLanguage.json",
|
|
||||||
"showSearch": "n",
|
|
||||||
"openSubMode": false,
|
|
||||||
"showCrumb": true,
|
|
||||||
"isFixed": "y",
|
|
||||||
"showIcon": false,
|
|
||||||
"showNav": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"theme": {
|
|
||||||
"package": "@alife/theme-fusion",
|
|
||||||
"version": "^0.1.0"
|
|
||||||
},
|
|
||||||
"compDependencies": []
|
|
||||||
}
|
|
||||||
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return [['src', 'config'], file];
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user