in modules/code-generator/src/cli/solutions/example-solution.ts [1:795]
export function getLowcodeSolutionTemplateFiles() {
return [
{
file: '.editorconfig',
content: `root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
quote_type = single
[*.md]
trim_trailing_whitespace = false
`,
},
{
file: '.eslintignore',
content: `# 忽略目录
node_modules/
build/
dist/
test-cases/
test/
tests/
output/
es/
lib/
coverage/
# 忽略文件
**/*.min.js
**/*-min.js
**/*.bundle.js
`,
},
{
file: '.eslintrc.js',
content: `module.exports = {
extends: 'eslint-config-ali/typescript/react',
rules: {
'max-len': ['error', { code: 200 }],
'comma-dangle': 0,
},
};
`,
},
{
file: '.gitignore',
content: `# project custom
build
es
lib
dist
output
package-lock.json
deploy-space/packages
deploy-space/.env
generated
# IDE
.vscode
.idea
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
lib
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# mac config files
.DS_Store
# codealike
codealike.json
.node
`,
},
{
file: '.prettierignore',
content: '/test-cases/',
},
{
file: '.prettierrc',
content: `{
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "es5"
}
`,
},
{
file: 'CHANGELOG.md',
content: '',
},
{
file: 'CONTRIBUTING.md',
content: `# 欢迎共建
# 注意
- 注意解决 eslint 问题
- 注意代码格式化 -- 建议安装 prettier 插件
- 发布前注意要跑通 demo 和所有的单测
## 本地调试运行 Demo
\`\`\`sh
> npm run demo
\`\`\`
## 本地跑单测
\`\`\`sh
> npm test
\`\`\`
`,
},
{
file: 'README.md',
content: `# 低代码出码自定义方案之 Hello World
## 直接执行
\`\`\`sh
> npx ali-lowcode-solution-hello-world demo-schema.json
\`\`\`
## 本地调试运行 Demo
\`\`\`sh
> npm run demo
\`\`\`
`,
},
{
file: 'demo-schema.json',
content: `{
"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": "JSFunction",
"value": "function componentDidMount() {\\n console.log('componentDidMount');\\n}"
}
},
"methodsModule": {
"type": "JSModule",
"source": "export function helloWorld() {\\n console.log('Hello world!');\\n}\\n"
},
"dataSource": {
"list": [
{
"id": "urlParams",
"type": "urlParams"
},
{
"id": "user",
"type": "fetch",
"options": {
"method": "GET",
"uri": "https://shs.xxx.com/mock/1458/demo/user",
"isSync": true
},
"dataHandler": {
"type": "JSExpression",
"value": "function (response) {\\nif (!response.data.success){\\n throw new Error(response.data.message);\\n }\\n return response.data.data;\\n}"
}
},
{
"id": "orders",
"type": "fetch",
"options": {
"method": "GET",
"uri": "https://shs.xxx.com/mock/1458/demo/orders",
"isSync": true
},
"dataHandler": {
"type": "JSExpression",
"value": "function (response) {\\nif (!response.data.success){\\n throw new Error(response.data.message);\\n }\\n return response.data.data.result;\\n}"
}
}
],
"dataHandler": {
"type": "JSExpression",
"value": "function (dataMap) {\\n console.info(\\"All datasources loaded:\\", dataMap);\\n}"
}
},
"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",
"condition": {
"type": "JSExpression",
"value": "this.index >= 1"
},
"loop": ["a", "b", "c"],
"props": {
"type": "primary",
"style": {
"margin": "0 5px 0 5px"
}
},
"children": [
{
"type": "JSExpression",
"value": "this.item"
}
]
}
]
}
]
}
]
}
]
}
],
"constants": {
"ENV": "prod",
"DOMAIN": "xxx.xxx.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": "月飞"
}
}
`,
},
{
file: 'jest.config.js',
content: `module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testPathIgnorePatterns: ['/node_modules/', '/test-cases/', '/static-files/', '/lib/'],
};
`,
},
{
file: 'package.json',
content: `{
"name": "ali-lowcode-solution-hello-world",
"version": "1.0.0",
"description": "AlLowCode Code Generate Solution - Hello World",
"files": [
"src",
"lib",
"tests",
"jest.config.js",
".editorconfig",
".eslintignore",
".eslintrc.js",
".gitignore",
".prettierignore",
".prettierrc",
"CHANGELOG.md",
"CONTRIBUTING.md",
"demo-schema.json",
"package.json",
"README.md",
"tsconfig.json"
],
"main": "lib/index.js",
"scripts": {
"start": "jest --watch",
"build": "npm run clean && concurrently 'npm run build:ts' 'npm run lint'",
"build:ts": "tsc",
"check:type": "tsc -p . --noEmit",
"clean": "rm -rf build dist lib generated",
"dev": "build-scripts start",
"lint": "eslint --ext .tsx,.ts,.js,.jsx src",
"lintfix": "eslint --fix --color --ext .tsx,.ts,.js,.jsx src",
"lint-staged": "lint-staged",
"prepublishOnly": "npm run build",
"postpublish": "git push origin master --tags",
"test": "jest",
"test:watch": "jest --watch",
"test:update-snapshots": "cross-env UPDATE_EXPECTED=true npx jest",
"demo": "npm run build && npx @alilc/lowcode-code-generator --solution . --output generated demo-schema.json"
},
"repository": {
"type": "git",
"url": "git@github.com:your-name/ali-lowcode-solution-hello-world.git"
},
"author": "",
"license": "ISC",
"publishConfig": {
"registry": "https://registry.npm.xxx.com"
},
"dependencies": {
"@alilc/lowcode-code-generator": "^1.0.0",
"@alilc/lowcode-types": "^1.0.0",
"tslib": "^2.3.0"
},
"devDependencies": {
"@types/async": "^3.2.3",
"@types/jest": "^26.0.17",
"@typescript-eslint/eslint-plugin": "^4.28.4",
"@typescript-eslint/parser": "^4.28.4",
"async": "^3.2.0",
"babel-runtime": "^6.26.0",
"concurrently": "^5.2.0",
"cross-env": "^7.0.0",
"debug": "^4.1.1",
"eslint": "^7.31.0",
"eslint-config-ali": "^12.1.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0",
"glob": "^7.2.0",
"husky": "4.2.5",
"jest": "^26.6.3",
"json5": "^2.2.0",
"lint-staged": "10.1.x",
"lodash": "^4.17.21",
"md5": "^2.2.1",
"prettier": "^2.3.2",
"ts-jest": "^26.4.4",
"ts-node": "^9.0.0",
"typescript": "4.x"
}
}
`,
},
{
file: 'tsconfig.json',
content: `{
"compilerOptions": {
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"importHelpers": true,
"incremental": false,
"jsx": "react",
"moduleResolution": "node",
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"stripInternal": true,
"outDir": "./lib",
"declarationDir": "./lib",
"rootDirs": ["./src"],
"target": "es6",
"module": "commonjs",
"lib": ["esnext"],
"types": ["jest", "node"],
"noUnusedLocals": false,
"noUnusedParameters": false
},
"include": ["src/**/*", "typings/**/*"]
}
`,
},
{
file: 'src/index.ts',
content: `import CodeGen from '@alilc/lowcode-code-generator';
import examplePlugin from './plugins/example';
export default function createHelloWorldProjectBuilder() {
return CodeGen.createProjectBuilder({
template: CodeGen.solutionParts.icejs.template,
plugins: {
components: [
CodeGen.plugins.icejs.reactCommonDeps(),
CodeGen.plugins.common.esModule({ fileType: 'jsx' }),
CodeGen.plugins.common.styleImport(),
CodeGen.plugins.icejs.containerClass(),
CodeGen.plugins.icejs.containerInjectContext(),
CodeGen.plugins.icejs.containerInjectUtils(),
CodeGen.plugins.icejs.containerInjectDataSourceEngine(),
CodeGen.plugins.icejs.containerInjectI18n(),
CodeGen.plugins.icejs.containerInjectConstants(),
CodeGen.plugins.icejs.containerInitState(),
CodeGen.plugins.icejs.containerLifeCycle(),
CodeGen.plugins.icejs.containerMethod(),
examplePlugin(),
CodeGen.plugins.icejs.jsx({
nodeTypeMapping: {
Div: 'div',
Component: 'div',
Page: 'div',
Block: 'div',
},
}),
CodeGen.plugins.style.css(),
],
pages: [
CodeGen.plugins.icejs.reactCommonDeps(),
CodeGen.plugins.common.esModule({ fileType: 'jsx' }),
CodeGen.plugins.common.styleImport(),
CodeGen.plugins.icejs.containerClass(),
CodeGen.plugins.icejs.containerInjectContext(),
CodeGen.plugins.icejs.containerInjectUtils(),
CodeGen.plugins.icejs.containerInjectDataSourceEngine(),
CodeGen.plugins.icejs.containerInjectI18n(),
CodeGen.plugins.icejs.containerInjectConstants(),
CodeGen.plugins.icejs.containerInitState(),
CodeGen.plugins.icejs.containerLifeCycle(),
CodeGen.plugins.icejs.containerMethod(),
examplePlugin(),
CodeGen.plugins.icejs.jsx({
nodeTypeMapping: {
Div: 'div',
Component: 'div',
Page: 'div',
Block: 'div',
},
}),
CodeGen.plugins.style.css(),
],
router: [
CodeGen.plugins.common.esModule(),
CodeGen.solutionParts.icejs.plugins.router(),
],
entry: [CodeGen.solutionParts.icejs.plugins.entry()],
constants: [CodeGen.plugins.project.constants()],
utils: [
CodeGen.plugins.common.esModule(),
CodeGen.plugins.project.utils('react'),
],
i18n: [CodeGen.plugins.project.i18n()],
globalStyle: [CodeGen.solutionParts.icejs.plugins.globalStyle()],
htmlEntry: [CodeGen.solutionParts.icejs.plugins.entryHtml()],
packageJSON: [CodeGen.solutionParts.icejs.plugins.packageJSON()],
},
postProcessors: [CodeGen.postprocessor.prettier()],
});
}
`,
},
{
file: 'src/plugins/example.ts',
content: `import {
ICodeStruct,
BuilderComponentPlugin,
BuilderComponentPluginFactory,
FileType,
ChunkType,
IContainerInfo,
COMMON_CHUNK_NAME,
CLASS_DEFINE_CHUNK_NAME,
DEFAULT_LINK_AFTER,
} from '@alilc/lowcode-code-generator';
export interface 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 & {
methodsModule?: {
type?: 'JSModule';
source?: string;
};
};
if (ir.methodsModule?.type !== 'JSModule' || !ir.methodsModule?.source) {
return next;
}
// 创建 methods.jsx
next.chunks.push({
type: ChunkType.STRING,
subModule: 'methods',
fileType: cfg.fileType,
name: COMMON_CHUNK_NAME.CustomContent,
content: ir.methodsModule.source,
linkAfter: [],
});
// 引入对应的模块
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: COMMON_CHUNK_NAME.InternalDepsImport,
content: "import __$$methodsModule from './methods';",
linkAfter: [...DEFAULT_LINK_AFTER[COMMON_CHUNK_NAME.InternalDepsImport]],
});
// 将导出的东东都放到 class 上实例方法部分
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
content: 'Object.assign(this, __$$methodsModule);',
linkAfter: [
...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorContent],
],
});
return next;
};
return plugin;
};
export default pluginFactory;
`,
},
{
file: 'tests/basic.test.ts',
content: `test('basic functions should be ok', () => {
// 这里放一些单元测试
expect(0).toBe(0);
});
`,
},
];
}