forked from opentiny/tiny-engine
parent
11767f2b64
commit
b343220d77
|
@ -0,0 +1,5 @@
|
|||
SQL_HOST=localhost
|
||||
SQL_PORT=3306
|
||||
SQL_USER=root
|
||||
SQL_PASSWORD=admin
|
||||
SQL_DATABASE=tiny_engine
|
11
package.json
11
package.json
|
@ -19,7 +19,9 @@
|
|||
"pub:preminor": "pnpm run build:plugin && pnpm run build:alpha && pnpm lerna version preminor --preid beta --no-push --yes && lerna publish from-package --pre-dist-tag beta --yes",
|
||||
"pub:prepatch": "pnpm run build:plugin && pnpm run build:alpha && pnpm lerna version prepatch --preid beta --no-push --yes && lerna publish from-package --pre-dist-tag beta --yes",
|
||||
"pub:prerelease": "pnpm run build:plugin && pnpm run build:alpha && pnpm lerna version prerelease --preid beta --no-push --yes && lerna publish from-package --pre-dist-tag beta --yes",
|
||||
"setup": "node ./scripts/setup.js"
|
||||
"setup": "node ./scripts/setup.js",
|
||||
"splitMaterials": "node ./scripts/splitMaterials.mjs",
|
||||
"buildMaterials": "node ./scripts/buildMaterials.mjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.21.3",
|
||||
|
@ -30,16 +32,21 @@
|
|||
"@vitejs/plugin-vue-jsx": "^1.3.2",
|
||||
"assert": "^2.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"chokidar": "^3.5.3",
|
||||
"concurrently": "^8.2.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^16.3.1",
|
||||
"eslint": "^8.38.0",
|
||||
"eslint-plugin-vue": "^8.0.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"fs-extra": "^10.1.0",
|
||||
"husky": "^8.0.0",
|
||||
"concurrently": "^8.2.0",
|
||||
"lerna": "^7.2.0",
|
||||
"less": "^4.1.2",
|
||||
"lint-staged": "^13.2.0",
|
||||
"mysql": "^2.18.1",
|
||||
"path": "^0.12.7",
|
||||
"picocolors": "^1.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup-plugin-polyfill-node": "^0.12.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
import fsExtra from 'fs-extra'
|
||||
import path from 'node:path'
|
||||
import chokidar from 'chokidar'
|
||||
import fg from 'fast-glob'
|
||||
import MysqlConnection from './connection.mjs'
|
||||
import Logger from './logger.mjs'
|
||||
|
||||
const logger = new Logger('buildMaterials')
|
||||
// 物料文件存放文件夹名称
|
||||
const materialsDir = 'materials'
|
||||
// 物料资产包
|
||||
const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json')
|
||||
// mockServer应用数据
|
||||
const appInfoPath = path.join(process.cwd(), '/mockServer/src/services/appinfo.json')
|
||||
const appInfo = fsExtra.readJSONSync(appInfoPath)
|
||||
const bundle = {
|
||||
data: {
|
||||
framework: 'Vue',
|
||||
materials: {
|
||||
components: [],
|
||||
blocks: [],
|
||||
snippets: []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const connection = new MysqlConnection()
|
||||
|
||||
/**
|
||||
* 更新物料资产包和应用mock数据
|
||||
*/
|
||||
const write = () => {
|
||||
fsExtra.outputJSONSync(bundlePath, bundle, { spaces: 2 })
|
||||
fsExtra.outputJSONSync(appInfoPath, appInfo, { spaces: 2 })
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验组件文件数据
|
||||
* @param {string} file 组件文件路径
|
||||
* @param {object} component 组件数据
|
||||
* @returns
|
||||
*/
|
||||
const validateComponent = (file, component) => {
|
||||
const requiredFields = ['component']
|
||||
const fields = Object.keys(component)
|
||||
const requiredList = requiredFields.filter((field) => !fields.includes(field))
|
||||
|
||||
if (requiredList.length) {
|
||||
logger.error(`组件文件 ${file} 缺少必要字段:${requiredList.join('、')}。`)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
if (!component.npm) {
|
||||
logger.warn(`组件文件 ${file} 缺少 npm 字段,出码时将不能通过import语句导入组件。`)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验区块文件数据
|
||||
* @param {string} file 区块文件路径
|
||||
* @param {object} block 区块数据
|
||||
* @returns
|
||||
*/
|
||||
const validateBlock = (file, block) => {
|
||||
const requiredFields = ['label', 'assets']
|
||||
const fields = Object.keys(block)
|
||||
const requiredList = requiredFields.filter((field) => !fields.includes(field))
|
||||
|
||||
if (requiredList.length) {
|
||||
logger.error(`区块文件 ${file} 缺少必要字段:${requiredList.join('、')}。`)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取materials目录下的json文件,执行下列操作
|
||||
* 1. 合并生成物料资产包
|
||||
* 2. 更新应用的组件数据componentsMap
|
||||
* 3. 连接上数据库后,将组件数据写入数据库(新增或更新)
|
||||
*/
|
||||
const generateComponents = () => {
|
||||
try {
|
||||
fg([`${materialsDir}/**/*.json`]).then((files) => {
|
||||
if(!files.length) {
|
||||
logger.warn('物料文件夹为空,请先执行`pnpm splitMaterials`命令拆分物料资产包')
|
||||
}
|
||||
|
||||
const { components = [], snippets = [], blocks = [] } = bundle.data.materials
|
||||
const componentsMap = []
|
||||
const appInfoBlocksLabels = appInfo.blockHistories.map((item) => item.label)
|
||||
|
||||
files.forEach((file) => {
|
||||
const material = fsExtra.readJsonSync(file, { throws: false })
|
||||
|
||||
if (!material) {
|
||||
logger.error(`读取物料文件 ${file} 失败`)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (file.includes('/blocks/')) {
|
||||
const valid = validateBlock(file, material)
|
||||
|
||||
if (!valid) return
|
||||
|
||||
blocks.push(material)
|
||||
|
||||
if (!appInfoBlocksLabels.includes(material.label)) {
|
||||
appInfo.blockHistories.push(material)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const valid = validateComponent(file, material)
|
||||
|
||||
if (!valid) return
|
||||
|
||||
const { snippets: componentSnippets, category, ...componentInfo } = material
|
||||
|
||||
components.push(componentInfo)
|
||||
|
||||
const snippet = snippets.find((item) => item.group === category)
|
||||
|
||||
if (snippet) {
|
||||
componentSnippets && snippet.children.push(componentSnippets[0])
|
||||
} else if (category && componentInfo) {
|
||||
snippets.push({
|
||||
group: category,
|
||||
children: componentSnippets || []
|
||||
})
|
||||
}
|
||||
|
||||
const { component, npm = {} } = componentInfo
|
||||
|
||||
componentsMap.push({ component, npm })
|
||||
|
||||
if (connection.connected) {
|
||||
connection.initDB(material)
|
||||
}
|
||||
})
|
||||
|
||||
appInfo.materialHistory.components = componentsMap
|
||||
|
||||
write()
|
||||
})
|
||||
|
||||
logger.success('构建物料资产包成功')
|
||||
} catch (error) {
|
||||
logger.error(`构建物料资产包失败:${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 监听materials下json文件的变化
|
||||
const watcher = chokidar.watch(`${materialsDir}/**/*.json`, { ignoreInitial: true })
|
||||
|
||||
watcher.on('all', (event, file) => {
|
||||
const eventMap = {
|
||||
add: '新增',
|
||||
change: '更新',
|
||||
unlink: '删除'
|
||||
}
|
||||
|
||||
logger.info(`${eventMap[event]}组件文件 ${file}`)
|
||||
|
||||
// 监听物料文件变化,更新物料资产包
|
||||
generateComponents()
|
||||
|
||||
if (!connection.connected || event === 'unlink') return
|
||||
|
||||
const component = fsExtra.readJsonSync(path.join(process.cwd(), file))
|
||||
|
||||
if (event === 'change') {
|
||||
connection.updateComponent(component)
|
||||
} else if (event === 'add') {
|
||||
connection.insertComponent(component)
|
||||
}
|
||||
})
|
||||
|
||||
// 连接数据库
|
||||
connection
|
||||
.connect()
|
||||
.then(() => {
|
||||
connection.initUserComponentsTable().finally(() => {
|
||||
generateComponents()
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
// 未能连接数据库也可以执行更新本地mock数据
|
||||
generateComponents()
|
||||
})
|
|
@ -0,0 +1,338 @@
|
|||
import mysql from 'mysql'
|
||||
import Logger from './logger.mjs'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import dotenv from 'dotenv'
|
||||
|
||||
const logger = new Logger('buildMaterials')
|
||||
|
||||
// 先构造出.env*文件的绝对路径
|
||||
const appDirectory = fs.realpathSync(process.cwd())
|
||||
const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath)
|
||||
const pathsDotenv = resolveApp('.env')
|
||||
// 加载.env.local
|
||||
dotenv.config({ path: `${pathsDotenv}.local` })
|
||||
const { SQL_HOST, SQL_PORT, SQL_USER, SQL_PASSWORD, SQL_DATABASE } = process.env
|
||||
|
||||
// 组件表名称
|
||||
const componentsTableName = 'user_components'
|
||||
// 组件关联到物料资产包的id
|
||||
const materialHistoryId = 639
|
||||
// 数据库配置
|
||||
const mysqlConfig = {
|
||||
host: SQL_HOST, // 主机名(服务器地址)
|
||||
port: SQL_PORT, // 端口号
|
||||
user: SQL_USER, // 用户名
|
||||
password: SQL_PASSWORD, // 密码
|
||||
database: SQL_DATABASE // 数据库名称
|
||||
}
|
||||
class MysqlConnection {
|
||||
constructor(config) {
|
||||
this.config = config || mysqlConfig
|
||||
// 是否连接上了数据库
|
||||
this.connected = false
|
||||
this.connection = mysql.createConnection(this.config)
|
||||
}
|
||||
|
||||
connect() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.connection.connect((error) => {
|
||||
if (error) {
|
||||
logger.warn('未能连接到数据库,请查看数据库配置是否正确')
|
||||
reject()
|
||||
} else {
|
||||
logger.success('连接数据库成功')
|
||||
this.connected = true
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行sql语句,更新数据库
|
||||
* @param {string} sql sql语句
|
||||
* @param {string} componentName 组件名称
|
||||
*/
|
||||
query(sql) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.connection.query(sql, (error, result) => {
|
||||
if (error) {
|
||||
reject(error)
|
||||
} else {
|
||||
resolve(result)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件字段映射
|
||||
* @param {string} field 字段名
|
||||
* @returns 映射后的字段名
|
||||
*/
|
||||
fieldTransform(field) {
|
||||
const fieldMap = {
|
||||
docUrl: 'doc_url',
|
||||
devMode: 'dev_mode',
|
||||
schema: 'schema_fragment'
|
||||
}
|
||||
|
||||
return fieldMap[field] || field
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化单引号
|
||||
* @param {string} str 待格式化的字符串
|
||||
* @returns 格式化后的字符串
|
||||
*/
|
||||
formatSingleQuoteValue(str) {
|
||||
if (typeof str !== 'string') {
|
||||
return str
|
||||
}
|
||||
|
||||
return str.replace(/'/g, "\\'")
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成更新组件的sql语句
|
||||
* @param {object} component 组件数据
|
||||
* @returns 更新组件的sql语句
|
||||
*/
|
||||
updateComponent(component) {
|
||||
const values = []
|
||||
let sqlContent = `update ${componentsTableName} set `
|
||||
|
||||
Object.keys(component).forEach((key) => {
|
||||
const { [key]: value } = component
|
||||
const field = this.fieldTransform(key)
|
||||
let updateContent = ''
|
||||
|
||||
if (['id', 'component'].includes(field)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
const formatValue = this.formatSingleQuoteValue(value)
|
||||
|
||||
updateContent = `\`${field}\` = '${formatValue}'`
|
||||
} else if (typeof field === 'number' || field === null) {
|
||||
updateContent = `\`${field}\` = ${value}`
|
||||
} else {
|
||||
const formatValue = this.formatSingleQuoteValue(JSON.stringify(value))
|
||||
|
||||
updateContent = `\`${field}\` = '${formatValue}'`
|
||||
}
|
||||
|
||||
values.push(updateContent)
|
||||
})
|
||||
|
||||
sqlContent += values.join()
|
||||
sqlContent += ` where component = '${component.component}';`
|
||||
|
||||
this.query(sqlContent, component.component)
|
||||
.then(() => {
|
||||
logger.success(`更新组件 ${component.component} 成功`)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.success(`更新组件 ${component.component} 失败:${error}`)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建的组件关联物料资产包
|
||||
* @param {number} id 新建的组件id
|
||||
*/
|
||||
relationMaterialHistory(id) {
|
||||
const uniqSql = `SELECT * FROM \`material_histories_components__user_components_mhs\` WHERE \`material-history_id\`=${materialHistoryId} AND \`user-component_id\`=${id}`
|
||||
this.query(uniqSql).then((result) => {
|
||||
if (!result.length) {
|
||||
const sqlContent = `INSERT INTO \`material_histories_components__user_components_mhs\` (\`material-history_id\`, \`user-component_id\`) VALUES (${materialHistoryId}, ${id})`
|
||||
|
||||
this.query(sqlContent)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成新增组件的sql语句
|
||||
* @param {object} component 组件数据
|
||||
* @returns 新增组件的sql语句
|
||||
*/
|
||||
insertComponent(component) {
|
||||
const {
|
||||
version,
|
||||
name,
|
||||
component: componentName,
|
||||
icon,
|
||||
description,
|
||||
docUrl,
|
||||
screenshot,
|
||||
tags,
|
||||
keywords,
|
||||
devMode,
|
||||
npm,
|
||||
group,
|
||||
category,
|
||||
priority = 1,
|
||||
snippets,
|
||||
schema,
|
||||
configure,
|
||||
public: publicRight = 0,
|
||||
framework = 'vue',
|
||||
isOfficial = 0,
|
||||
isDefault = 0,
|
||||
tiny_reserved = 0,
|
||||
tenant = 1,
|
||||
createBy = 86,
|
||||
updatedBy = 86
|
||||
} = component
|
||||
const values = `('${version}',
|
||||
'${this.formatSingleQuoteValue(JSON.stringify(name))}',
|
||||
'${componentName}',
|
||||
'${icon}',
|
||||
'${this.formatSingleQuoteValue(description)}',
|
||||
'${docUrl}',
|
||||
'${screenshot}',
|
||||
'${tags}',
|
||||
'${keywords}',
|
||||
'${devMode}',
|
||||
'${this.formatSingleQuoteValue(JSON.stringify(npm))}',
|
||||
'${group}',
|
||||
'${category}',
|
||||
'${priority}',
|
||||
'${this.formatSingleQuoteValue(JSON.stringify(snippets))}',
|
||||
'${this.formatSingleQuoteValue(JSON.stringify(schema))}',
|
||||
'${this.formatSingleQuoteValue(JSON.stringify(configure))}',
|
||||
'${publicRight}',
|
||||
'${framework}',
|
||||
'${isOfficial}',
|
||||
'${isDefault}',
|
||||
'${tiny_reserved}',
|
||||
'${tenant}',
|
||||
'${createBy}',
|
||||
'${updatedBy}'
|
||||
);`
|
||||
|
||||
const sqlContent = `INSERT INTO ${componentsTableName} (version, name, component, icon, description, doc_url,
|
||||
screenshot, tags, keywords, dev_mode, npm, \`group\`, \`category\`, priority, snippets,
|
||||
schema_fragment, configure, \`public\`, framework, isOfficial, isDefault, tiny_reserved,
|
||||
tenant, createdBy, updatedBy) VALUES ${values}`.replace(/\n/g, '')
|
||||
|
||||
this.query(sqlContent, componentName)
|
||||
.then((result) => {
|
||||
const id = result.insertId
|
||||
|
||||
logger.success(`新增组件 ${component.component} 成功`)
|
||||
this.relationMaterialHistory(id)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.success(`新增组件 ${component.component} 失败:${error}`)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据库数据,判断是否已存在组件,不存在时执行新增组件
|
||||
* @param {object} component 组件数据
|
||||
*/
|
||||
initDB(component) {
|
||||
const selectSqlContent = `SELECT * FROM ${this.config.database}.${componentsTableName} WHERE component = '${component.component}'`
|
||||
|
||||
this.query(selectSqlContent)
|
||||
.then((result) => {
|
||||
if (!result.length) {
|
||||
this.insertComponent(component)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.success(`查询组件 ${component.component} 失败:${error}`)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建组件表
|
||||
* @returns promise
|
||||
*/
|
||||
createUserComponentsTable() {
|
||||
const sqlContent = `
|
||||
CREATE TABLE ${componentsTableName} (
|
||||
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
version varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
||||
name longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
||||
component varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
||||
icon varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
description varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
doc_url varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
screenshot varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
tags varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
keywords varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
dev_mode varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
||||
npm longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
||||
\`group\` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
category varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
priority int(11) NULL DEFAULT NULL,
|
||||
snippets longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
|
||||
schema_fragment longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
|
||||
configure longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
|
||||
createdBy int(11) NULL DEFAULT NULL,
|
||||
updatedBy int(11) NULL DEFAULT NULL,
|
||||
created_by int(11) NULL DEFAULT NULL,
|
||||
updated_by int(11) NULL DEFAULT NULL,
|
||||
created_at timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
public int(11) NULL DEFAULT NULL,
|
||||
framework varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
||||
isOfficial tinyint(1) NULL DEFAULT NULL,
|
||||
isDefault tinyint(1) NULL DEFAULT NULL,
|
||||
tiny_reserved tinyint(1) NULL DEFAULT NULL,
|
||||
tenant int(11) NULL DEFAULT NULL,
|
||||
component_metadata longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
|
||||
library int(11) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (id) USING BTREE,
|
||||
UNIQUE INDEX unique_component(createdBy, framework, component, version) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;
|
||||
`.replace(/\n/g, '')
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.query(sqlContent)
|
||||
.then((result) => {
|
||||
logger.success(`创建表 ${componentsTableName} 成功`)
|
||||
resolve(result)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.success(`创建表 ${componentsTableName} 失败:${error}`)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据库的组件表
|
||||
* @returns promise
|
||||
*/
|
||||
initUserComponentsTable() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 查询是否已存在表
|
||||
this.query(`SHOW TABLES LIKE '${componentsTableName}'`)
|
||||
.then((result) => {
|
||||
if (result.length) {
|
||||
// 已存在
|
||||
resolve()
|
||||
} else {
|
||||
this.createUserComponentsTable()
|
||||
.then(() => {
|
||||
resolve()
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default MysqlConnection
|
|
@ -0,0 +1,43 @@
|
|||
import colors from 'picocolors'
|
||||
|
||||
class Logger {
|
||||
constructor(command) {
|
||||
this.command = command
|
||||
}
|
||||
|
||||
output(type, msg) {
|
||||
const format = () => {
|
||||
const colorMap = {
|
||||
info: 'cyan',
|
||||
warn: 'yellow',
|
||||
error: 'red',
|
||||
success: 'green'
|
||||
}
|
||||
const time = new Date().toLocaleTimeString()
|
||||
const colorMsg = colors[colorMap[type]](msg)
|
||||
|
||||
return `[${this.command}] [${colors.dim(time)}] ${colorMsg}`
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
return console.log(format())
|
||||
}
|
||||
|
||||
info(msg) {
|
||||
this.output('info', msg)
|
||||
}
|
||||
|
||||
warn(msg) {
|
||||
this.output('warn', msg)
|
||||
}
|
||||
|
||||
error(msg) {
|
||||
this.output('error', msg)
|
||||
}
|
||||
|
||||
success(msg) {
|
||||
this.output('success', msg)
|
||||
}
|
||||
}
|
||||
|
||||
export default Logger
|
|
@ -0,0 +1,60 @@
|
|||
import fs from 'fs-extra'
|
||||
import path from 'node:path'
|
||||
import Logger from './logger.mjs'
|
||||
|
||||
const logger = new Logger('splitMaterials')
|
||||
|
||||
// 物料资产包mock数据路径
|
||||
const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json')
|
||||
// 物料文件存放文件夹名称
|
||||
const materialsDir = 'materials'
|
||||
const bundle = fs.readJSONSync(bundlePath)
|
||||
const { components, snippets, blocks } = bundle.data.materials
|
||||
|
||||
const capitalize = (str) => `${str.charAt(0).toUpperCase()}${str.slice(1)}`
|
||||
const toPascalCase = (str) => str.split('-').map(capitalize).join('')
|
||||
|
||||
/**
|
||||
* 将物料资产包拆分为单个组件
|
||||
*/
|
||||
const splitMaterials = () => {
|
||||
try {
|
||||
components.forEach((comp) => {
|
||||
snippets.some((child) => {
|
||||
const snippet = child.children.find((item) => {
|
||||
if (Array.isArray(comp.component)) {
|
||||
return toPascalCase(comp.component[0]) === toPascalCase(item.snippetName)
|
||||
}
|
||||
|
||||
return toPascalCase(comp.component) === toPascalCase(item.snippetName)
|
||||
})
|
||||
|
||||
if (snippet) {
|
||||
comp.snippets = [snippet]
|
||||
comp.category = child.group
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
const fileName = Array.isArray(comp.component) ? comp.component[0] : comp.component
|
||||
const componentPath = path.join(process.cwd(), materialsDir, 'components', `${toPascalCase(fileName)}.json`)
|
||||
|
||||
fs.outputJsonSync(componentPath, comp, { spaces: 2 })
|
||||
})
|
||||
|
||||
blocks.forEach((block) => {
|
||||
const blockPath = path.join(process.cwd(), materialsDir, 'blocks', `${block.label}.json`)
|
||||
|
||||
fs.outputJsonSync(blockPath, block, { spaces: 2 })
|
||||
})
|
||||
|
||||
logger.success('拆分物料资产包完成')
|
||||
} catch (error) {
|
||||
logger.error(`拆分物料资产包失败: ${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
splitMaterials()
|
Loading…
Reference in New Issue