- Notifications
You must be signed in to change notification settings - Fork 434
feat: introduce react-generator plugin #1593
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
hexqi merged 22 commits into opentiny:ospp-2025/source-to-dsl from zjy2414:source-to-dsl/react-generator Oct 31, 2025
Merged
Changes from 3 commits
Commits
Show all changes
22 commits Select commit Hold shift + click to select a range
59cd281 feat: add react generator
zjy2414 aaf2d77 test: add tests for react components
zjy2414 0161b01 fix: update prettier configuration for jsxSingleQuote and arrowParens
zjy2414 61027c1 fix: 修改生成React代码的方法,将类组件风格的引用替换为函数组件风格
zjy2414 f3d307f test: 修改generator中的mockData中的函数方法
zjy2414 d9da612 docs: 将README中的npm命令替换为pnpm命令
zjy2414 6e9e664 docs: 移除README中的冗余测试命令
zjy2414 67b73d8 docs: 更新README
zjy2414 bb16fd1 docs: 更新README
zjy2414 734ea43 fix: 更新依赖版本以确保兼容性
zjy2414 722428d test: 调整预期结果依赖项顺序
zjy2414 a7e086b fix: 调整依赖项
zjy2414 0d6fe0a fix: 修复脚本和样式配置更新
zjy2414 c00dcc5 fix: 修复upperCase文件命名和导入路径错误
zjy2414 dd8aaa9 fix: 修复parseImport函数中的componentType为componentName的错误
zjy2414 8cef74d fix: 修复块导入路径后缀为.vue的错误,改为.jsx
zjy2414 a396b99 fix: 内联处理JSX子元素;优化路径导入逻辑
zjy2414 3bd3a9b fix: 更新代码和文档以支持JSExpression的双向数据绑定,移除JSDataBinding相关内容
zjy2414 c398434 test: 更新测试用例,覆盖双向绑定场景
zjy2414 471c051 fix: 添加对__dirname的手动计算以支持ESM环境
zjy2414 cb9c24e feat: 更新生命周期处理逻辑,支持Vue3钩子映射到React生命周期
zjy2414 473de35 test: 更新生命周期钩子名称符合DSL规范
zjy2414 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| /** | ||
| * Minimal ESLint config for tests to lint generated JSX without errors. | ||
| */ | ||
| module.exports = { | ||
| root: true, | ||
| env: { | ||
| browser: true, | ||
| es2021: true, | ||
| node: true, | ||
| }, | ||
| parserOptions: { | ||
| ecmaVersion: 'latest', | ||
| sourceType: 'module', | ||
| ecmaFeatures: { jsx: true }, | ||
| }, | ||
| // No rules enabled by default; this is only to ensure parsing succeeds. | ||
| rules: {}, | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| output/ | ||
| result/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,334 @@ | ||
| # @opentiny/tiny-engine-dsl-react | ||
| | ||
| [](https://www.npmjs.com/package/@opentiny/tiny-engine-dsl-react) | ||
| [](https://opensource.org/licenses/MIT) | ||
| | ||
| 一个DSL到React代码生成器,支持将TinyEngine设计器的DSL schema转换为可运行的React应用代码。 | ||
| | ||
| ## ✨ 特性 | ||
| | ||
| - 🚀 **完整的React应用生成** - 支持生成完整的React应用,包括页面、组件、路由等 | ||
| - 🔄 **数据双向绑定** - 支持JSDataBinding和JSExpression的双向数据绑定 | ||
| - ⚡ **生命周期管理** - 自动转换React组件生命周期方法 | ||
| - 🎨 **代码格式化** - 集成Prettier,自动格式化生成的代码 | ||
| - 🔌 **插件化架构** - 支持自定义插件扩展功能 | ||
| - 🌍 **国际化支持** - 内置i18n国际化功能 | ||
| - 📦 **依赖管理** - 自动处理组件依赖和包管理 | ||
| - 🎯 **类型安全** - 提供完整的TypeScript类型定义 | ||
| | ||
| ## 📦 安装 | ||
| | ||
| ```bash | ||
| npm install @opentiny/tiny-engine-dsl-react | ||
| ``` | ||
| | ||
| ## 🚀 快速开始 | ||
| | ||
| ### 基础使用 | ||
| | ||
| ```javascript | ||
| import { generateApp } from '@opentiny/tiny-engine-dsl-react' | ||
| | ||
| // 创建代码生成器实例 | ||
| const generator = generateApp() | ||
| | ||
| // 生成React应用代码 | ||
| const result = generator.generate(schema) | ||
| console.log(result) | ||
| ``` | ||
| | ||
| ### 生成完整应用 | ||
| | ||
| ```javascript | ||
| import { generateApp } from '@opentiny/tiny-engine-dsl-react' | ||
| | ||
| const generator = generateApp({ | ||
| pluginConfig: { | ||
| // 自定义配置 | ||
| formatCode: { | ||
| enableFormat: true, | ||
| printWidth: 100 | ||
| } | ||
| } | ||
| }) | ||
| | ||
| // 生成完整的React应用 | ||
| const appCode = generator.generate(schema) | ||
| ``` | ||
| | ||
| ## 📚 核心功能 | ||
| | ||
| ### 1. 数据双向绑定 | ||
| | ||
| 支持将DSL中的`JSDataBinding`和带有`model`属性的`JSExpression`转换为React的`useState`和事件处理逻辑。 | ||
| | ||
| #### 使用示例 | ||
| | ||
| ```javascript | ||
| // DSL Schema | ||
| { | ||
| "componentName": "TinyInput", | ||
| "props": { | ||
| "value": { | ||
| "type": "JSDataBinding", | ||
| "value": "this.state.username" | ||
| } | ||
| } | ||
| } | ||
| | ||
| // 生成的React代码 | ||
| const [state, setState] = useState({ username: '' }) | ||
| | ||
| <TinyInput | ||
| value={state.username} | ||
| onChange={e => setState(prev => ({ ...prev, username: e.target.value }))} | ||
| /> | ||
| ``` | ||
| | ||
| #### 嵌套对象绑定 | ||
| | ||
| ```javascript | ||
| // DSL Schema | ||
| { | ||
| "componentName": "TinyInput", | ||
| "props": { | ||
| "value": { | ||
| "type": "JSDataBinding", | ||
| "value": "this.state.userInfo.name" | ||
| } | ||
| } | ||
| } | ||
| | ||
| // 生成的React代码 | ||
| <TinyInput | ||
| value={state.userInfo.name} | ||
| onChange={e => setState(prev => ({ | ||
| ...prev, | ||
| userInfo: { ...prev.userInfo, name: e.target.value } | ||
| }))} | ||
| /> | ||
| ``` | ||
| | ||
| ### 2. 生命周期管理 | ||
| | ||
| 自动转换React组件的生命周期方法。 | ||
| | ||
| #### 支持的生命周期 | ||
| | ||
| - `componentDidMount` - 组件挂载后 | ||
hexqi marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| - `componentWillUnmount` - 组件卸载前 | ||
| - `componentDidUpdate` - 组件更新后 | ||
| - `componentDidCatch` - 错误边界捕获 | ||
| - `componentWillMount` - 组件挂载前 | ||
| - `shouldComponentUpdate` - 控制组件更新 | ||
| | ||
| #### 使用示例 | ||
| | ||
zjy2414 marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| ```javascript | ||
| // DSL Schema | ||
| { | ||
| "lifeCycles": { | ||
| "componentDidMount": { | ||
| "type": "JSFunction", | ||
| "value": "function componentDidMount() { console.log('Component mounted') }" | ||
| }, | ||
| "componentWillUnmount": { | ||
| "type": "JSFunction", | ||
| "value": "function componentWillUnmount() { console.log('Component unmounted') }" | ||
| } | ||
| } | ||
| } | ||
| | ||
| // 生成的React代码 | ||
| class MyComponent extends React.Component { | ||
| componentDidMount() { | ||
| console.log('Component mounted') | ||
| } | ||
| | ||
| componentWillUnmount() { | ||
| console.log('Component unmounted') | ||
| } | ||
| | ||
| render() { | ||
| return <div>Hello World</div> | ||
| } | ||
| } | ||
| ``` | ||
| | ||
| ### 3. 代码格式化 | ||
| | ||
| 集成Prettier,自动格式化生成的代码。 | ||
| | ||
| #### 配置选项 | ||
| | ||
| ```javascript | ||
| const generator = generateApp({ | ||
| pluginConfig: { | ||
| formatCode: { | ||
| // Prettier 配置 | ||
| printWidth: 100, | ||
| tabWidth: 2, | ||
| semi: true, | ||
| singleQuote: true, | ||
| | ||
| // 插件配置 | ||
| enableFormat: true, | ||
| skipFiles: ['txt', 'log'], | ||
| onlyFiles: ['js', 'jsx', 'ts', 'tsx'], | ||
| logFormatResult: true | ||
| } | ||
| } | ||
| }) | ||
| ``` | ||
| | ||
| #### 禁用格式化 | ||
| | ||
| ```javascript | ||
| const generator = generateApp({ | ||
| pluginConfig: { | ||
| formatCode: { | ||
| enableFormat: false | ||
| } | ||
| } | ||
| }) | ||
| ``` | ||
| | ||
| ### 4. 插件系统 | ||
| | ||
| 支持自定义插件扩展功能。 | ||
| | ||
| #### 内置插件 | ||
| | ||
| - **template** - 模板生成插件 | ||
| - **block** - 区块生成插件 | ||
| - **page** - 页面生成插件 | ||
| - **dataSource** - 数据源插件 | ||
| - **dependencies** - 依赖管理插件 | ||
| - **i18n** - 国际化插件 | ||
| - **router** - 路由插件 | ||
| - **utils** - 工具函数插件 | ||
| - **globalState** - 全局状态插件 | ||
| - **formatCode** - 代码格式化插件 | ||
| - **parseSchema** - Schema解析插件 | ||
| | ||
| #### 自定义插件 | ||
| | ||
| ```javascript | ||
| const customPlugin = { | ||
| name: 'customPlugin', | ||
| transform: (schema, context) => { | ||
| // 自定义转换逻辑 | ||
| return schema | ||
| } | ||
| } | ||
| | ||
| const generator = generateApp({ | ||
| customPlugins: { | ||
| transform: [customPlugin] | ||
| } | ||
| }) | ||
| ``` | ||
| | ||
| ## 🔧 API 参考 | ||
| | ||
| ### generateApp(config) | ||
| | ||
| 创建代码生成器实例。 | ||
| | ||
| #### 参数 | ||
| | ||
| - `config` (Object) - 配置对象 | ||
| - `pluginConfig` (Object) - 插件配置 | ||
| - `customPlugins` (Object) - 自定义插件 | ||
| - `customContext` (Object) - 自定义上下文 | ||
| | ||
| #### 返回值 | ||
| | ||
| 返回代码生成器实例,包含以下方法: | ||
| | ||
| - `generate(schema)` - 生成代码 | ||
| - `generatePage(schema)` - 生成页面代码 | ||
| - `generateBlock(schema)` - 生成区块代码 | ||
| | ||
| ### CodeGenerator | ||
| | ||
| 代码生成器类。 | ||
| | ||
| ```javascript | ||
| import { CodeGenerator } from '@opentiny/tiny-engine-dsl-react' | ||
| | ||
| const generator = new CodeGenerator({ | ||
| plugins: { | ||
| transformStart: [], | ||
| transform: [], | ||
| transformEnd: [] | ||
| }, | ||
| context: {} | ||
| }) | ||
| ``` | ||
| | ||
| ### 开发环境 | ||
| | ||
| ```bash | ||
| # 安装依赖 | ||
| pnpm install | ||
| ``` | ||
| | ||
| ## 🧪 测试 | ||
| | ||
| ### 运行测试 | ||
| | ||
| ```bash | ||
| # 运行所有测试 | ||
| npm test | ||
| | ||
| # 运行特定测试 | ||
| npm test test/data-binding | ||
| npm test test/lifecycle | ||
| npm test test/formatCode | ||
| | ||
| # 运行完整测试套件 | ||
| npm run test:latest | ||
| ``` | ||
| | ||
| ### 测试用例 | ||
| | ||
| - **data-binding** - 数据双向绑定功能测试 | ||
| - **lifecycle** - 生命周期功能测试 | ||
| - **formatCode** - 代码格式化功能测试 | ||
| - **generator** - 代码生成器核心功能测试 | ||
| - **unit** - 单元测试 | ||
| | ||
| ## 📁 项目结构 | ||
| | ||
| ``` | ||
| src/ | ||
| ├── generator/ # 代码生成器核心 | ||
| │ ├── codeGenerator.js | ||
| │ ├── generateApp.js | ||
| │ ├── generateJsx.js | ||
| │ ├── page.js | ||
| │ └── parseImport.js | ||
| ├── plugins/ # 插件系统 | ||
| │ ├── formatCodePlugin.js | ||
| │ ├── genBlockPlugin.js | ||
| │ ├── genPagePlugin.js | ||
| │ └── ... | ||
| ├── templates/ # 代码模板 | ||
| │ └── react-template/ | ||
| ├── parser/ # DSL解析器 | ||
| ├── pre-processor/ # 预处理器 | ||
| ├── utils/ # 工具函数 | ||
| └── constant/ # 常量定义 | ||
| ``` | ||
| | ||
| ## 🎯 设计理念 | ||
| | ||
| ### 代码生成架构 | ||
| | ||
| ``` | ||
| ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ | ||
| │ Plugin │ │ Template │ │ Parser │ │ Generator │ | ||
| │ 插件系统 │───▶│ 模板系统 │───▶│ 解析器 │───▶│ 代码生成器 │ | ||
| └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "compilerOptions": { | ||
| "baseUrl": "./", | ||
| "target": "ES6", | ||
| "module": "CommonJS", | ||
| "paths": { | ||
| "@/*": ["src/*"] | ||
| } | ||
| }, | ||
| "include": ["src/**/*"], | ||
| "exclude": ["node_modules", "dist"] | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.