feat: 🎸 add rax code generator solution and test case

This commit is contained in:
牧毅 2020-08-11 19:59:41 +08:00
parent 8647ade39d
commit 20c0953e0d
44 changed files with 1179 additions and 5 deletions

View File

@ -41,7 +41,7 @@
"ts"
],
"require": [
"ts-node/register"
"ts-node/register/transpile-only"
]
},
"publishConfig": {

View File

@ -121,6 +121,19 @@ export class ProjectBuilder implements IProjectBuilder {
files,
});
}
// appConfig
if (parseResult.project && builders.appConfig) {
const { files } = await builders.appConfig.generateModule(
parseResult.project,
);
buildResult.push({
path: this.template.slots.appConfig.path,
files,
});
}
// constants?
if (
parseResult.project &&
@ -136,6 +149,7 @@ export class ProjectBuilder implements IProjectBuilder {
files,
});
}
// utils?
if (
parseResult.globalUtils &&
@ -151,6 +165,7 @@ export class ProjectBuilder implements IProjectBuilder {
files,
});
}
// i18n?
if (parseResult.globalI18n && builders.i18n && this.template.slots.i18n) {
const { files } = await builders.i18n.generateModule(
@ -162,6 +177,7 @@ export class ProjectBuilder implements IProjectBuilder {
files,
});
}
// globalStyle
if (parseResult.project && builders.globalStyle) {
const { files } = await builders.globalStyle.generateModule(
@ -173,6 +189,7 @@ export class ProjectBuilder implements IProjectBuilder {
files,
});
}
// htmlEntry
if (parseResult.project && builders.htmlEntry) {
const { files } = await builders.htmlEntry.generateModule(
@ -184,6 +201,7 @@ export class ProjectBuilder implements IProjectBuilder {
files,
});
}
// packageJSON
if (parseResult.project && builders.packageJSON) {
const { files } = await builders.packageJSON.generateModule(

View File

@ -6,8 +6,8 @@ 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 createIceJsProjectBuilder from './solutions/icejs';
// import createRecoreProjectBuilder from './solutions/recore';
// 引入说明
import { REACT_CHUNK_NAME } from './plugins/component/react/const';
@ -50,8 +50,8 @@ export default {
createProjectBuilder,
createModuleBuilder,
solutions: {
icejs: createIceJsProjectBuilder,
recore: createRecoreProjectBuilder,
// icejs: createIceJsProjectBuilder,
// recore: createRecoreProjectBuilder,
},
solutionParts: {
icejs,

View File

@ -0,0 +1,17 @@
import template from './template';
import entry from './plugins/entry';
import appConfig from './plugins/appConfig';
import entryDocument from './plugins/entryDocument';
import globalStyle from './plugins/globalStyle';
import packageJSON from './plugins/packageJSON';
export default {
template,
plugins: {
appConfig,
entry,
entryDocument,
globalStyle,
packageJSON,
},
};

View File

@ -0,0 +1,45 @@
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.JSON,
name: COMMON_CHUNK_NAME.CustomContent,
content: `
{
"routes": [
{
"path": "/",
"source": "pages/Home/index"
}
],
"window": {
"title": "Rax App Demo"
}
}
`,
linkAfter: [],
});
return next;
};
return plugin;
};
export default pluginFactory;

View File

@ -0,0 +1,51 @@
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.JS,
name: COMMON_CHUNK_NAME.ExternalDepsImport,
content: `
import { runApp } from 'rax-app';
import appConfig from './app.json';
`,
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.FileVarDefine,
COMMON_CHUNK_NAME.FileUtilDefine,
],
});
return next;
};
return plugin;
};
export default pluginFactory;

View File

@ -0,0 +1,59 @@
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}</title>
<Style />
</head>
<body>
{/* root container */}
<Root />
<Script />
</body>
</html>
);
}
export default Document;
`,
linkAfter: [],
});
return next;
};
return plugin;
};
export default pluginFactory;

View File

@ -0,0 +1,55 @@
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: `
// TODO: 引入默认全局样式
`,
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;

View File

@ -0,0 +1,89 @@
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
import {
BuilderComponentPlugin,
BuilderComponentPluginFactory,
ChunkType,
FileType,
ICodeStruct,
IPackageJSON,
IProjectInfo,
} from '../../../../../types';
interface IIceJsPackageJSON extends IPackageJSON {
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',
};
next.chunks.push({
type: ChunkType.JSON,
fileType: FileType.JSON,
name: COMMON_CHUNK_NAME.FileMainContent,
content: packageJson,
linkAfter: [],
});
return next;
};
return plugin;
};
export default pluginFactory;

View File

@ -0,0 +1,28 @@
import ResultFile from '../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'.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];
}

View File

@ -0,0 +1,27 @@
import ResultFile from '../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'.eslintignore',
'',
`
#
build/
tests/
demo/
# node
coverage/
#
**/*-min.js
**/*.min.js
`,
);
return [[], file];
}

View File

@ -0,0 +1,19 @@
import ResultFile from '../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'.eslintrc',
'js',
`
module.exports = {
extends: ['rax'],
};
`,
);
return [[], file];
}

View File

@ -0,0 +1,33 @@
import ResultFile from '../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'.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];
}

View File

@ -0,0 +1,31 @@
import ResultFile from '../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'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];
}

View File

@ -0,0 +1,23 @@
import ResultFile from '../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'abc',
'json',
`
{
"type": "rax",
"builder": "@ali/builder-rax-v1",
"info": {
"raxVersion": "1.x"
}
}
`,
);
return [[], file];
}

View File

@ -0,0 +1,28 @@
import ResultFile from '../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'build',
'json',
`
{
"inlineStyle": false,
"plugins": [
[
"build-plugin-rax-app",
{
"targets": ["web", "miniapp"]
}
],
"@ali/build-plugin-rax-app-def"
]
}
`,
);
return [[], file];
}

View File

@ -0,0 +1,46 @@
import ResultFile from '../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'package',
'json',
`
{
"name": "@ali/rax-component-demo",
"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": {
"rax": "^1.1.0",
"rax-app": "^2.0.0",
"rax-document": "^0.1.0",
"rax-text": "^1.0.0",
"rax-view": "^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"
}
}
`,
);
return [[], file];
}

View File

@ -0,0 +1,20 @@
import ResultFile from '../../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'app',
'js',
`
import { runApp } from 'rax-app';
import appConfig from './app.json';
runApp(appConfig);
`,
);
return [['src'], file];
}

View File

@ -0,0 +1,27 @@
import ResultFile from '../../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'app',
'json',
`
{
"routes": [
{
"path": "/",
"source": "pages/Home/index"
}
],
"window": {
"title": "Rax App Demo"
}
}
`,
);
return [['src'], file];
}

View File

@ -0,0 +1,40 @@
import ResultFile from '../../../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'index',
'jsx',
`
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;
`,
);
return [['src','document'], file];
}

View File

@ -0,0 +1,16 @@
import ResultFile from '../../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'global',
'less',
`
`,
);
return [['src'], file];
}

View File

@ -0,0 +1,16 @@
import ResultFile from '../../../../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'index',
'css',
`
`,
);
return [['src','pages','Home'], file];
}

View File

@ -0,0 +1,34 @@
import ResultFile from '../../../../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'index',
'jsx',
`
import { createElement, Component } from 'rax';
import Page from 'rax-view';
import Text from 'rax-text';
import './index.css';
class Home$$Page extends Component {
render() {
return (
<Page>
<Text>Hello world!</Text>
</Page>
);
}
}
export default Home$$Page;
`,
);
return [['src','pages','Home'], file];
}

View File

@ -0,0 +1,17 @@
import ResultFile from '../../../../../../../model/ResultFile';
import { IResultFile } from '../../../../../../../types';
export default function getFile(): [string[], IResultFile] {
const file = new ResultFile(
'utils',
'js',
`
export default {};
`,
);
return [['src'], file];
}

View File

@ -0,0 +1,94 @@
import ResultDir from '../../../../../model/ResultDir';
import {
IProjectTemplate,
IResultDir,
} from '../../../../../types';
import { runFileGenerator } from '../../../../../utils/templateHelper';
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'
import file6 from './files/build.json'
import file7 from './files/package.json'
import file8 from './files/src/app.js'
import file9 from './files/src/app.json'
import file10 from './files/src/document/index.jsx'
import file11 from './files/src/global.less'
import file12 from './files/src/pages/Home/index.css'
import file13 from './files/src/pages/Home/index.jsx'
import file14 from './files/src/utils.js'
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',
},
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(): IResultDir {
const root = new ResultDir('.');
runFileGenerator(root, file0);
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);
return root;
},
};
export default raxAppTemplate;

View File

@ -0,0 +1,63 @@
import { IProjectBuilder } from '../types';
import { createProjectBuilder } from '../generator/ProjectBuilder';
import esModule from '../plugins/common/esmodule';
import containerClass from '../plugins/component/react/containerClass';
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 raxApp from '../plugins/project/framework/rax';
import { prettier } from '../postprocessor';
export default function createIceJsProjectBuilder(): IProjectBuilder {
return createProjectBuilder({
template: raxApp.template,
plugins: {
components: [
reactCommonDeps(),
esModule({
fileType: 'jsx',
}),
containerClass(),
containerInjectUtils(),
containerInitState(),
containerLifeCycle(),
containerMethod(),
jsx(),
css(),
],
pages: [
reactCommonDeps(),
esModule({
fileType: 'jsx',
}),
containerClass(),
containerInjectUtils(),
containerInitState(),
containerLifeCycle(),
containerMethod(),
jsx(),
css(),
],
appConfig: [raxApp.plugins.appConfig()],
entry: [raxApp.plugins.entry()],
constants: [constants()],
utils: [esModule(), utils()],
i18n: [i18n()],
globalStyle: [raxApp.plugins.globalStyle()],
htmlEntry: [raxApp.plugins.entryDocument()],
packageJSON: [raxApp.plugins.packageJSON()],
},
postProcessors: [prettier()],
});
}

View File

@ -0,0 +1 @@
actual/

View File

@ -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

View File

@ -0,0 +1,11 @@
# 忽略目录
build/
tests/
demo/
# node 覆盖率文件
coverage/
# 忽略文件
**/*-min.js
**/*.min.js

View File

@ -0,0 +1,3 @@
module.exports = {
extends: ['rax'],
};

View 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

View File

@ -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.

View File

@ -0,0 +1,7 @@
{
"type": "rax",
"builder": "@ali/builder-rax-v1",
"info": {
"raxVersion": "1.x"
}
}

View File

@ -0,0 +1,12 @@
{
"inlineStyle": false,
"plugins": [
[
"build-plugin-rax-app",
{
"targets": ["web", "miniapp"]
}
],
"@ali/build-plugin-rax-app-def"
]
}

View File

@ -0,0 +1,30 @@
{
"name": "@ali/rax-component-demo",
"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": {
"rax": "^1.1.0",
"rax-app": "^2.0.0",
"rax-document": "^0.1.0",
"rax-text": "^1.0.0",
"rax-view": "^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"
}
}

View File

@ -0,0 +1,4 @@
import { runApp } from 'rax-app';
import appConfig from './app.json';
runApp(appConfig);

View File

@ -0,0 +1,11 @@
{
"routes": [
{
"path": "/",
"source": "pages/Home/index"
}
],
"window": {
"title": "Rax App Demo"
}
}

View File

@ -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;

View File

@ -0,0 +1,18 @@
import { createElement, Component } from 'rax';
import Page from 'rax-view';
import Text from 'rax-text';
import './index.css';
class Home$$Page extends Component {
render() {
return (
<Page>
<Text>Hello world!</Text>
</Page>
);
}
}
export default Home$$Page;

View File

@ -0,0 +1 @@
export default {};

View File

@ -0,0 +1,51 @@
{
// Schema 参见https://yuque.antfin-inc.com/mo/spec/spec-materials#eNCJr
version: '1.0.0',
componentsMap: [
{
componentName: 'Page',
package: 'rax-view',
version: '^1.0.0',
destructuring: false,
exportName: 'Page',
},
{
componentName: 'Text',
package: 'rax-text',
version: '^1.0.0',
destructuring: false,
exportName: 'Text',
},
],
componentsTree: [
{
componentName: 'Page',
props: {},
lifeCycles: {},
fileName: 'home',
dataSource: {
list: [],
},
children: [
{
componentName: 'Text',
props: {},
children: 'Hello world!',
},
],
},
],
config: {
sdkVersion: '1.0.3',
historyMode: 'hash',
targetRootID: 'root',
},
meta: {
name: '示例应用',
git_group: 'demo-group',
project_name: 'demo-project',
description: '这是一个示例应用',
spma: 'spmademo',
creator: '张三',
},
}

View File

@ -0,0 +1,60 @@
import test from 'ava';
import { spawnSync } from 'child_process';
import fs from 'fs';
import glob from 'glob';
import JSON from 'json5';
import path from 'path';
import CodeGenerator from '../src';
import createRaxAppBuilder from '../src/solutions/rax-app';
import { IProjectSchema } from '../src/types/schema';
const TEST_CASES_DIR = path.join(__dirname, '../test-cases/rax-app');
async function exportProject(schemaJson: IProjectSchema, targetPath: string, projectName: string) {
const raxAppBuilder = createRaxAppBuilder();
const result = await raxAppBuilder.generateProject(schemaJson);
const publisher = CodeGenerator.publishers.disk();
await publisher.publish({
project: result,
outputPath: targetPath,
projectSlug: projectName,
createProjectFolder: true,
});
}
const defineTest = (caseDirName: string) => {
test(`rax-app ${caseDirName} should works`, async (t) => {
const caseFullDir = path.join(TEST_CASES_DIR, caseDirName);
const schema = JSON.parse(fs.readFileSync(path.join(caseFullDir, 'schema.json5'), 'utf-8'));
const actualDir = path.join(caseFullDir, 'actual');
await exportProject(schema, actualDir, 'demo-project');
const actualFiles = glob.sync('**/*.{js,jsx,json,ts,tsx,less,css,scss,sass}', { cwd: actualDir });
t.true(actualFiles.length > 0)
spawnSync('npx', ['prettier', '--write', ...actualFiles], {
stdio: 'inherit',
shell: true,
cwd: actualDir,
});
const diffRes = spawnSync('diff', ['-bur', 'actual', 'expected'], {
stdio: 'pipe',
shell: true,
cwd: caseFullDir,
encoding: 'utf-8',
});
t.is(diffRes.stdout, '')
});
};
test('simple truth should pass', async (t) => {
t.is(0, 0);
});
fs.readdirSync(TEST_CASES_DIR).forEach(defineTest);