-
Notifications
You must be signed in to change notification settings - Fork 473
feat(material): add material package #537
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
79e7718
7b7a193
4bbdbbd
af3d945
63b7157
c3312e0
3f756ec
2db8558
4adb84a
79adeb4
74a7abd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,7 +1,9 @@ | ||||||||||||||||||||||||||
| import material from '@opentiny/tiny-engine-materials' | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export default { | ||||||||||||||||||||||||||
| id: 'engine.config', | ||||||||||||||||||||||||||
| theme: 'light', | ||||||||||||||||||||||||||
| material: ['/mock/bundle.json'], | ||||||||||||||||||||||||||
| material: [material], | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainSwitching from a mock JSON URL to the materials package looks good — confirm engine compatibility and document the migration. Nice move away from hardcoded Optional (to ease migration/backward-compat): allow a fallback/toggle to the legacy bundle for now. Example: -import * as materials from '@opentiny/tiny-engine-materials'
-const material = materials.default ?? materials.material ?? materials
+import * as materials from '@opentiny/tiny-engine-materials'
+const material = materials.default ?? materials.material ?? materials
+const usePkg = !!(import.meta?.env?.VITE_USE_MATERIAL_PKG ?? true)
export default {
id: 'engine.config',
theme: 'light',
- material: [material],
+ material: [usePkg ? material : '/mock/bundle.json'],
scripts: [],
styles: []
}Quick checks you can run: 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "1) Ensure no stale references to the old mock bundle remain"
rg -n -C2 '/mock/bundle\.json' || echo "No references found."
echo
echo "2) Grep for material array handling to ensure objects are supported (heuristic)"
rg -n -C3 -S '\bmaterial\b' packages | head -n 100 || trueLength of output: 14235 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Context around material in designer-demo/src/preview.js:"
rg -n -C3 'material' designer-demo/src/preview.js || true
echo
echo "Import statements in designer-demo/src/preview.js:"
rg -n 'import ' designer-demo/src/preview.jsLength of output: 608 Confirm inline material support & document breaking change migration Engine already accepts in‐memory material objects (see “也可以传入 JSON 对象” examples in docs/api/frontend-api/preview-api.md and docs/extension-capabilities-overview/registry.md). To finish this breaking change: • Update documentation
• (Optional) provide a runtime toggle/fallback to the legacy mock bundle in designer-demo/engine.config.js: import * as materials from '@opentiny/tiny-engine-materials'
const material = materials.default ?? materials.material ?? materials
+ const usePkg = Boolean(import.meta.env.VITE_USE_MATERIAL_PKG ?? true)
export default {
id: 'engine.config',
theme: 'light',
- material: [material],
+ material: [usePkg ? material : '/mock/bundle.json'],
scripts: [],
styles: []
}• (Out-of-scope for this PR) schedule follow-up to clean up stale 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
| scripts: [], | ||||||||||||||||||||||||||
| styles: [] | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # TinyEngine 官方物料 | ||
|
|
||
| ## 使用 | ||
|
|
||
| ### 持续构建 | ||
|
|
||
| ```bash | ||
| npm run serve | ||
| ``` | ||
|
|
||
| 解释: | ||
|
|
||
| 1. 会持续监听 src 目录下文件变动,持续构建出来物料产物 | ||
|
chilingling marked this conversation as resolved.
|
||
| 2. 会启动静态服务器。 | ||
|
|
||
| ### 将组件库分别进行构建,以及将所有组件库构建成一份物料产物 | ||
|
|
||
| ```bash | ||
| npm run build | ||
|
|
||
| # 构建成功会得到比如 ElementPlus.json、TinyVue.json 等组件库对应的 json,以及 all.json | ||
| ``` | ||
|
|
||
| ### 将组件库分别进行构建 | ||
|
|
||
| ```bash | ||
| npm run build:split | ||
|
|
||
| # 构建成功会得到比如 ElementPlus.json、TinyVue.json 等组件库对应的 json | ||
| ``` | ||
|
|
||
| ## 添加自己的物料 | ||
|
|
||
| 请先大致了解 TinyEngine 物料协议:[TinyEngine物料协议](https://opentiny.design/tiny-engine#/protocol) | ||
|
|
||
| src 目录功能约定结构: | ||
|
|
||
| ```bash | ||
| src/ | ||
| |__ ElementPlus 组件库名称 | ||
| |__ Button.json ElementPlus Button组件 | ||
| |__ Table.json ElementPlus Table 组件 | ||
| ``` | ||
|
|
||
| 所以,我们添加自己的物料可以大致分为两步: | ||
|
|
||
| 1. 根据目录结构约定添加 xxx.json 组件文件 | ||
| 2. xxx.json 中根据物料协议进行书写。 | ||
|
|
||
| ## TODO | ||
|
|
||
| - [ ] 脚本自动生成组件库对应物料。 | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,267 @@ | ||||||||||||||||||||||||||||||||||||||||||
| import fsExtra from 'fs-extra' | ||||||||||||||||||||||||||||||||||||||||||
| import path from 'node:path' | ||||||||||||||||||||||||||||||||||||||||||
| import chokidar from 'chokidar' | ||||||||||||||||||||||||||||||||||||||||||
| import fg from 'fast-glob' | ||||||||||||||||||||||||||||||||||||||||||
| import { fileURLToPath } from 'node:url' | ||||||||||||||||||||||||||||||||||||||||||
| import httpServer from 'http-server' | ||||||||||||||||||||||||||||||||||||||||||
| import portFinder from 'portfinder' | ||||||||||||||||||||||||||||||||||||||||||
| import Logger from '../../scripts/logger.mjs' | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const __filename = fileURLToPath(import.meta.url) | ||||||||||||||||||||||||||||||||||||||||||
| const __dirname = path.dirname(__filename) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const logger = new Logger('buildMaterials') | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // 物料文件存放文件夹名称 | ||||||||||||||||||||||||||||||||||||||||||
| const materialsDir = path.resolve(__dirname, './src') | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||
| * 校验组件文件数据 | ||||||||||||||||||||||||||||||||||||||||||
| * @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 | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+35
to
+39
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistent validation behavior: warning with failure. The function logs a warning when the Apply this diff to align the log level with the behavior: if (!component.npm) {
- logger.warn(`组件文件 ${file} 缺少 npm 字段,出码时将不能通过import语句导入组件。`)
+ logger.error(`组件文件 ${file} 缺少 npm 字段,出码时将不能通过import语句导入组件。`)
return false
}Alternatively, if components without if (!component.npm) {
logger.warn(`组件文件 ${file} 缺少 npm 字段,出码时将不能通过import语句导入组件。`)
- return false
+ // Allow components without npm field
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return true | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const generateComponents = async (entry) => { | ||||||||||||||||||||||||||||||||||||||||||
| const files = await fg('*.json', { cwd: entry }) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (!files.length) { | ||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const bundle = { | ||||||||||||||||||||||||||||||||||||||||||
| components: [], | ||||||||||||||||||||||||||||||||||||||||||
| snippets: [], | ||||||||||||||||||||||||||||||||||||||||||
| packages: [] | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| const componentsMap = [] | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const metaInfo = fsExtra.readJsonSync(path.resolve(entry, 'meta.json'), { throws: false }) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (metaInfo?.package) { | ||||||||||||||||||||||||||||||||||||||||||
| bundle.packages.push(metaInfo.package) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| if (metaInfo?.snippets) { | ||||||||||||||||||||||||||||||||||||||||||
| bundle.snippets = metaInfo.snippets | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const componentFiles = files.filter((fileName) => { | ||||||||||||||||||||||||||||||||||||||||||
| if (fileName === 'meta.json') { | ||||||||||||||||||||||||||||||||||||||||||
| return false | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // 下划线开头的组件文件不导出 | ||||||||||||||||||||||||||||||||||||||||||
| return !fileName.startsWith('_') | ||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| componentFiles.forEach((file) => { | ||||||||||||||||||||||||||||||||||||||||||
| const material = fsExtra.readJsonSync(path.resolve(entry, file), { throws: false }) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (!material) { | ||||||||||||||||||||||||||||||||||||||||||
| const fileFullPath = path.join(process.cwd(), file) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| logger.error(`文件格式有误 (${fileFullPath})`) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+76
to
+85
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incorrect path construction in error message. Line 80 constructs the error path using Apply this diff to fix the path construction: if (!material) {
- const fileFullPath = path.join(process.cwd(), file)
+ const fileFullPath = path.resolve(entry, file)
logger.error(`文件格式有误 (${fileFullPath})`)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const valid = validateComponent(file, material) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (!valid) return | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const { snippets: componentSnippets, category, ...componentInfo } = material | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| bundle.components.push(componentInfo) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const snippet = bundle.snippets.find((item) => item.group === category) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (snippet) { | ||||||||||||||||||||||||||||||||||||||||||
| if (!snippet.children) { | ||||||||||||||||||||||||||||||||||||||||||
| snippet.children = [] | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (componentSnippets) { | ||||||||||||||||||||||||||||||||||||||||||
| snippet.children.push(...componentSnippets) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } else if (category && componentInfo && componentSnippets) { | ||||||||||||||||||||||||||||||||||||||||||
| bundle.snippets.push({ | ||||||||||||||||||||||||||||||||||||||||||
| group: category, | ||||||||||||||||||||||||||||||||||||||||||
| children: componentSnippets || [] | ||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const npmInfo = componentInfo.npm | ||||||||||||||||||||||||||||||||||||||||||
| const { package: packageName = '', exportName = '' } = npmInfo | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const mapItem = { | ||||||||||||||||||||||||||||||||||||||||||
| componentName: componentInfo.component, | ||||||||||||||||||||||||||||||||||||||||||
| package: packageName, | ||||||||||||||||||||||||||||||||||||||||||
| exportName | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (typeof npmInfo.destructuring === 'boolean') { | ||||||||||||||||||||||||||||||||||||||||||
| mapItem.destructuring = componentInfo.npm.destructuring | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (npmInfo.package) { | ||||||||||||||||||||||||||||||||||||||||||
| componentsMap.push(mapItem) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||
| bundle, | ||||||||||||||||||||||||||||||||||||||||||
| componentsMap | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const getFrameworkWithData = (data) => { | ||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||
| framework: 'Vue', | ||||||||||||||||||||||||||||||||||||||||||
| materials: data | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const buildComponents = async (config = {}) => { | ||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||
| const entries = await fg('*/', { | ||||||||||||||||||||||||||||||||||||||||||
| cwd: materialsDir, | ||||||||||||||||||||||||||||||||||||||||||
| onlyDirectories: true, | ||||||||||||||||||||||||||||||||||||||||||
| deep: 1 | ||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const { buildCombine = true } = config | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const allBundles = { | ||||||||||||||||||||||||||||||||||||||||||
| components: [], | ||||||||||||||||||||||||||||||||||||||||||
| snippets: [], | ||||||||||||||||||||||||||||||||||||||||||
| packages: [] | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| let allComponentsMap = [] | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| for (const entry of entries) { | ||||||||||||||||||||||||||||||||||||||||||
| const res = await generateComponents(path.resolve(materialsDir, `${entry}`)) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (!res) { | ||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| fsExtra.outputJSONSync(path.resolve(__dirname, `./dist/${entry}.json`), getFrameworkWithData(res.bundle), { | ||||||||||||||||||||||||||||||||||||||||||
| spaces: 2 | ||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||
| fsExtra.outputJSONSync(path.resolve(__dirname, `./dist/${entry}.compsMap.json`), res.componentsMap, { spaces: 2 }) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| allBundles.components = allBundles.components.concat(res.bundle.components) | ||||||||||||||||||||||||||||||||||||||||||
| allComponentsMap = allComponentsMap.concat(res.componentsMap) | ||||||||||||||||||||||||||||||||||||||||||
| allBundles.packages = allBundles.packages.concat(res.bundle.packages) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| for (const snippetItem of res.bundle.snippets) { | ||||||||||||||||||||||||||||||||||||||||||
| const snippet = allBundles.snippets.find((item) => item.group === snippetItem.group) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (snippet) { | ||||||||||||||||||||||||||||||||||||||||||
| if (!snippet.children) { | ||||||||||||||||||||||||||||||||||||||||||
| snippet.children = [] | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| snippet.children.push(...(snippetItem.children || [])) | ||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
| allBundles.snippets.push(snippetItem) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (buildCombine) { | ||||||||||||||||||||||||||||||||||||||||||
| fsExtra.outputJSONSync(path.resolve(__dirname, `./dist/index.json`), getFrameworkWithData(allBundles), { | ||||||||||||||||||||||||||||||||||||||||||
| spaces: 2 | ||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||
| fsExtra.outputJSONSync(path.resolve(__dirname, `./dist/index.compsMap.json`), allComponentsMap, { spaces: 2 }) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| logger.success('物料资产包构建成功') | ||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||
| logger.error(`物料资产包构建失败:${error}`) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // 持续构建 | ||||||||||||||||||||||||||||||||||||||||||
| async function serve() { | ||||||||||||||||||||||||||||||||||||||||||
| // 监听materials下json文件的变化 | ||||||||||||||||||||||||||||||||||||||||||
| const watcher = chokidar.watch(`${materialsDir}/**/*.json`, { ignoreInitial: true }) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| watcher.on('all', (event, file) => { | ||||||||||||||||||||||||||||||||||||||||||
| const eventMap = { | ||||||||||||||||||||||||||||||||||||||||||
| add: '新增', | ||||||||||||||||||||||||||||||||||||||||||
| change: '更新', | ||||||||||||||||||||||||||||||||||||||||||
| unlink: '删除' | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| const fileFullPath = path.join(process.cwd(), file) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| logger.info(`${eventMap[event]}组件文件 (${fileFullPath})`) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // 监听物料文件变化,更新物料资产包 | ||||||||||||||||||||||||||||||||||||||||||
| buildComponents() | ||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // 第一次需要手动出发构建一遍 | ||||||||||||||||||||||||||||||||||||||||||
| await buildComponents() | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const staticServerPort = await portFinder.getPortPromise({ port: 4001 }) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const server = httpServer.createServer({ | ||||||||||||||||||||||||||||||||||||||||||
| caches: 1, | ||||||||||||||||||||||||||||||||||||||||||
| cors: true, | ||||||||||||||||||||||||||||||||||||||||||
| root: path.resolve(__dirname, './dist') | ||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| server.listen(staticServerPort, () => { | ||||||||||||||||||||||||||||||||||||||||||
| logger.success(`物料服务已启动 http://127.0.0.1:${staticServerPort}`) | ||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // 单次构建,分组件库 | ||||||||||||||||||||||||||||||||||||||||||
| function buildSplit() { | ||||||||||||||||||||||||||||||||||||||||||
| buildComponents({ buildCombine: false }) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // 单次构建,合并所有组件库 | ||||||||||||||||||||||||||||||||||||||||||
| function build() { | ||||||||||||||||||||||||||||||||||||||||||
| buildComponents() | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| function start() { | ||||||||||||||||||||||||||||||||||||||||||
| const commandsMap = { | ||||||||||||||||||||||||||||||||||||||||||
| serve: serve, | ||||||||||||||||||||||||||||||||||||||||||
| build: build, | ||||||||||||||||||||||||||||||||||||||||||
| 'build:split': buildSplit | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const command = process.argv.slice(2) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (!commandsMap[command]) { | ||||||||||||||||||||||||||||||||||||||||||
| logger.error(`[@opentiny/tiny-engine-materials] 不支持${command}命令`) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| commandsMap[command]() | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+249
to
+265
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Command argument extracted incorrectly. Line 256 uses Apply this diff to fix the bug: - const command = process.argv.slice(2)
+ const command = process.argv[2]
if (!commandsMap[command]) {Alternatively, extract the first element explicitly: - const command = process.argv.slice(2)
+ const [command] = process.argv.slice(2)
if (!commandsMap[command]) {🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| start() | ||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| { | ||
| "name": "@opentiny/tiny-engine-materials", | ||
| "version": "1.0.0", | ||
| "description": "", | ||
|
chilingling marked this conversation as resolved.
|
||
| "main": "dist/index.json", | ||
| "module": "dist/index.json", | ||
| "type": "module", | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1", | ||
| "serve": "node buildMaterials.mjs serve", | ||
| "build": "node buildMaterials.mjs build", | ||
| "build:split": "node buildMaterials.mjs build:split" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 外层也有两个物料的命令,看下是不是一起整合下
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 全体迁移完成后再整合 |
||
| }, | ||
| "keywords": [], | ||
| "publishConfig": { | ||
| "access": "public" | ||
| }, | ||
| "files": [ | ||
| "dist" | ||
| ], | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/opentiny/tiny-engine", | ||
| "directory": "packages/materials" | ||
| }, | ||
| "bugs": { | ||
| "url": "https://github.com/opentiny/tiny-engine/issues" | ||
| }, | ||
| "author": "OpenTiny Team", | ||
| "license": "MIT", | ||
| "homepage": "https://opentiny.design/tiny-engine", | ||
| "devDependencies": { | ||
| "chokidar": "^3.5.3", | ||
| "fast-glob": "^3.3.2", | ||
| "fs-extra": "^11.2.0", | ||
| "http-server": "^14.1.1", | ||
| "portfinder": "^1.0.32" | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Default import may not match the package’s export shape — consider interop-safe import.
If
@opentiny/tiny-engine-materialsdoes not export a default (e.g., CommonJS export or named export), this will break at runtime. Use a namespace import and normalize to amaterialobject for robustness.Apply this diff:
To verify the export shape of the materials package and the dependency wiring, run:
🏁 Script executed:
Length of output: 1001
Ensure interop-safe import of
@opentiny/tiny-engine-materialsThe
@opentiny/tiny-engine-materialspackage has no default export, so this will break at runtime:designer-demo/engine.config.js:1
This normalizes the import to work with both ESM and CJS export shapes.
📝 Committable suggestion
🤖 Prompt for AI Agents