feat: 🎸 完善 Rax 出码, 跑通第一个测试用例👏👏👏

This commit is contained in:
牧毅 2020-08-12 11:39:15 +08:00
parent c46af6376f
commit 9f621101b3
11 changed files with 307 additions and 25 deletions

View File

@ -0,0 +1 @@
test-cases/

View File

@ -8,6 +8,7 @@
"demo"
],
"scripts": {
"start": "ava --watch",
"build": "rimraf lib && tsc",
"demo": "node ./demo/demo.js",
"test": "ava",
@ -45,6 +46,11 @@
],
"require": [
"ts-node/register/transpile-only"
],
"sources": [
"src/**/*",
"test/**/*",
"test-cases/**/expected/**/*"
]
},
"publishConfig": {

View File

@ -21,6 +21,7 @@ export const CLASS_DEFINE_CHUNK_NAME = {
InsVar: 'CommonClassDefineInsVar',
InsVarMethod: 'CommonClassDefineInsVarMethod',
InsMethod: 'CommonClassDefineInsMethod',
InsPrivateMethod: 'CommonClassDefineInsPrivateMethod',
End: 'CommonClassDefineEnd',
};
@ -82,6 +83,15 @@ export const DEFAULT_LINK_AFTER = {
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,
@ -89,6 +99,7 @@ export const DEFAULT_LINK_AFTER = {
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]: [

View File

@ -1,9 +1,9 @@
export const RAX_CHUNK_NAME = {
ClassDidMountStart: 'RaxComponentClassDidMountStart',
ClassDidMountContent: 'RaxComponentClassDidMountContent',
ClassDidMountEnd: 'RaxComponentClassDidMountEnd',
ClassRenderStart: 'RaxComponentClassRenderStart',
ClassRenderPre: 'RaxComponentClassRenderPre',
ClassRenderEnd: 'RaxComponentClassRenderEnd',
ClassRenderJSX: 'RaxComponentClassRenderJSX',
ClassDidMountStart: 'RaxComponentClassDidMountStart',
ClassDidMountEnd: 'RaxComponentClassDidMountEnd',
ClassDidMountContent: 'RaxComponentClassDidMountContent',
ClassRenderEnd: 'RaxComponentClassRenderEnd',
};

View File

@ -35,12 +35,17 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
],
});
next.chunks.push({
type: ChunkType.STRING,
fileType: FileType.JSX,
name: CLASS_DEFINE_CHUNK_NAME.End,
content: `}`,
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start, RAX_CHUNK_NAME.ClassRenderEnd],
linkAfter: [
CLASS_DEFINE_CHUNK_NAME.Start,
RAX_CHUNK_NAME.ClassRenderEnd,
CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
],
});
// next.chunks.push({
@ -62,15 +67,36 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
// ],
// });
next.chunks.push({
type: ChunkType.STRING,
fileType: FileType.JSX,
name: RAX_CHUNK_NAME.ClassDidMountStart,
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.ClassDidMountStart,
RAX_CHUNK_NAME.ClassDidMountContent,
],
});
next.chunks.push({
type: ChunkType.STRING,
fileType: FileType.JSX,
name: RAX_CHUNK_NAME.ClassRenderStart,
content: 'render() {',
linkAfter: [
CLASS_DEFINE_CHUNK_NAME.Start,
CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
CLASS_DEFINE_CHUNK_NAME.InsMethod,
RAX_CHUNK_NAME.ClassDidMountEnd,
],
});
@ -79,11 +105,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
fileType: FileType.JSX,
name: RAX_CHUNK_NAME.ClassRenderEnd,
content: '}',
linkAfter: [
RAX_CHUNK_NAME.ClassRenderStart,
RAX_CHUNK_NAME.ClassRenderPre,
RAX_CHUNK_NAME.ClassRenderJSX,
],
linkAfter: [RAX_CHUNK_NAME.ClassRenderStart, RAX_CHUNK_NAME.ClassRenderPre, RAX_CHUNK_NAME.ClassRenderJSX],
});
next.chunks.push({

View File

@ -0,0 +1,86 @@
import { CLASS_DEFINE_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: CLASS_DEFINE_CHUNK_NAME.InsVar,
content: `
_context = this._createContext();
`,
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
});
// TODO: 补充数据源的定义
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
content: `
_createContext() {
const self = this;
const context = {
get state() {
return self.state;
},
setState(newState) {
self.setState(newState);
},
get dataSourceMap() {
return self._dataSourceEngine?.dataSourceMap || {};
},
async reloadDataSource() {
self._dataSourceEngine?.reloadDataSource();
},
get utils() {
return self._utils;
},
get page() {
return context;
},
get component() {
return context;
},
get props() {
return self.props;
},
};
return context;
}
`,
linkAfter: [
RAX_CHUNK_NAME.ClassRenderEnd
],
});
return next;
};
return plugin;
};
export default pluginFactory;

View File

@ -0,0 +1,78 @@
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: FileType.JSX,
name: COMMON_CHUNK_NAME.ExternalDepsImport,
content: `
import { createDataSourceEngine } from '@ali/lowcode-data-source-engine';
`,
linkAfter: [],
});
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
content: `
_dataSourceList = this._defineDataSourceList();
_dataSourceEngine = createDataSourceEngine(this._dataSourceList, this._context);`,
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.ClassDidMountStart,
],
});
// TODO: 补充数据源的定义
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
content: `
_defineDataSourceList() {
return [];
}`,
linkAfter: [
RAX_CHUNK_NAME.ClassRenderEnd
],
});
return next;
};
return plugin;
};
export default pluginFactory;

View File

@ -7,6 +7,7 @@ import {
FileType,
ICodeStruct,
} from '../../../types';
import { RAX_CHUNK_NAME } from './const';
type PluginConfig = {
fileType: string;
@ -24,13 +25,27 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
};
// TODO: utils 怎么注入?
// 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],
// });
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,
content: `
_defineUtils() {
return {};
}`,
linkAfter: [
RAX_CHUNK_NAME.ClassRenderEnd
],
});
return next;
};

View File

@ -40,7 +40,10 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
fileType: FileType.JSX,
name: CLASS_DEFINE_CHUNK_NAME.End,
content: `}`,
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start, REACT_CHUNK_NAME.ClassRenderEnd],
linkAfter: [
CLASS_DEFINE_CHUNK_NAME.Start,
REACT_CHUNK_NAME.ClassRenderEnd,
],
});
next.chunks.push({

View File

@ -4,10 +4,12 @@ import { createProjectBuilder } from '../generator/ProjectBuilder';
import esModule from '../plugins/common/esmodule';
import containerClass from '../plugins/component/rax/containerClass';
import containerInitState from '../plugins/component/rax/containerInitState';
import containerInjectUtils from '../plugins/component/rax/containerInjectUtils';
import containerLifeCycle from '../plugins/component/rax/containerLifeCycle';
import containerMethod from '../plugins/component/rax/containerMethod';
import containerInitState from '../plugins/component/rax/containerInitState';
import containerInjectContext from '../plugins/component/rax/containerInjectContext';
import containerInjectDataSourceEngine from '../plugins/component/rax/containerInjectDataSourceEngine';
import containerInjectUtils from '../plugins/component/rax/containerInjectUtils';
import jsx from '../plugins/component/rax/jsx';
import commonDeps from '../plugins/component/rax/commonDeps';
import css from '../plugins/component/style/css';
@ -42,8 +44,10 @@ export default function createIceJsProjectBuilder(): IProjectBuilder {
fileType: 'jsx',
}),
containerClass(),
containerInjectUtils(),
containerInitState(),
containerInjectContext(),
containerInjectDataSourceEngine(),
containerInjectUtils(),
containerLifeCycle(),
containerMethod(),
jsx(),
@ -58,6 +62,8 @@ export default function createIceJsProjectBuilder(): IProjectBuilder {
htmlEntry: [raxApp.plugins.entryDocument()],
packageJSON: [raxApp.plugins.packageJSON()],
},
postProcessors: [prettier()],
postProcessors: [
// prettier() // 暂且禁用 prettier
],
});
}

View File

@ -4,9 +4,22 @@ import Page from 'rax-view';
import Text from 'rax-text';
import { createDataSourceEngine } from '@ali/lowcode-data-source-engine';
import './index.css';
class Home$$Page extends Component {
_context = this._createContext();
_dataSourceList = this._defineDataSourceList();
_dataSourceEngine = createDataSourceEngine(this._dataSourceList, this._context);
_utils = this._defineUtils();
componentDidMount() {
this._dataSourceEngine.reloadDataSource();
}
render() {
return (
<Page>
@ -14,6 +27,47 @@ class Home$$Page extends Component {
</Page>
);
}
_createContext() {
const self = this;
const context = {
get state() {
return self.state;
},
setState(newState) {
self.setState(newState);
},
get dataSourceMap() {
return self._dataSourceEngine?.dataSourceMap || {};
},
async reloadDataSource() {
self._dataSourceEngine?.reloadDataSource();
},
get utils() {
return self._utils;
},
get page() {
return context;
},
get component() {
return context;
},
get props() {
return self.props;
},
};
return context;
}
_defineDataSourceList() {
return [];
}
_defineUtils() {
return {};
}
}
export default Home$$Page;