mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-04 17:27:09 +00:00
feat: 🎸 Rax 出码器支持路由功能
This commit is contained in:
parent
acd1f0601e
commit
8ecc002f65
@ -24,8 +24,8 @@ interface IModuleInfo {
|
|||||||
|
|
||||||
function getDirFromRoot(root: IResultDir, path: string[]): IResultDir {
|
function getDirFromRoot(root: IResultDir, path: string[]): IResultDir {
|
||||||
let current: IResultDir = root;
|
let current: IResultDir = root;
|
||||||
path.forEach(p => {
|
path.forEach((p) => {
|
||||||
const exist = current.dirs.find(d => d.name === p);
|
const exist = current.dirs.find((d) => d.name === p);
|
||||||
if (exist) {
|
if (exist) {
|
||||||
current = exist;
|
current = exist;
|
||||||
} else {
|
} else {
|
||||||
@ -76,7 +76,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
// components
|
// components
|
||||||
// pages
|
// pages
|
||||||
const containerBuildResult: IModuleInfo[] = await Promise.all<IModuleInfo>(
|
const containerBuildResult: IModuleInfo[] = await Promise.all<IModuleInfo>(
|
||||||
parseResult.containers.map(async containerInfo => {
|
parseResult.containers.map(async (containerInfo) => {
|
||||||
let builder: IModuleBuilder;
|
let builder: IModuleBuilder;
|
||||||
let path: string[];
|
let path: string[];
|
||||||
if (containerInfo.containerType === 'Page') {
|
if (containerInfo.containerType === 'Page') {
|
||||||
@ -100,9 +100,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
|
|
||||||
// router
|
// router
|
||||||
if (parseResult.globalRouter && builders.router) {
|
if (parseResult.globalRouter && builders.router) {
|
||||||
const { files } = await builders.router.generateModule(
|
const { files } = await builders.router.generateModule(parseResult.globalRouter);
|
||||||
parseResult.globalRouter,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.router.path,
|
path: this.template.slots.router.path,
|
||||||
@ -112,9 +110,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
|
|
||||||
// entry
|
// entry
|
||||||
if (parseResult.project && builders.entry) {
|
if (parseResult.project && builders.entry) {
|
||||||
const { files } = await builders.entry.generateModule(
|
const { files } = await builders.entry.generateModule(parseResult.project);
|
||||||
parseResult.project,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.entry.path,
|
path: this.template.slots.entry.path,
|
||||||
@ -123,10 +119,8 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// appConfig
|
// appConfig
|
||||||
if (parseResult.project && builders.appConfig) {
|
if (builders.appConfig) {
|
||||||
const { files } = await builders.appConfig.generateModule(
|
const { files } = await builders.appConfig.generateModule(parseResult);
|
||||||
parseResult.project,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.appConfig.path,
|
path: this.template.slots.appConfig.path,
|
||||||
@ -135,14 +129,8 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// constants?
|
// constants?
|
||||||
if (
|
if (parseResult.project && builders.constants && this.template.slots.constants) {
|
||||||
parseResult.project &&
|
const { files } = await builders.constants.generateModule(parseResult.project);
|
||||||
builders.constants &&
|
|
||||||
this.template.slots.constants
|
|
||||||
) {
|
|
||||||
const { files } = await builders.constants.generateModule(
|
|
||||||
parseResult.project,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.constants.path,
|
path: this.template.slots.constants.path,
|
||||||
@ -151,14 +139,8 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// utils?
|
// utils?
|
||||||
if (
|
if (parseResult.globalUtils && builders.utils && this.template.slots.utils) {
|
||||||
parseResult.globalUtils &&
|
const { files } = await builders.utils.generateModule(parseResult.globalUtils);
|
||||||
builders.utils &&
|
|
||||||
this.template.slots.utils
|
|
||||||
) {
|
|
||||||
const { files } = await builders.utils.generateModule(
|
|
||||||
parseResult.globalUtils,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.utils.path,
|
path: this.template.slots.utils.path,
|
||||||
@ -168,9 +150,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
|
|
||||||
// i18n?
|
// i18n?
|
||||||
if (parseResult.globalI18n && builders.i18n && this.template.slots.i18n) {
|
if (parseResult.globalI18n && builders.i18n && this.template.slots.i18n) {
|
||||||
const { files } = await builders.i18n.generateModule(
|
const { files } = await builders.i18n.generateModule(parseResult.globalI18n);
|
||||||
parseResult.globalI18n,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.i18n.path,
|
path: this.template.slots.i18n.path,
|
||||||
@ -180,9 +160,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
|
|
||||||
// globalStyle
|
// globalStyle
|
||||||
if (parseResult.project && builders.globalStyle) {
|
if (parseResult.project && builders.globalStyle) {
|
||||||
const { files } = await builders.globalStyle.generateModule(
|
const { files } = await builders.globalStyle.generateModule(parseResult.project);
|
||||||
parseResult.project,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.globalStyle.path,
|
path: this.template.slots.globalStyle.path,
|
||||||
@ -192,9 +170,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
|
|
||||||
// htmlEntry
|
// htmlEntry
|
||||||
if (parseResult.project && builders.htmlEntry) {
|
if (parseResult.project && builders.htmlEntry) {
|
||||||
const { files } = await builders.htmlEntry.generateModule(
|
const { files } = await builders.htmlEntry.generateModule(parseResult.project);
|
||||||
parseResult.project,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.htmlEntry.path,
|
path: this.template.slots.htmlEntry.path,
|
||||||
@ -204,9 +180,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
|
|
||||||
// packageJSON
|
// packageJSON
|
||||||
if (parseResult.project && builders.packageJSON) {
|
if (parseResult.project && builders.packageJSON) {
|
||||||
const { files } = await builders.packageJSON.generateModule(
|
const { files } = await builders.packageJSON.generateModule(parseResult.project);
|
||||||
parseResult.project,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.packageJSON.path,
|
path: this.template.slots.packageJSON.path,
|
||||||
@ -217,14 +191,14 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
// Post Process
|
// Post Process
|
||||||
|
|
||||||
// Combine Modules
|
// Combine Modules
|
||||||
buildResult.forEach(moduleInfo => {
|
buildResult.forEach((moduleInfo) => {
|
||||||
let targetDir = getDirFromRoot(projectRoot, moduleInfo.path);
|
let targetDir = getDirFromRoot(projectRoot, moduleInfo.path);
|
||||||
if (moduleInfo.moduleName) {
|
if (moduleInfo.moduleName) {
|
||||||
const dir = new ResultDir(moduleInfo.moduleName);
|
const dir = new ResultDir(moduleInfo.moduleName);
|
||||||
targetDir.addDirectory(dir);
|
targetDir.addDirectory(dir);
|
||||||
targetDir = dir;
|
targetDir = dir;
|
||||||
}
|
}
|
||||||
moduleInfo.files.forEach(file => targetDir.addFile(file));
|
moduleInfo.files.forEach((file) => targetDir.addFile(file));
|
||||||
});
|
});
|
||||||
|
|
||||||
return projectRoot;
|
return projectRoot;
|
||||||
@ -233,7 +207,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
private createModuleBuilders(): Record<string, IModuleBuilder> {
|
private createModuleBuilders(): Record<string, IModuleBuilder> {
|
||||||
const builders: Record<string, IModuleBuilder> = {};
|
const builders: Record<string, IModuleBuilder> = {};
|
||||||
|
|
||||||
Object.keys(this.plugins).forEach(pluginName => {
|
Object.keys(this.plugins).forEach((pluginName) => {
|
||||||
if (this.plugins[pluginName].length > 0) {
|
if (this.plugins[pluginName].length > 0) {
|
||||||
const options: { mainFileName?: string } = {};
|
const options: { mainFileName?: string } = {};
|
||||||
if (this.template.slots[pluginName] && this.template.slots[pluginName].fileName) {
|
if (this.template.slots[pluginName] && this.template.slots[pluginName].fileName) {
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import {
|
|||||||
IProjectSchema,
|
IProjectSchema,
|
||||||
ISchemaParser,
|
ISchemaParser,
|
||||||
UtilItem,
|
UtilItem,
|
||||||
|
IRouterInfo,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
|
|
||||||
const defaultContainer: IContainerInfo = {
|
const defaultContainer: IContainerInfo = {
|
||||||
@ -144,20 +145,21 @@ class SchemaParser implements ISchemaParser {
|
|||||||
const containersDeps = ([] as IDependency[]).concat(...containers.map((c) => c.deps || []));
|
const containersDeps = ([] as IDependency[]).concat(...containers.map((c) => c.deps || []));
|
||||||
|
|
||||||
// 分析路由配置
|
// 分析路由配置
|
||||||
// TODO: 低代码规范里面的路由是咋弄的?
|
const routes: IRouterInfo['routes'] = containers
|
||||||
const routes = containers
|
|
||||||
.filter((container) => container.containerType === 'Page')
|
.filter((container) => container.containerType === 'Page')
|
||||||
.map((page) => {
|
.map((page) => {
|
||||||
const meta = (page as { meta?: IPageMeta }).meta as IPageMeta;
|
const meta = (page as { meta?: IPageMeta }).meta as IPageMeta;
|
||||||
if (meta) {
|
if (meta) {
|
||||||
return {
|
return {
|
||||||
path: meta.router,
|
path: meta.router,
|
||||||
|
fileName: page.fileName,
|
||||||
componentName: page.moduleName,
|
componentName: page.moduleName,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
path: '',
|
path: '',
|
||||||
|
fileName: page.fileName,
|
||||||
componentName: page.moduleName,
|
componentName: page.moduleName,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import changeCase from 'change-case';
|
||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -6,7 +7,7 @@ import {
|
|||||||
ChunkType,
|
ChunkType,
|
||||||
FileType,
|
FileType,
|
||||||
ICodeStruct,
|
ICodeStruct,
|
||||||
IRouterInfo,
|
IParseResult,
|
||||||
} from '../../../../../types';
|
} from '../../../../../types';
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||||
@ -15,23 +16,22 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|||||||
...pre,
|
...pre,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ir = next.ir as IRouterInfo;
|
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' }];
|
||||||
|
|
||||||
// TODO: 如何生成路由?
|
|
||||||
next.chunks.push({
|
next.chunks.push({
|
||||||
type: ChunkType.STRING,
|
type: ChunkType.STRING,
|
||||||
fileType: FileType.JSON,
|
fileType: FileType.JSON,
|
||||||
name: COMMON_CHUNK_NAME.CustomContent,
|
name: COMMON_CHUNK_NAME.CustomContent,
|
||||||
content: `
|
content: `
|
||||||
{
|
{
|
||||||
"routes": [
|
"routes": ${JSON.stringify(routes, null, 2)},
|
||||||
{
|
|
||||||
"path": "/",
|
|
||||||
"source": "pages/Home/index"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"window": {
|
"window": {
|
||||||
"title": "Rax App Demo"
|
"title": ${JSON.stringify(ir.project?.meta?.title || ir.project?.meta?.name || '')}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
|||||||
@ -25,6 +25,7 @@ export interface IUtilInfo extends IWithDependency {
|
|||||||
export interface IRouterInfo extends IWithDependency {
|
export interface IRouterInfo extends IWithDependency {
|
||||||
routes: Array<{
|
routes: Array<{
|
||||||
path: string;
|
path: string;
|
||||||
|
fileName: string;
|
||||||
componentName: string;
|
componentName: string;
|
||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -108,12 +108,6 @@ export function generateUnknownType(value: CompositeValue, handlers: CustomHandl
|
|||||||
|
|
||||||
export function generateCompositeType(value: CompositeValue, handlers: CustomHandlerSet = {}): [boolean, string] {
|
export function generateCompositeType(value: CompositeValue, handlers: CustomHandlerSet = {}): [boolean, string] {
|
||||||
const result = generateUnknownType(value, handlers);
|
const result = generateUnknownType(value, handlers);
|
||||||
|
|
||||||
// TODO:什么场景下会返回这样的字符串??
|
|
||||||
if (result.substr(0, 1) === "'" && result.substr(-1, 1) === "'") {
|
|
||||||
return [true, result.substring(1, result.length - 1)];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [false, result];
|
return [false, result];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import {
|
|||||||
CompositeValue,
|
CompositeValue,
|
||||||
NodeSchema,
|
NodeSchema,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { CustomHandlerSet, generateCompositeType } from './compositeType';
|
import { CustomHandlerSet, generateCompositeType, generateUnknownType } from './compositeType';
|
||||||
import { generateExpression } from './jsExpression';
|
import { generateExpression } from './jsExpression';
|
||||||
|
|
||||||
// tslint:disable-next-line: no-empty
|
// tslint:disable-next-line: no-empty
|
||||||
@ -49,10 +49,18 @@ export function generateAttr(
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const [isString, valueStr] = generateCompositeType(attrValue, customHandlers);
|
if (typeof attrValue === 'string') {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
value: `${attrName}=${JSON.stringify(attrValue)}`,
|
||||||
|
type: PIECE_TYPE.ATTR,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
value: `${attrName}=${isString ? `"${valueStr}"` : `{${valueStr}}`}`,
|
value: `${attrName}={${generateUnknownType(attrValue, customHandlers)}}`,
|
||||||
type: PIECE_TYPE.ATTR,
|
type: PIECE_TYPE.ATTR,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -23,6 +23,9 @@
|
|||||||
props: {},
|
props: {},
|
||||||
lifeCycles: {},
|
lifeCycles: {},
|
||||||
fileName: 'home',
|
fileName: 'home',
|
||||||
|
meta: {
|
||||||
|
router: '/',
|
||||||
|
},
|
||||||
dataSource: {
|
dataSource: {
|
||||||
list: [],
|
list: [],
|
||||||
},
|
},
|
||||||
|
|||||||
@ -35,6 +35,9 @@
|
|||||||
{
|
{
|
||||||
componentName: 'Page',
|
componentName: 'Page',
|
||||||
fileName: 'home',
|
fileName: 'home',
|
||||||
|
meta: {
|
||||||
|
router: '/',
|
||||||
|
},
|
||||||
state: {
|
state: {
|
||||||
clickCount: 0,
|
clickCount: 0,
|
||||||
user: { name: '张三', age: 18, avatar: 'https://gw.alicdn.com/tfs/TB1Ui9BMkY2gK0jSZFgXXc5OFXa-50-50.png' },
|
user: { name: '张三', age: 18, avatar: 'https://gw.alicdn.com/tfs/TB1Ui9BMkY2gK0jSZFgXXc5OFXa-50-50.png' },
|
||||||
|
|||||||
@ -0,0 +1,12 @@
|
|||||||
|
# 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
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
# 忽略目录
|
||||||
|
build/
|
||||||
|
tests/
|
||||||
|
demo/
|
||||||
|
|
||||||
|
# node 覆盖率文件
|
||||||
|
coverage/
|
||||||
|
|
||||||
|
# 忽略文件
|
||||||
|
**/*-min.js
|
||||||
|
**/*.min.js
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: ['rax'],
|
||||||
|
};
|
||||||
17
packages/code-generator/test-cases/rax-app/demo3/expected/demo-project/.gitignore
vendored
Normal file
17
packages/code-generator/test-cases/rax-app/demo3/expected/demo-project/.gitignore
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# 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
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
# @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.
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"type": "rax",
|
||||||
|
"builder": "@ali/builder-rax-v1",
|
||||||
|
"info": {
|
||||||
|
"raxVersion": "1.x"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"inlineStyle": false,
|
||||||
|
"plugins": [
|
||||||
|
[
|
||||||
|
"build-plugin-rax-app",
|
||||||
|
{
|
||||||
|
"targets": ["web", "miniapp"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"@ali/build-plugin-rax-app-def"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "@ali/rax-app-demo",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "rm -f ./dist/miniapp.tar.gz && npm run build:miniapp && cd build/miniapp && tar czf ../../dist/miniapp.tar.gz *",
|
||||||
|
"build:miniapp": "build-scripts build",
|
||||||
|
"start": "build-scripts start",
|
||||||
|
"lint": "eslint --ext .js --ext .jsx ./"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@ali/lowcode-datasource-engine": "^0.1.0",
|
||||||
|
"universal-env": "^3.2.0",
|
||||||
|
"rax": "^1.1.0",
|
||||||
|
"rax-app": "^2.0.0",
|
||||||
|
"rax-document": "^0.1.0",
|
||||||
|
"rax-view": "^1.0.0",
|
||||||
|
"rax-text": "^1.0.0",
|
||||||
|
"rax-link": "^1.0.0",
|
||||||
|
"rax-image": "^1.0.0"
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { runApp } from 'rax-app';
|
||||||
|
import appConfig from './app.json';
|
||||||
|
|
||||||
|
import './global.scss';
|
||||||
|
|
||||||
|
runApp(appConfig);
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"path": "/",
|
||||||
|
"source": "pages/Home/index"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/list",
|
||||||
|
"source": "pages/List/index"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/detail",
|
||||||
|
"source": "pages/Detail/index"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"window": {
|
||||||
|
"title": "Rax App Demo"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
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>Rax App Demo</title>
|
||||||
|
<Style />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{/* root container */}
|
||||||
|
<Root />
|
||||||
|
<Script />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Document;
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
body {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
page,
|
||||||
|
body {
|
||||||
|
width: 750rpx;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
@ -0,0 +1,136 @@
|
|||||||
|
// 注意: 出码引擎注入的临时变量默认都以 "__$$" 开头,禁止在搭建的代码中直接访问。
|
||||||
|
// 例外:rax 框架的导出名和各种组件名除外。
|
||||||
|
import { createElement, Component } from 'rax';
|
||||||
|
|
||||||
|
import View from 'rax-view';
|
||||||
|
|
||||||
|
import Text from 'rax-text';
|
||||||
|
|
||||||
|
import Link from 'rax-link';
|
||||||
|
|
||||||
|
import Image from 'rax-image';
|
||||||
|
|
||||||
|
import { create as __$$createDataSourceEngine } from '@ali/lowcode-datasource-engine';
|
||||||
|
|
||||||
|
import { isMiniApp as __$$isMiniApp } from 'universal-env';
|
||||||
|
|
||||||
|
import __$$projectUtils from '../../utils';
|
||||||
|
|
||||||
|
import './index.css';
|
||||||
|
|
||||||
|
class Detail$$Page extends Component {
|
||||||
|
state = {};
|
||||||
|
|
||||||
|
_methods = this._defineMethods();
|
||||||
|
|
||||||
|
_context = this._createContext();
|
||||||
|
|
||||||
|
_dataSourceConfig = this._defineDataSourceConfig();
|
||||||
|
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceConfig, this._context, { runtimeConfig: true });
|
||||||
|
|
||||||
|
_utils = this._defineUtils();
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this._dataSourceEngine.reloadDataSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const __$$context = this._context;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<View>
|
||||||
|
<Text>This is the Detail Page</Text>
|
||||||
|
</View>
|
||||||
|
<Link href="javascript:history.back();" miniappHref="navigateBack:">
|
||||||
|
<Text>Go back</Text>
|
||||||
|
</Link>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_createContext() {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
const context = {
|
||||||
|
get state() {
|
||||||
|
return self.state;
|
||||||
|
},
|
||||||
|
setState(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;
|
||||||
|
},
|
||||||
|
...this._methods,
|
||||||
|
};
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
_defineDataSourceConfig() {
|
||||||
|
const __$$context = this._context;
|
||||||
|
return { list: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
_defineUtils() {
|
||||||
|
const utils = {
|
||||||
|
...__$$projectUtils,
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(utils).forEach(([name, util]) => {
|
||||||
|
if (typeof util === 'function') {
|
||||||
|
utils[name] = util.bind(this._context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return utils;
|
||||||
|
}
|
||||||
|
|
||||||
|
_defineMethods() {
|
||||||
|
const __$$methods = {};
|
||||||
|
|
||||||
|
// 为所有的方法绑定上下文
|
||||||
|
Object.entries(__$$methods).forEach(([methodName, method]) => {
|
||||||
|
if (typeof method === 'function') {
|
||||||
|
__$$methods[methodName] = (...args) => {
|
||||||
|
return method.apply(this._context, args);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return __$$methods;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Detail$$Page;
|
||||||
|
|
||||||
|
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 : [];
|
||||||
|
}
|
||||||
@ -0,0 +1,136 @@
|
|||||||
|
// 注意: 出码引擎注入的临时变量默认都以 "__$$" 开头,禁止在搭建的代码中直接访问。
|
||||||
|
// 例外:rax 框架的导出名和各种组件名除外。
|
||||||
|
import { createElement, Component } from 'rax';
|
||||||
|
|
||||||
|
import View from 'rax-view';
|
||||||
|
|
||||||
|
import Text from 'rax-text';
|
||||||
|
|
||||||
|
import Link from 'rax-link';
|
||||||
|
|
||||||
|
import Image from 'rax-image';
|
||||||
|
|
||||||
|
import { create as __$$createDataSourceEngine } from '@ali/lowcode-datasource-engine';
|
||||||
|
|
||||||
|
import { isMiniApp as __$$isMiniApp } from 'universal-env';
|
||||||
|
|
||||||
|
import __$$projectUtils from '../../utils';
|
||||||
|
|
||||||
|
import './index.css';
|
||||||
|
|
||||||
|
class Home$$Page extends Component {
|
||||||
|
state = {};
|
||||||
|
|
||||||
|
_methods = this._defineMethods();
|
||||||
|
|
||||||
|
_context = this._createContext();
|
||||||
|
|
||||||
|
_dataSourceConfig = this._defineDataSourceConfig();
|
||||||
|
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceConfig, this._context, { runtimeConfig: true });
|
||||||
|
|
||||||
|
_utils = this._defineUtils();
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this._dataSourceEngine.reloadDataSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const __$$context = this._context;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<View>
|
||||||
|
<Text>This is the Home Page</Text>
|
||||||
|
</View>
|
||||||
|
<Link href="#/list" miniappHref="navigate:/pages/List/index">
|
||||||
|
<Text>Go To The List Page</Text>
|
||||||
|
</Link>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_createContext() {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
const context = {
|
||||||
|
get state() {
|
||||||
|
return self.state;
|
||||||
|
},
|
||||||
|
setState(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;
|
||||||
|
},
|
||||||
|
...this._methods,
|
||||||
|
};
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
_defineDataSourceConfig() {
|
||||||
|
const __$$context = this._context;
|
||||||
|
return { list: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
_defineUtils() {
|
||||||
|
const utils = {
|
||||||
|
...__$$projectUtils,
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(utils).forEach(([name, util]) => {
|
||||||
|
if (typeof util === 'function') {
|
||||||
|
utils[name] = util.bind(this._context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return utils;
|
||||||
|
}
|
||||||
|
|
||||||
|
_defineMethods() {
|
||||||
|
const __$$methods = {};
|
||||||
|
|
||||||
|
// 为所有的方法绑定上下文
|
||||||
|
Object.entries(__$$methods).forEach(([methodName, method]) => {
|
||||||
|
if (typeof method === 'function') {
|
||||||
|
__$$methods[methodName] = (...args) => {
|
||||||
|
return method.apply(this._context, args);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return __$$methods;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Home$$Page;
|
||||||
|
|
||||||
|
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 : [];
|
||||||
|
}
|
||||||
@ -0,0 +1,139 @@
|
|||||||
|
// 注意: 出码引擎注入的临时变量默认都以 "__$$" 开头,禁止在搭建的代码中直接访问。
|
||||||
|
// 例外:rax 框架的导出名和各种组件名除外。
|
||||||
|
import { createElement, Component } from 'rax';
|
||||||
|
|
||||||
|
import View from 'rax-view';
|
||||||
|
|
||||||
|
import Text from 'rax-text';
|
||||||
|
|
||||||
|
import Link from 'rax-link';
|
||||||
|
|
||||||
|
import Image from 'rax-image';
|
||||||
|
|
||||||
|
import { create as __$$createDataSourceEngine } from '@ali/lowcode-datasource-engine';
|
||||||
|
|
||||||
|
import { isMiniApp as __$$isMiniApp } from 'universal-env';
|
||||||
|
|
||||||
|
import __$$projectUtils from '../../utils';
|
||||||
|
|
||||||
|
import './index.css';
|
||||||
|
|
||||||
|
class List$$Page extends Component {
|
||||||
|
state = {};
|
||||||
|
|
||||||
|
_methods = this._defineMethods();
|
||||||
|
|
||||||
|
_context = this._createContext();
|
||||||
|
|
||||||
|
_dataSourceConfig = this._defineDataSourceConfig();
|
||||||
|
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceConfig, this._context, { runtimeConfig: true });
|
||||||
|
|
||||||
|
_utils = this._defineUtils();
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this._dataSourceEngine.reloadDataSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const __$$context = this._context;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<View>
|
||||||
|
<Text>This is the List Page</Text>
|
||||||
|
</View>
|
||||||
|
<Link href="#/detail" miniappHref="navigate:/pages/Detail/index">
|
||||||
|
<Text>Go To The Detail Page</Text>
|
||||||
|
</Link>
|
||||||
|
<Link href="javascript:history.back();" miniappHref="navigateBack:">
|
||||||
|
<Text>Go back</Text>
|
||||||
|
</Link>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_createContext() {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
const context = {
|
||||||
|
get state() {
|
||||||
|
return self.state;
|
||||||
|
},
|
||||||
|
setState(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;
|
||||||
|
},
|
||||||
|
...this._methods,
|
||||||
|
};
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
_defineDataSourceConfig() {
|
||||||
|
const __$$context = this._context;
|
||||||
|
return { list: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
_defineUtils() {
|
||||||
|
const utils = {
|
||||||
|
...__$$projectUtils,
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(utils).forEach(([name, util]) => {
|
||||||
|
if (typeof util === 'function') {
|
||||||
|
utils[name] = util.bind(this._context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return utils;
|
||||||
|
}
|
||||||
|
|
||||||
|
_defineMethods() {
|
||||||
|
const __$$methods = {};
|
||||||
|
|
||||||
|
// 为所有的方法绑定上下文
|
||||||
|
Object.entries(__$$methods).forEach(([methodName, method]) => {
|
||||||
|
if (typeof method === 'function') {
|
||||||
|
__$$methods[methodName] = (...args) => {
|
||||||
|
return method.apply(this._context, args);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return __$$methods;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default List$$Page;
|
||||||
|
|
||||||
|
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 : [];
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
export default {};
|
||||||
175
packages/code-generator/test-cases/rax-app/demo3/schema.json5
Normal file
175
packages/code-generator/test-cases/rax-app/demo3/schema.json5
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
{
|
||||||
|
// Schema 参见:https://yuque.antfin-inc.com/mo/spec/spec-materials#eNCJr
|
||||||
|
version: '1.0.0',
|
||||||
|
componentsMap: [
|
||||||
|
{
|
||||||
|
componentName: 'View',
|
||||||
|
package: 'rax-view',
|
||||||
|
version: '^1.0.0',
|
||||||
|
destructuring: false,
|
||||||
|
exportName: 'View',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Text',
|
||||||
|
package: 'rax-text',
|
||||||
|
version: '^1.0.0',
|
||||||
|
destructuring: false,
|
||||||
|
exportName: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Link',
|
||||||
|
package: 'rax-link',
|
||||||
|
version: '^1.0.0',
|
||||||
|
destructuring: false,
|
||||||
|
exportName: 'Link',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Image',
|
||||||
|
package: 'rax-image',
|
||||||
|
version: '^1.0.0',
|
||||||
|
destructuring: false,
|
||||||
|
exportName: 'Image',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Page',
|
||||||
|
package: 'rax-view',
|
||||||
|
version: '^1.0.0',
|
||||||
|
destructuring: false,
|
||||||
|
exportName: 'Page',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
componentsTree: [
|
||||||
|
{
|
||||||
|
componentName: 'Page',
|
||||||
|
fileName: 'home',
|
||||||
|
state: {},
|
||||||
|
dataSource: {
|
||||||
|
list: [],
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
router: '/',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'View',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Text',
|
||||||
|
children: 'This is the Home Page',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Link',
|
||||||
|
props: {
|
||||||
|
href: '#/list',
|
||||||
|
miniappHref: 'navigate:/pages/List/index',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Text',
|
||||||
|
children: 'Go To The List Page',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Page',
|
||||||
|
fileName: 'list',
|
||||||
|
state: {},
|
||||||
|
dataSource: {
|
||||||
|
list: [],
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
router: '/list',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'View',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Text',
|
||||||
|
children: 'This is the List Page',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Link',
|
||||||
|
props: {
|
||||||
|
href: '#/detail',
|
||||||
|
miniappHref: 'navigate:/pages/Detail/index',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Text',
|
||||||
|
children: 'Go To The Detail Page',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Link',
|
||||||
|
props: {
|
||||||
|
href: 'javascript:history.back();',
|
||||||
|
miniappHref: 'navigateBack:',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Text',
|
||||||
|
children: 'Go back',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Page',
|
||||||
|
fileName: 'detail',
|
||||||
|
state: {},
|
||||||
|
dataSource: {
|
||||||
|
list: [],
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
router: '/detail',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'View',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Text',
|
||||||
|
children: 'This is the Detail Page',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Link',
|
||||||
|
props: {
|
||||||
|
href: 'javascript:history.back();',
|
||||||
|
miniappHref: 'navigateBack:',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Text',
|
||||||
|
children: 'Go back',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
css: 'page,body{\n width: 750rpx;\n overflow-x: hidden;\n}',
|
||||||
|
config: {
|
||||||
|
sdkVersion: '1.0.3',
|
||||||
|
historyMode: 'hash',
|
||||||
|
targetRootID: 'root',
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
name: 'Rax App Demo',
|
||||||
|
git_group: 'demo-group',
|
||||||
|
project_name: 'demo-project',
|
||||||
|
description: '这是一个示例应用',
|
||||||
|
spma: 'spmademo',
|
||||||
|
creator: '张三',
|
||||||
|
},
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user