@epxing/cli 0.5.0-beta.5 → 0.5.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +3 -5
- package/README.md +113 -109
- package/dist/cli.mjs +5 -2
- package/dist/skills/epxing-frontend-vue3-migrate/SKILL.md +206 -164
- package/dist/skills/epxing-frontend-vue3-migrate/pitfalls.md +743 -506
- package/dist/skills/epxing-frontend-vue3-migrate/scripts/fix-eval-paths.cjs +255 -0
- package/dist/tools/chunks/{7OXB6XHJ.mjs → ZSFF3IJH.mjs} +24 -9
- package/dist/tools/epx-create/scaffold.mjs +34 -18
- package/dist/tools/epx-migrate/detect-vue3-risks.mjs +1 -1
- package/dist/tools/epx-migrate/migrate.mjs +54 -53
- package/dist/vite.mjs +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 将参数占位符中的动态属性读取迁移为公开路径读取;业务表达式只报告。
|
|
3
|
+
const fs = require('node:fs')
|
|
4
|
+
const path = require('node:path')
|
|
5
|
+
const { createRequire } = require('node:module')
|
|
6
|
+
|
|
7
|
+
function dependencies (project) {
|
|
8
|
+
const requireProject = createRequire(path.join(project, 'package.json'))
|
|
9
|
+
try {
|
|
10
|
+
return {
|
|
11
|
+
parser: requireProject('@babel/parser'),
|
|
12
|
+
traverse: requireProject('@babel/traverse').default,
|
|
13
|
+
sfc: requireProject('@vue/compiler-sfc')
|
|
14
|
+
}
|
|
15
|
+
} catch (error) {
|
|
16
|
+
throw new Error('需要目标工程已安装的 @babel/parser、@babel/traverse 和 @vue/compiler-sfc;未自动安装依赖。' + error.message)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function nameOf (node) {
|
|
21
|
+
return node?.name || node?.value
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function componentObject (nodePath) {
|
|
25
|
+
if (!nodePath?.isObjectExpression()) return false
|
|
26
|
+
const parent = nodePath.parentPath
|
|
27
|
+
return parent?.isExportDefaultDeclaration() ||
|
|
28
|
+
(parent?.isCallExpression() && nameOf(parent.node.callee) === 'defineComponent' &&
|
|
29
|
+
parent.node.arguments[0] === nodePath.node)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function thisOwner (nodePath) {
|
|
33
|
+
let fn = nodePath.getFunctionParent()
|
|
34
|
+
while (fn?.isArrowFunctionExpression()) fn = fn.getFunctionParent()
|
|
35
|
+
if (!fn || (!fn.isObjectMethod() && !fn.isFunctionExpression())) return null
|
|
36
|
+
let member = fn.isObjectMethod() ? fn : fn.parentPath
|
|
37
|
+
if (!member?.isObjectMethod() && !member?.isObjectProperty()) return null
|
|
38
|
+
// 普通嵌套函数会改变 this,不能仅因位于组件文件中就自动处理。
|
|
39
|
+
let object = member.parentPath
|
|
40
|
+
for (let level = 0; level < 4 && object?.isObjectExpression(); level++) {
|
|
41
|
+
if (componentObject(object)) {
|
|
42
|
+
return ['methods', 'computed', 'watch', 'created', 'mounted', 'render',
|
|
43
|
+
'beforeCreate', 'beforeMount', 'updated', 'beforeUpdate',
|
|
44
|
+
'unmounted', 'beforeUnmount', 'data', 'setup'].includes(nameOf(member.node.key))
|
|
45
|
+
? (nameOf(member.node.key) === 'setup' ? null : fn)
|
|
46
|
+
: null
|
|
47
|
+
}
|
|
48
|
+
member = object.parentPath
|
|
49
|
+
if (!member?.isObjectProperty()) return null
|
|
50
|
+
object = member.parentPath
|
|
51
|
+
}
|
|
52
|
+
return null
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function placeholderRegex (node) {
|
|
56
|
+
return node?.type === 'RegExpLiteral' &&
|
|
57
|
+
/(?:\\\$\\\[|#\\\[|#\\\{)/.test(node.pattern)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function replaceCall (node) {
|
|
61
|
+
return node?.type === 'CallExpression' && node.callee.type === 'MemberExpression' &&
|
|
62
|
+
!node.callee.computed && node.callee.property.name === 'replace' &&
|
|
63
|
+
placeholderRegex(node.arguments[0])
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function placeholderKey (argPath) {
|
|
67
|
+
if (!argPath.isIdentifier()) return false
|
|
68
|
+
const binding = argPath.scope.getBinding(argPath.node.name)
|
|
69
|
+
if (!binding || !binding.constant) return false
|
|
70
|
+
const fn = binding.scope.path
|
|
71
|
+
if (binding.kind === 'param' && fn.isFunction() &&
|
|
72
|
+
fn.node.params[1]?.type === 'Identifier' && fn.node.params[1].name === argPath.node.name &&
|
|
73
|
+
replaceCall(fn.parentPath.node) && fn.parentPath.node.arguments[1] === fn.node) return true
|
|
74
|
+
if (!binding.path.isVariableDeclarator() || !replaceCall(binding.path.node.init)) return false
|
|
75
|
+
const callback = binding.path.node.init.arguments[1]
|
|
76
|
+
if (callback?.type === 'StringLiteral') return callback.value === '$1'
|
|
77
|
+
if (!callback || !['ArrowFunctionExpression', 'FunctionExpression'].includes(callback.type)) return false
|
|
78
|
+
const capture = callback.params[1]
|
|
79
|
+
if (capture?.type !== 'Identifier') return false
|
|
80
|
+
const body = callback.body.type === 'BlockStatement'
|
|
81
|
+
? (callback.body.body.length === 1 && callback.body.body[0].type === 'ReturnStatement'
|
|
82
|
+
? callback.body.body[0].argument : null)
|
|
83
|
+
: callback.body
|
|
84
|
+
return body?.type === 'Identifier' && body.name === capture.name
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function contextFor (callPath, root) {
|
|
88
|
+
if (root === 'this') return thisOwner(callPath) ? { root } : null
|
|
89
|
+
const binding = callPath.scope.getBinding(root)
|
|
90
|
+
if (binding) {
|
|
91
|
+
if (!binding.constant || !binding.path.isVariableDeclarator() ||
|
|
92
|
+
binding.path.node.init?.type !== 'ThisExpression' || !thisOwner(binding.path)) return null
|
|
93
|
+
return { root }
|
|
94
|
+
}
|
|
95
|
+
// 只在已证实属于组件的词法 this 中修复旧代码缺少的常见别名。
|
|
96
|
+
return ['that', '_this'].includes(root) && thisOwner(callPath) ? { root: 'this' } : null
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function analyzeCode (code, { filename, lang = '', offset = 0, source = code }, deps) {
|
|
100
|
+
const plugins = []
|
|
101
|
+
if (/tsx?$/.test(lang) || /\.[cm]?tsx?$/.test(filename)) plugins.push('typescript')
|
|
102
|
+
if (lang !== 'ts' && !/\.[cm]?ts$/.test(filename)) plugins.push('jsx')
|
|
103
|
+
const ast = deps.parser.parse(code, { sourceType: 'unambiguous', plugins })
|
|
104
|
+
const edits = []
|
|
105
|
+
const findings = []
|
|
106
|
+
deps.traverse(ast, {
|
|
107
|
+
CallExpression (callPath) {
|
|
108
|
+
const node = callPath.node
|
|
109
|
+
if (node.callee.type !== 'Identifier' || node.callee.name !== 'eval') return
|
|
110
|
+
// 同名业务函数不是全局 eval。
|
|
111
|
+
if (callPath.scope.getBinding('eval')) return
|
|
112
|
+
const finding = {
|
|
113
|
+
file: filename,
|
|
114
|
+
line: source.slice(0, offset + node.start).split('\n').length,
|
|
115
|
+
kind: 'review',
|
|
116
|
+
reason: '表达式、配置解析或未知路径来源,保留原代码并人工核对上下文。',
|
|
117
|
+
before: code.slice(node.start, node.end)
|
|
118
|
+
}
|
|
119
|
+
const value = node.arguments[0]
|
|
120
|
+
if (node.arguments.length === 1 && value?.type === 'TemplateLiteral' &&
|
|
121
|
+
value.expressions.length === 1 && value.quasis[1].value.cooked === '') {
|
|
122
|
+
const prefix = value.quasis[0].value.cooked
|
|
123
|
+
const match = /^(this|[A-Za-z_$][\w$]*)(\.[A-Za-z_$][\w$]*)*\.$/.exec(prefix)
|
|
124
|
+
const exprPath = callPath.get('arguments.0.expressions.0')
|
|
125
|
+
if (match && placeholderKey(exprPath)) {
|
|
126
|
+
const context = contextFor(callPath, match[1])
|
|
127
|
+
if (context) {
|
|
128
|
+
const object = context.root + prefix.slice(match[1].length, -1)
|
|
129
|
+
const key = code.slice(value.expressions[0].start, value.expressions[0].end)
|
|
130
|
+
const after = context.root + '.$_.get(' + object + ', ' + key + ')'
|
|
131
|
+
edits.push({ start: offset + node.start, end: offset + node.end, text: after })
|
|
132
|
+
Object.assign(finding, { kind: 'automatic', after, reason: '参数占位符路径读取,上下文已确认。' })
|
|
133
|
+
} else {
|
|
134
|
+
finding.reason = '参数占位符命中,但别名或 this 上下文无法确认。'
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
findings.push(finding)
|
|
139
|
+
}
|
|
140
|
+
})
|
|
141
|
+
return { edits, findings }
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function analyzeFile (filename, source, deps) {
|
|
145
|
+
if (!filename.endsWith('.vue')) return analyzeCode(source, { filename }, deps)
|
|
146
|
+
const parsed = deps.sfc.parse(source, { filename })
|
|
147
|
+
if (parsed.errors.length) throw new Error(parsed.errors.map(e => e.message || e).join('; '))
|
|
148
|
+
const result = { edits: [], findings: [] }
|
|
149
|
+
for (const block of [parsed.descriptor.script, parsed.descriptor.scriptSetup]) {
|
|
150
|
+
if (!block) continue
|
|
151
|
+
if (block.src) {
|
|
152
|
+
result.findings.push({ file: filename, line: block.loc.start.line, kind: 'review', reason: '外部 script src 需核对是否在本次 src 扫描范围内。' })
|
|
153
|
+
continue
|
|
154
|
+
}
|
|
155
|
+
const part = analyzeCode(block.content, {
|
|
156
|
+
filename, lang: block.lang || '', offset: block.loc.start.offset, source
|
|
157
|
+
}, deps)
|
|
158
|
+
result.edits.push(...part.edits)
|
|
159
|
+
result.findings.push(...part.findings)
|
|
160
|
+
}
|
|
161
|
+
const template = parsed.descriptor.template
|
|
162
|
+
for (const match of (template?.content || '').matchAll(/\beval\s*\(/g)) {
|
|
163
|
+
result.findings.push({ file: filename, line: template.loc.start.line + template.content.slice(0, match.index).split('\n').length - 1, kind: 'review', reason: '模板内 eval 需人工核对模板上下文。' })
|
|
164
|
+
}
|
|
165
|
+
return result
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function sourceFiles (directory) {
|
|
169
|
+
const result = []
|
|
170
|
+
for (const entry of fs.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
171
|
+
if (entry.isSymbolicLink()) continue
|
|
172
|
+
const file = path.join(directory, entry.name)
|
|
173
|
+
if (entry.isDirectory() && !['node_modules', '.git', '.cache', 'dist', 'lib'].includes(entry.name)) result.push(...sourceFiles(file))
|
|
174
|
+
else if (entry.isFile() && /\.(vue|[cm]?js|jsx|[cm]?ts|tsx)$/.test(entry.name) && !entry.name.endsWith('.d.ts')) result.push(file)
|
|
175
|
+
}
|
|
176
|
+
return result
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function migrate ({ project, apply = false, reportFile }, deps = dependencies(project)) {
|
|
180
|
+
project = path.resolve(project)
|
|
181
|
+
const src = path.join(project, 'src')
|
|
182
|
+
if (!fs.existsSync(src)) throw new Error('目标必须是包含 src 的前端工程:' + project)
|
|
183
|
+
const files = sourceFiles(src)
|
|
184
|
+
const pending = []
|
|
185
|
+
const findings = []
|
|
186
|
+
const errors = []
|
|
187
|
+
for (const file of files) {
|
|
188
|
+
const source = fs.readFileSync(file, 'utf8')
|
|
189
|
+
try {
|
|
190
|
+
const result = analyzeFile(file, source, deps)
|
|
191
|
+
findings.push(...result.findings)
|
|
192
|
+
if (result.edits.length) {
|
|
193
|
+
let changed = source
|
|
194
|
+
for (const edit of result.edits.sort((a, b) => b.start - a.start)) changed = changed.slice(0, edit.start) + edit.text + changed.slice(edit.end)
|
|
195
|
+
pending.push({ file, source, changed })
|
|
196
|
+
}
|
|
197
|
+
} catch (error) {
|
|
198
|
+
errors.push({ file, message: error.message })
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const report = {
|
|
202
|
+
version: 1, project, mode: apply ? 'apply' : 'preview', filesScanned: files.length,
|
|
203
|
+
automatic: findings.filter(f => f.kind === 'automatic').length,
|
|
204
|
+
review: findings.filter(f => f.kind === 'review').length,
|
|
205
|
+
filesChanged: [], findings, errors
|
|
206
|
+
}
|
|
207
|
+
// 先完成全部解析;任一文件失败时不修改源码。
|
|
208
|
+
if (apply && !errors.length && pending.length) {
|
|
209
|
+
const backupRoot = path.join(project, '.cache', 'eval-path-backups')
|
|
210
|
+
fs.mkdirSync(backupRoot, { recursive: true })
|
|
211
|
+
const backup = fs.mkdtempSync(path.join(backupRoot, 'run-'))
|
|
212
|
+
for (const entry of pending) {
|
|
213
|
+
const target = path.join(backup, path.relative(project, entry.file))
|
|
214
|
+
fs.mkdirSync(path.dirname(target), { recursive: true })
|
|
215
|
+
fs.writeFileSync(target, entry.source)
|
|
216
|
+
}
|
|
217
|
+
// 防止扫描到写入之间覆盖其它人的新改动。
|
|
218
|
+
for (const entry of pending) if (fs.readFileSync(entry.file, 'utf8') !== entry.source) throw new Error('扫描后文件已变化,未写入源码:' + entry.file)
|
|
219
|
+
for (const entry of pending) fs.writeFileSync(entry.file, entry.changed)
|
|
220
|
+
report.backup = backup
|
|
221
|
+
report.filesChanged = pending.map(entry => entry.file)
|
|
222
|
+
}
|
|
223
|
+
report.exitCode = errors.length ? 1 : ((report.review || (!apply && report.automatic)) ? 2 : 0)
|
|
224
|
+
if (reportFile) {
|
|
225
|
+
fs.mkdirSync(path.dirname(path.resolve(reportFile)), { recursive: true })
|
|
226
|
+
fs.writeFileSync(reportFile, JSON.stringify(report, null, 2) + '\n')
|
|
227
|
+
}
|
|
228
|
+
return report
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (require.main === module) {
|
|
232
|
+
try {
|
|
233
|
+
const args = process.argv.slice(2)
|
|
234
|
+
if (args.includes('--help')) {
|
|
235
|
+
console.log('用法:node fix-eval-paths.cjs <前端工程> [--apply] [--report <JSON文件>]\n默认只读预览;--apply 先备份后改写。退出码:0 已处理,2 有待修复/待复核项,1 解析或依赖失败。')
|
|
236
|
+
} else {
|
|
237
|
+
const options = { project: null, apply: false }
|
|
238
|
+
for (let i = 0; i < args.length; i++) {
|
|
239
|
+
if (args[i] === '--apply') options.apply = true
|
|
240
|
+
else if (args[i] === '--report' && args[i + 1] && !args[i + 1].startsWith('--')) options.reportFile = args[++i]
|
|
241
|
+
else if (!args[i].startsWith('--') && !options.project) options.project = path.resolve(args[i])
|
|
242
|
+
else throw new Error('未知或不完整参数:' + args[i])
|
|
243
|
+
}
|
|
244
|
+
if (!options.project) throw new Error('请指定前端工程;使用 --help 查看用法。')
|
|
245
|
+
const report = migrate(options)
|
|
246
|
+
console.log(JSON.stringify(report, null, 2))
|
|
247
|
+
process.exitCode = report.exitCode
|
|
248
|
+
}
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.error(error.message)
|
|
251
|
+
process.exitCode = 1
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
module.exports = { dependencies, analyzeCode, analyzeFile, migrate }
|
|
@@ -1,4 +1,18 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as o}from"./OVN5O3EZ.mjs";var a=`import { createRequire } from 'node:module'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { spawnSync } from 'node:child_process'
|
|
4
|
+
|
|
5
|
+
const require = createRequire(import.meta.url)
|
|
6
|
+
const args = process.argv.slice(2)
|
|
7
|
+
const full = args.includes('--full') || process.env.npm_config_full === 'true'
|
|
8
|
+
const lazy = full ? 'false' : (process.env.LAZY_LIB || 'true')
|
|
9
|
+
const vite = path.join(path.dirname(require.resolve('vite/package.json')), 'bin/vite.js')
|
|
10
|
+
const result = spawnSync(process.execPath, [vite, 'build', ...args.filter(arg => arg !== '--full')], {
|
|
11
|
+
stdio: 'inherit', env: { ...process.env, LAZY_LIB: lazy }
|
|
12
|
+
})
|
|
13
|
+
if (result.error) throw result.error
|
|
14
|
+
process.exit(result.status ?? 1)
|
|
15
|
+
`;function c(n="5.3.0-beta.2"){let i=n.match(/^[~^]?(\d+)\.(\d+)\.(\d+)(?:-([\w.-]+))?$/);if(!i)return!1;let[,r,t,e,s]=i,p=Number(r)*1e6+Number(t)*1e3+Number(e);return p!==5003e3?p>5003e3:!s||/^beta\.(\d+)$/.test(s)&&Number(s.slice(5))>=2}o(c,"usesAutomaticStyles");var l=["@epxing/core/style.css","@epxing/components/style.css","@epxing/business/style.css"],m={main:`import { createApp } from '@epxing/core'
|
|
2
16
|
import Components from '@epxing/components'
|
|
3
17
|
import Business from '@epxing/business'
|
|
4
18
|
import '@epxing/theme'
|
|
@@ -26,10 +40,10 @@ const count = ref(0)
|
|
|
26
40
|
<style scoped>
|
|
27
41
|
.product-start { padding: var(--epx-space-4, 24px); color: var(--epx-text); }
|
|
28
42
|
</style>
|
|
29
|
-
`};function
|
|
43
|
+
`};function g(n,i,r){let t=o(s=>(s||"").replaceAll(`\r
|
|
30
44
|
`,`
|
|
31
|
-
`).trim(),"normalize"),e=t(
|
|
32
|
-
`,"");return e===t(
|
|
45
|
+
`).trim(),"normalize"),e=t(n);for(let s of l)e=e.replace(`import '${s}'
|
|
46
|
+
`,"");return e===t(m.main)&&t(i)===t(m.app.replaceAll("__NAME__",r))}o(g,"isLegacyWelcomeProduct");function x(n,i){let r={...n,"build-lib.mjs":a,"package.json":JSON.stringify({name:"__NAME__",version:"0.1.0",private:!0,runtime:"vue3",type:"module",scripts:{dev:"vite","build:lib":"node build-lib.mjs","build:lib:full":"node build-lib.mjs --full","build:lib:lazy":"cross-env LAZY_LIB=true vite build","build:app":"vite build --mode app",preview:"vite preview"},dependencies:{"@epxing/core":"__PACKAGES_VERSION__","@epxing/components":"__PACKAGES_VERSION__","@epxing/utils":"__PACKAGES_VERSION__","@epxing/business":"__PACKAGES_VERSION__","@epxing/theme":"__PACKAGES_VERSION__",vue:"3.5.39","vue-router":"4.6.4",vuex:"4.1.0","element-plus":"2.14.3"},devDependencies:{"@epxing/cli":"__CLI_VERSION__","@epxing/icons":"__PACKAGES_VERSION__",vite:"^6.0.0","@vitejs/plugin-vue":"^5.2.1","@vitejs/plugin-vue-jsx":"^4.1.1",sass:"^1.83.3","cross-env":"^7.0.3"}},null,2)+`
|
|
33
47
|
`,"vite.config.mjs":`import path from 'node:path'
|
|
34
48
|
import { fileURLToPath } from 'node:url'
|
|
35
49
|
import { createRequire } from 'node:module'
|
|
@@ -121,9 +135,9 @@ npm run build:app
|
|
|
121
135
|
\`\`\`
|
|
122
136
|
|
|
123
137
|
\u672C\u5730\u9884\u89C8\u9ED8\u8BA4\u7AEF\u53E3 8080\uFF0C\u9ED8\u8BA4\u6253\u5F00\u5E73\u53F0\u7CFB\u7EDF\u3002\u542F\u52A8\u524D\u5728 .env.development.local \u914D\u7F6E\u540E\u7AEF\u53CA\u5BA2\u6237\u7AEF\u3001\u7CFB\u7EDF\u3001\u5E94\u7528\u53C2\u6570\uFF1B\u767B\u5F55\u3001\u83DC\u5355\u548C\u9996\u9875\u4F7F\u7528\u5E73\u53F0\u914D\u7F6E\u3002
|
|
124
|
-
`,"PRODUCT-GUIDE.md":
|
|
125
|
-
`);for(let e of["src/main.js","PRODUCT-GUIDE.md"])
|
|
126
|
-
`+t)}return
|
|
138
|
+
`,"PRODUCT-GUIDE.md":u};if(!c(i)){let t=l.map(e=>`import '${e}'`).join(`
|
|
139
|
+
`);for(let e of["src/main.js","PRODUCT-GUIDE.md"])r[e]=r[e].replace("import '@epxing/theme'",`import '@epxing/theme'
|
|
140
|
+
`+t)}return r}o(x,"createPackageTemplates");var u=`# \u4EA7\u54C1\u5F00\u53D1\u4E0E\u5347\u7EA7\u4F7F\u7528\u8BF4\u660E
|
|
127
141
|
|
|
128
142
|
<!-- epxing-generated-product-guide -->
|
|
129
143
|
|
|
@@ -199,7 +213,8 @@ export default {
|
|
|
199
213
|
npm run build:app # dist/\uFF1A\u72EC\u7ACB\u5E94\u7528\uFF0C\u4F7F\u7528 npm \u5305
|
|
200
214
|
npx epxing lib # lib/\uFF1A\u9ED8\u8BA4\u6309\u9700\u4EA7\u54C1\u5E93
|
|
201
215
|
npx epxing lib --full # lib/\uFF1A\u5B8C\u6574\u4EA7\u54C1\u5E93
|
|
202
|
-
npm run build:lib # \
|
|
216
|
+
npm run build:lib # \u9ED8\u8BA4\u61D2\u52A0\u8F7D\uFF0C\u4E0A\u4F20\u6574\u4E2A lib/ \u76EE\u5F55
|
|
217
|
+
npm run build:lib --full # \u663E\u5F0F\u5168\u91CF\u6784\u5EFA\uFF0C\u4E5F\u53EF\u7528 build:lib:full
|
|
203
218
|
npm run build:lib:lazy # \u663E\u5F0F\u6309\u9700\u5E93\u6784\u5EFA
|
|
204
219
|
\`\`\`
|
|
205
220
|
|
|
@@ -232,4 +247,4 @@ epxing --version
|
|
|
232
247
|
\`\`\`
|
|
233
248
|
|
|
234
249
|
\u6D4B\u8BD5\u7248\u4F7F\u7528 beta \u6807\u7B7E\uFF1B\u4EA7\u54C1\u5C06 @epxing \u5E73\u53F0\u5305\u56FA\u5B9A\u5728\u540C\u4E00\u5DF2\u9A8C\u8BC1\u7248\u672C\u3002CLI \u66F4\u65B0\u4E0D\u4F1A\u81EA\u52A8\u6539\u4EA7\u54C1\u4F9D\u8D56\uFF0C\u6309 migrate \u9884\u89C8\u3001\u5BA1\u9605\u3001\u5E94\u7528\u3001\u5B89\u88C5\u3001\u6784\u5EFA\u548C\u9A8C\u6536\u7684\u987A\u5E8F\u66F4\u65B0\u3002
|
|
235
|
-
`;export{c as
|
|
250
|
+
`;export{a,c as b,l as c,g as d,x as e};
|
|
@@ -1,4 +1,18 @@
|
|
|
1
|
-
var
|
|
1
|
+
var A=Object.defineProperty;var d=(i,n)=>A(i,"name",{value:n,configurable:!0});var f=`import { createRequire } from 'node:module'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { spawnSync } from 'node:child_process'
|
|
4
|
+
|
|
5
|
+
const require = createRequire(import.meta.url)
|
|
6
|
+
const args = process.argv.slice(2)
|
|
7
|
+
const full = args.includes('--full') || process.env.npm_config_full === 'true'
|
|
8
|
+
const lazy = full ? 'false' : (process.env.LAZY_LIB || 'true')
|
|
9
|
+
const vite = path.join(path.dirname(require.resolve('vite/package.json')), 'bin/vite.js')
|
|
10
|
+
const result = spawnSync(process.execPath, [vite, 'build', ...args.filter(arg => arg !== '--full')], {
|
|
11
|
+
stdio: 'inherit', env: { ...process.env, LAZY_LIB: lazy }
|
|
12
|
+
})
|
|
13
|
+
if (result.error) throw result.error
|
|
14
|
+
process.exit(result.status ?? 1)
|
|
15
|
+
`;import l from"node:fs";import m from"node:path";import{execSync as b}from"node:child_process";import{fileURLToPath as y,pathToFileURL as j}from"node:url";function I(i="5.3.0-beta.2"){let n=i.match(/^[~^]?(\d+)\.(\d+)\.(\d+)(?:-([\w.-]+))?$/);if(!n)return!1;let[,o,t,p,a]=n,r=Number(o)*1e6+Number(t)*1e3+Number(p);return r!==5003e3?r>5003e3:!a||/^beta\.(\d+)$/.test(a)&&Number(a.slice(5))>=2}d(I,"usesAutomaticStyles");var h=["@epxing/core/style.css","@epxing/components/style.css","@epxing/business/style.css"];function v(i,n){let o={...i,"build-lib.mjs":f,"package.json":JSON.stringify({name:"__NAME__",version:"0.1.0",private:!0,runtime:"vue3",type:"module",scripts:{dev:"vite","build:lib":"node build-lib.mjs","build:lib:full":"node build-lib.mjs --full","build:lib:lazy":"cross-env LAZY_LIB=true vite build","build:app":"vite build --mode app",preview:"vite preview"},dependencies:{"@epxing/core":"__PACKAGES_VERSION__","@epxing/components":"__PACKAGES_VERSION__","@epxing/utils":"__PACKAGES_VERSION__","@epxing/business":"__PACKAGES_VERSION__","@epxing/theme":"__PACKAGES_VERSION__",vue:"3.5.39","vue-router":"4.6.4",vuex:"4.1.0","element-plus":"2.14.3"},devDependencies:{"@epxing/cli":"__CLI_VERSION__","@epxing/icons":"__PACKAGES_VERSION__",vite:"^6.0.0","@vitejs/plugin-vue":"^5.2.1","@vitejs/plugin-vue-jsx":"^4.1.1",sass:"^1.83.3","cross-env":"^7.0.3"}},null,2)+`
|
|
2
16
|
`,"vite.config.mjs":`import path from 'node:path'
|
|
3
17
|
import { fileURLToPath } from 'node:url'
|
|
4
18
|
import { createRequire } from 'node:module'
|
|
@@ -90,9 +104,9 @@ npm run build:app
|
|
|
90
104
|
\`\`\`
|
|
91
105
|
|
|
92
106
|
\u672C\u5730\u9884\u89C8\u9ED8\u8BA4\u7AEF\u53E3 8080\uFF0C\u9ED8\u8BA4\u6253\u5F00\u5E73\u53F0\u7CFB\u7EDF\u3002\u542F\u52A8\u524D\u5728 .env.development.local \u914D\u7F6E\u540E\u7AEF\u53CA\u5BA2\u6237\u7AEF\u3001\u7CFB\u7EDF\u3001\u5E94\u7528\u53C2\u6570\uFF1B\u767B\u5F55\u3001\u83DC\u5355\u548C\u9996\u9875\u4F7F\u7528\u5E73\u53F0\u914D\u7F6E\u3002
|
|
93
|
-
`,"PRODUCT-GUIDE.md":S};if(!
|
|
107
|
+
`,"PRODUCT-GUIDE.md":S};if(!I(n)){let t=h.map(p=>`import '${p}'`).join(`
|
|
94
108
|
`);for(let p of["src/main.js","PRODUCT-GUIDE.md"])o[p]=o[p].replace("import '@epxing/theme'",`import '@epxing/theme'
|
|
95
|
-
`+
|
|
109
|
+
`+t)}return o}d(v,"createPackageTemplates");var S=`# \u4EA7\u54C1\u5F00\u53D1\u4E0E\u5347\u7EA7\u4F7F\u7528\u8BF4\u660E
|
|
96
110
|
|
|
97
111
|
<!-- epxing-generated-product-guide -->
|
|
98
112
|
|
|
@@ -168,7 +182,8 @@ export default {
|
|
|
168
182
|
npm run build:app # dist/\uFF1A\u72EC\u7ACB\u5E94\u7528\uFF0C\u4F7F\u7528 npm \u5305
|
|
169
183
|
npx epxing lib # lib/\uFF1A\u9ED8\u8BA4\u6309\u9700\u4EA7\u54C1\u5E93
|
|
170
184
|
npx epxing lib --full # lib/\uFF1A\u5B8C\u6574\u4EA7\u54C1\u5E93
|
|
171
|
-
npm run build:lib # \
|
|
185
|
+
npm run build:lib # \u9ED8\u8BA4\u61D2\u52A0\u8F7D\uFF0C\u4E0A\u4F20\u6574\u4E2A lib/ \u76EE\u5F55
|
|
186
|
+
npm run build:lib --full # \u663E\u5F0F\u5168\u91CF\u6784\u5EFA\uFF0C\u4E5F\u53EF\u7528 build:lib:full
|
|
172
187
|
npm run build:lib:lazy # \u663E\u5F0F\u6309\u9700\u5E93\u6784\u5EFA
|
|
173
188
|
\`\`\`
|
|
174
189
|
|
|
@@ -201,14 +216,15 @@ epxing --version
|
|
|
201
216
|
\`\`\`
|
|
202
217
|
|
|
203
218
|
\u6D4B\u8BD5\u7248\u4F7F\u7528 beta \u6807\u7B7E\uFF1B\u4EA7\u54C1\u5C06 @epxing \u5E73\u53F0\u5305\u56FA\u5B9A\u5728\u540C\u4E00\u5DF2\u9A8C\u8BC1\u7248\u672C\u3002CLI \u66F4\u65B0\u4E0D\u4F1A\u81EA\u52A8\u6539\u4EA7\u54C1\u4F9D\u8D56\uFF0C\u6309 migrate \u9884\u89C8\u3001\u5BA1\u9605\u3001\u5E94\u7528\u3001\u5B89\u88C5\u3001\u6784\u5EFA\u548C\u9A8C\u6536\u7684\u987A\u5E8F\u66F4\u65B0\u3002
|
|
204
|
-
`;var _=m.resolve(m.dirname(
|
|
219
|
+
`;var _=m.resolve(m.dirname(y(import.meta.url)),"../.."),s={"build-lib.mjs":f};s["package.json"]=`{
|
|
205
220
|
"name": "__NAME__",
|
|
206
221
|
"version": "0.1.0",
|
|
207
222
|
"runtime": "vue3",
|
|
208
223
|
"private": true,
|
|
209
224
|
"scripts": {
|
|
210
225
|
"dev": "vite",
|
|
211
|
-
"build:lib": "
|
|
226
|
+
"build:lib": "node build-lib.mjs",
|
|
227
|
+
"build:lib:full": "node build-lib.mjs --full",
|
|
212
228
|
"build:lib:lazy": "cross-env LAZY_LIB=true vite build"
|
|
213
229
|
},
|
|
214
230
|
"dependencies": {
|
|
@@ -223,7 +239,7 @@ epxing --version
|
|
|
223
239
|
"cross-env": "^7.0.3"
|
|
224
240
|
}
|
|
225
241
|
}
|
|
226
|
-
`;
|
|
242
|
+
`;s["vite.config.mjs"]=`// \u4EA7\u54C1\u9879\u76EE Vite \u5355\u914D\u7F6E\uFF1Adev \u58F3 + \u8FDC\u7A0B\u5E93 UMD \u6784\u5EFA \u4E8C\u5408\u4E00\uFF08\u5F62\u6001\u8BF4\u660E\u89C1 epx-frame \u7684 docs/PROJECT-GUIDE.md \xA7\u4E09\uFF09\u3002
|
|
227
243
|
// npm run dev \u2192 \u8D77\u5B8C\u6574\u5E73\u53F0\u8C03\u8BD5\u4F60\u7684\u7EC4\u4EF6\uFF08:8080\uFF09
|
|
228
244
|
// npm run build:lib \u2192 lib/index.js + index.css + index.deps.json\uFF08UMD\uFF0C\u5E73\u53F0 FM_SYSTEM_WEBPACK \u52A0\u8F7D\uFF09
|
|
229
245
|
// \u4E09\u4E2A\u6587\u4EF6\u540C\u76EE\u5F55\u4E00\u8D77\u90E8\u7F72\uFF1Bdeps.json \u4E0D\u7528\u5355\u72EC\u914D url\uFF08\u5E73\u53F0\u6309 js url \u63A8\u5BFC\uFF09
|
|
@@ -255,7 +271,7 @@ export default defineConfig(({ mode }) => {
|
|
|
255
271
|
// \u4EA7\u51FA <bundle>.deps.json\uFF1A\u5E73\u53F0\u52A0\u8F7D\u672C\u8FDC\u7A0B\u5E93\u524D\u636E\u6B64\u81EA\u52A8 ensure \u7528\u5230\u7684\u61D2\u52A0\u8F7D\u7EC4\u4EF6\uFF0C
|
|
256
272
|
// \u8FDC\u7A0B\u4FA7\u65E0\u9700\u624B\u5199 await window.frame.ensure()\u3002\u8BE6\u89C1 epx-frame \u7684 docs/WINDOW-FRAME-ABI.md\u3002
|
|
257
273
|
frameDeps(),
|
|
258
|
-
// \u6253\u5305\u5F62\u6001\uFF1A\u9ED8\u8BA4\
|
|
274
|
+
// \u6253\u5305\u5F62\u6001\uFF1A\u9ED8\u8BA4\u61D2\u52A0\u8F7D\uFF0Cnpm run build:lib --full \u663E\u5F0F\u5168\u91CF\u6784\u5EFA\u3002
|
|
259
275
|
// \u300C\u6E05\u5355 + \u7EC4\u4EF6\u6309\u9700\u52A0\u8F7D\u300D\u2014\u2014\u4EA7\u7269\u591A\u51FA chunks/ shims/ index.full.js index.manifest.json\uFF0C
|
|
260
276
|
// \u90E8\u7F72\u65F6\u5FC5\u987B\u4E0A\u4F20**\u6574\u4E2A lib/ \u76EE\u5F55**\uFF08\u4E0D\u518D\u662F index.js + index.css \u4E24\u4E2A\u6587\u4EF6\uFF09\u3002
|
|
261
277
|
lazyLib({ enabled: process.env.LAZY_LIB === 'true', glob: './__DIRNAME__/**/*.vue', pkgName: pkg.name }),
|
|
@@ -330,7 +346,7 @@ export default defineConfig(({ mode }) => {
|
|
|
330
346
|
}
|
|
331
347
|
}
|
|
332
348
|
})
|
|
333
|
-
`;
|
|
349
|
+
`;s[".env.development"]=`# dev \u58F3\u7684\u5E73\u53F0\u8FD0\u884C\u65F6\u914D\u7F6E\uFF08npm run dev \u65F6\u7531 vite \u6CE8\u5165 window.*\uFF0C\u53D8\u91CF\u542B\u4E49\u540C\u5E73\u53F0 config.js\uFF09
|
|
334
350
|
# \u672C\u673A\u60F3\u8FDE\u522B\u7684\u540E\u7AEF\uFF1A\u4E0D\u8981\u6539\u8FD9\u4E2A\u6587\u4EF6\uFF0C\u65B0\u5EFA .env.development.local\uFF08\u4E0D\u8FDB git\uFF09\u8986\u76D6\u5BF9\u5E94\u884C\u5373\u53EF\uFF0C\u5982\uFF1A
|
|
335
351
|
# IP=https://test.epxing.com:88/
|
|
336
352
|
IP=https://dev.epxing.com:88/
|
|
@@ -340,7 +356,7 @@ BASE_CLIENT_ID=frame
|
|
|
340
356
|
BASE_SYSTEM_ID=epxing-frame-manage
|
|
341
357
|
BASE_APP_ID=FM_SERVICE_PLATFORM
|
|
342
358
|
WITH_CREDENTIALS=false
|
|
343
|
-
`;
|
|
359
|
+
`;s["src/index.js"]=`// \u8FDC\u7A0B\u5E93\u5165\u53E3\uFF1A\u81EA\u52A8\u6536\u96C6\u5168\u90E8\u4E1A\u52A1\u7EC4\u4EF6 + install \u6CE8\u518C\uFF08\u65B0\u589E\u7EC4\u4EF6\u96F6\u767B\u8BB0\uFF09
|
|
344
360
|
// \u672C\u9879\u76EE\u6E90\u7801\u91CC\u5199\u7684 ri- \u56FE\u6807\u89C4\u5219\uFF08\u7531 vite.config \u7684 epxIcons \u751F\u6210\uFF09\u3002
|
|
345
361
|
// \u4E0E UnoCSS \u7684 import 'uno.css' \u540C\u4E00\u7EA6\u5B9A\uFF1B\u4E00\u4E2A ri- \u90FD\u6CA1\u7528\u65F6\u5B83\u662F\u7A7A\u7684\uFF0C\u5F15\u5B83\u4E0D\u4EA7\u751F\u4F53\u79EF\u3002
|
|
346
362
|
import 'virtual:epx-icons.css'
|
|
@@ -380,7 +396,7 @@ const install = function (app, options) {
|
|
|
380
396
|
}
|
|
381
397
|
// runtime \u968F\u6784\u5EFA\u4EA7\u7269\u4EA4\u4ED8\uFF0C\u5E73\u53F0\u636E\u6B64\u6309\u5E93\u9009\u62E9\u539F\u751F\u5B89\u88C5\u6216\u65E7\u7248\u517C\u5BB9\u3002
|
|
382
398
|
export default { name, version, install, ...components, runtime: pkg.runtime }
|
|
383
|
-
`;
|
|
399
|
+
`;s["src/main.js"]=`// dev \u58F3\u5165\u53E3\uFF1A\u8D77\u5B8C\u6574\u5E73\u53F0\uFF08\u767B\u5F55/\u83DC\u5355/store/router \u5168\u6709\uFF09+ \u6302\u672C\u4EA7\u54C1\u7EC4\u4EF6\u3002
|
|
384
400
|
// \u6309\u9700\u5F15\u7528\uFF08epx-frame \u53EF\u63D2\u62D4\u5B50\u8DEF\u5F84\uFF0C\u8BE6\u89C1 frame \u4ED3\u5E93 PROJECT-GUIDE \xA7\u4E09\uFF09\uFF1A
|
|
385
401
|
// core = \u5185\u6838\uFF08createApp/store/router/\u5DE5\u5177\uFF09\uFF1Bcomponents = 113 \u4E2A\u901A\u7528\u7EC4\u4EF6\uFF1B
|
|
386
402
|
// business = \u5E73\u53F0\u7BA1\u7406\u9762/\u670D\u52A1\u5927\u5385\uFF08\u5E73\u53F0\u9875\u9762\u591A\u7531\u5B83\u62FC\u6210\uFF0C\u9ED8\u8BA4\u88C5\u4E0A\uFF09\u3002
|
|
@@ -405,7 +421,7 @@ app.use(business)
|
|
|
405
421
|
// app.use(designer); app.use(dashboard) // \u542F\u7528\u65F6\u628A\u4E0A\u9762\u5BF9\u5E94 import \u4E00\u8D77\u653E\u5F00\uFF0C\u5426\u5219 ReferenceError
|
|
406
422
|
app.use(product)
|
|
407
423
|
app.mount('#app')
|
|
408
|
-
`;
|
|
424
|
+
`;s["index.html"]=`<!DOCTYPE html>
|
|
409
425
|
<html lang="zh-CN">
|
|
410
426
|
<head>
|
|
411
427
|
<meta charset="utf-8">
|
|
@@ -418,7 +434,7 @@ app.mount('#app')
|
|
|
418
434
|
<script type="module" src="/src/main.js"></script>
|
|
419
435
|
</body>
|
|
420
436
|
</html>
|
|
421
|
-
`;
|
|
437
|
+
`;s["src/__DIRNAME__/DemoList.vue"]=`<script>
|
|
422
438
|
// \u793A\u4F8B\u7EC4\u4EF6\uFF1A\u7EE7\u627F\u5E73\u53F0 EntityList\uFF08\u4EA7\u54C1\u5F00\u53D1\u4E3B\u59FF\u52BF\u2014\u2014\u5148\u7EE7\u627F\u518D\u91CD\u5199\uFF0C\u89C1 PROJECT-GUIDE \xA7\u4E94\uFF09\u3002
|
|
423
439
|
// \u9875\u9762\u914D\u7F6E\u91CC\u7528 component: "epx-__NAME__-demo-list" \u5373\u53EF\u6E32\u67D3\u672C\u7EC4\u4EF6\u3002\u8DD1\u901A\u540E\u53EF\u5220\u3002
|
|
424
440
|
// \u6309\u9700\u5F15\u7528\u5F62\u6001\u4E0B\u4ECE\u5B50\u8DEF\u5F84\u5BFC\u5165\uFF08\u4E0E main.js \u4E00\u81F4\uFF0C\u522B\u6DF7\u7528\u805A\u5408\u5165\u53E3 'epx-frame'\uFF09\u3002
|
|
@@ -437,15 +453,15 @@ export default {
|
|
|
437
453
|
border-radius: var(--epx-radius-base, 4px);
|
|
438
454
|
}
|
|
439
455
|
</style>
|
|
440
|
-
`;
|
|
456
|
+
`;s[".gitignore"]=`node_modules/
|
|
441
457
|
lib/
|
|
442
458
|
dist/
|
|
443
459
|
*.tgz
|
|
444
460
|
.DS_Store
|
|
445
461
|
.env*.local
|
|
446
|
-
`;
|
|
447
|
-
`).pop();c="file:./"+u,console.log(" \u2713 "+u)}else c="^"+JSON.parse(l.readFileSync(m.join(_,"package.json"),"utf8")).version,console.log(` epx-frame \u4F9D\u8D56 \u2192 ${c}\uFF08\u5168\u5C40\u5B89\u88C5\u6A21\u5F0F\uFF1Bnpm i \u65F6\u9700 --registry \u516C\u53F8\u6E90\uFF09`);let E=
|
|
448
|
-
\u2713 \u9879\u76EE\u5DF2\u751F\u6210\uFF1A${e}`),
|
|
462
|
+
`;s["README.md"]='# __NAME__\n\nepx-frame \u4EA7\u54C1\u8FDC\u7A0B\u5E93\u9879\u76EE\uFF08Vite \u5F62\u6001\uFF09\u3002\u5F00\u53D1\u6307\u5357\u89C1 epx-frame \u4ED3\u5E93 `docs/PROJECT-GUIDE.md`\u3002\n\n```bash\nnpm i # \u88C5\u4F9D\u8D56\nnpm run dev # \u672C\u5730\u5F00\u53D1\uFF08:8080\uFF0C\u8D77\u5B8C\u6574\u5E73\u53F0\uFF0C\u7528\u5E73\u53F0\u8D26\u53F7\u767B\u5F55\uFF09\nnpm run build:lib # \u6784\u5EFA\u8FDC\u7A0B\u5E93 lib/index.js + index.css\n```\n\n\u90E8\u7F72\uFF1Alib \u4EA7\u7269\u53D1\u5230\u6587\u4EF6\u670D\u52A1\uFF0C\u5E73\u53F0 FM_SYSTEM_WEBPACK \u7ED9\u672C\u7CFB\u7EDF\u914D js/css \u4E24\u6761 url\u3002\n`lib/index.deps.json`\uFF08\u4F9D\u8D56\u6E05\u5355\uFF09**\u8981\u548C index.js \u540C\u76EE\u5F55\u540C\u540D\u4E00\u8D77\u4F20**\uFF0C\u4F46**\u4E0D\u7528**\u5355\u72EC\u914D url\u2014\u2014\n\u5E73\u53F0\u6309 js url \u63A8\u5BFC\u5B83\uFF0C\u52A0\u8F7D\u672C\u5E93\u524D\u5148\u5907\u597D\u7528\u5230\u7684\u61D2\u52A0\u8F7D\u5E73\u53F0\u7EC4\u4EF6\uFF1B\u6F0F\u4F20\u53EA\u4F1A\u9759\u9ED8\u9000\u5316\u4E3A\u300C\u5907\u5168\u90E8\u300D\uFF08\u591A\u4E0B\u70B9 chunk\uFF09\u3002\n\u7EC4\u4EF6\u547D\u540D\uFF1A`epx-__NAME__-<\u57DF>-<\u540D>`\uFF08\u5168\u5E73\u53F0\u552F\u4E00\uFF09\uFF1B\u65B0\u589E .vue \u5373\u81EA\u52A8\u6CE8\u518C\u3002\n\n\u6846\u67B6\u5F15\u7528\u662F**\u6309\u9700\u5B50\u8DEF\u5F84**\u5F62\u6001\uFF08`epx-frame/core` + `epx-frame/components`\uFF0C\u89C1 src/main.js \u6CE8\u91CA\uFF09\uFF1A\nbusiness/designer/dashboard \u4E0D\u88C5\u4E5F\u4F1A\u5728\u8FD0\u884C\u65F6\u6309\u9700\u61D2\u52A0\u8F7D\uFF1B\u7EC4\u4EF6\u6E90\u7801\u91CC\u4E5F\u4ECE `epx-frame/components`\n\u5BFC\u5165\u7EE7\u627F\uFF08\u522B\u548C\u805A\u5408\u5165\u53E3 `epx-frame` \u6DF7\u7528\u2014\u2014\u4F1A\u51FA\u73B0\u4E24\u5957\u8FD0\u884C\u65F6\uFF09\u3002\n\n## \u56FE\u6807\n\n**461 \u4E2A\u5E73\u53F0\u56FE\u6807\u76F4\u63A5\u5199\u5C31\u884C\uFF0C\u96F6\u914D\u7F6E**\u2014\u2014\u5B83\u4EEC\u968F epx-frame \u53D1\u5E03\uFF0C\u62FF\u5230\u5373\u7528\uFF1A\n\n```vue\n<i class="el-icon-search"></i>\n<i class="epx-icon-shezhi"></i>\n```\n\n`font-size` \u63A7\u5236\u5927\u5C0F\u3001`color` \u63A7\u5236\u989C\u8272\uFF08\u5E95\u5C42\u662F CSS mask + currentColor\uFF09\u3002\n\n\u60F3\u7528\u5E73\u53F0\u6CA1\u6709\u7684\u56FE\u6807\uFF0C\u76F4\u63A5\u5199 [Remix Icon](https://remixicon.com) \u7684\u540D\u5B57\uFF1A\n\n```vue\n<i class="ri-rocket-line"></i>\n```\n\n**\u8981\u5148 `npm i -D @iconify-json/ri`**\uFF083229 \u4E2A\u56FE\u6807\u7684\u6570\u636E\u6E90\uFF0C\u53EA\u5728\u6784\u5EFA\u671F\u8BFB\u4E00\u6B21\uFF0C\u4E0D\u8FDB\u4EA7\u7269\uFF09\u3002\n`vite.config.mjs` \u91CC\u7684 `epxIcons()` \u4F1A\u626B\u6E90\u7801\u3001\u53EA\u4E3A**\u4F60\u5B9E\u9645\u7528\u5230\u7684**\u90A3\u51E0\u4E2A\u751F\u6210\u89C4\u5219\u2014\u2014\n\u5199 5 \u4E2A\u5C31\u662F 5 \u4E2A\u7684\u4F53\u79EF\uFF0C\u4E0D\u4F1A\u628A 3229 \u4E2A\u90FD\u6253\u8FDB\u53BB\u3002\u540D\u5B57\u62FC\u9519\u4E86\u4F1A\u5728\u6784\u5EFA\u65F6\u62A5\u51FA\u6765\uFF0C\u4E0D\u4F1A\u9759\u9ED8\u53D8\u7A7A\u767D\u3002\n\n\u56FE\u6807\u540D\u5B58\u5728**\u6570\u636E\u5E93**\u91CC\uFF08\u83DC\u5355\u56FE\u6807\u3001\u6309\u94AE iconCls\u3001\u9875\u9762\u914D\u7F6E\uFF09\u7684\u90A3\u4E9B\uFF0C\u6784\u5EFA\u671F\u626B\u4E0D\u5230\u2014\u2014\n\u4F46\u5E73\u53F0\u8FD0\u884C\u65F6\u4F1A\u6309\u9700\u8865\u9F50\uFF0C\u4F60\u4E0D\u7528\u505A\u4EFB\u4F55\u4E8B\u3002\u5B8C\u6574\u8BF4\u660E\u89C1 epx-frame \u4ED3\u5E93 `docs/guide/tools/icon.md`\u3002\n\n\u540E\u7AEF\u5730\u5740\u7B49\u73AF\u5883\u914D\u7F6E\u5728 `.env.development`\uFF1B\u672C\u673A\u60F3\u8FDE\u522B\u7684\u540E\u7AEF\uFF0C\u65B0\u5EFA `.env.development.local`\n\uFF08\u4E0D\u8FDB git\uFF09\u8986\u76D6\u5BF9\u5E94\u884C\uFF08\u5982 `IP=https://test.epxing.com:88/`\uFF09\uFF0C\u91CD\u542F dev \u751F\u6548\u3002\n\n\u521B\u5EFA\u547D\u4EE4\u5DF2\u5728 package.json \u5199\u5165 `runtime: "vue3"`\uFF0C\u5E76\u7531 src/index.js \u9ED8\u8BA4\u5BFC\u51FA\u540C\u540D\u6807\u8BC6\u3002\n\u6784\u5EFA\u90E8\u7F72\u540E\u5E73\u53F0\u6309\u5305\u9009\u62E9\u5B89\u88C5\u65B9\u5F0F\uFF1A`vue3` \u8D70\u539F\u751F\u5B89\u88C5\uFF0C`vue2` \u6216\u672A\u6807\u8BC6\u7684\u5176\u5B83\u5E93\u7EE7\u7EED\u4F7F\u7528\u517C\u5BB9\u6865\u3002\n';function w({name:i,dir:n,epxFrameSpec:o,packagesVersion:t,cliVersion:p="0.5.0-beta.5"}){let a=i.toLowerCase(),r=i;if(!/^[a-z][a-z0-9-]*$/i.test(i))throw new Error(`\u4EA7\u54C1\u540D\u300C${i}\u300D\u9700\u4EE5\u5B57\u6BCD\u5F00\u5934\uFF0C\u4EC5\u542B\u5B57\u6BCD/\u6570\u5B57/-`);let e=m.resolve(n);if(t&&o)throw new Error("--packages-version \u4E0E --epx-frame \u4E0D\u80FD\u540C\u65F6\u6307\u5B9A");if(t&&!/^(?:[~^]?\d+\.\d+\.\d+(?:-[\w.-]+)?|[a-z][\w.-]*)$/.test(t))throw new Error("--packages-version \u9700\u8981 npm \u7248\u672C\u3001\u7248\u672C\u8303\u56F4\u6216\u6807\u7B7E");if(l.existsSync(e)&&l.readdirSync(e).length)throw new Error(`\u76EE\u6807\u76EE\u5F55\u975E\u7A7A\uFF1A${e}`);let c=o;if(l.mkdirSync(e,{recursive:!0}),!c&&!t)if(l.existsSync(m.join(_,"vite.config.mjs"))){if(!l.existsSync(m.join(_,"lib/epx-frame.common.js")))throw new Error("frame \u4ED3\u5E93 lib/ \u672A\u6784\u5EFA\u2014\u2014\u5148\u5728 frame-vue3 \u8DD1 pnpm build:component\uFF0C\u6216\u7528 --epx-frame \u6307\u5B9A\u6765\u6E90");console.log(" \u6253\u5305 epx-frame tarball\uFF08npm pack\uFF09\u2026");let u=b("npm pack --pack-destination "+JSON.stringify(e),{cwd:_,encoding:"utf8"}).trim().split(`
|
|
463
|
+
`).pop();c="file:./"+u,console.log(" \u2713 "+u)}else c="^"+JSON.parse(l.readFileSync(m.join(_,"package.json"),"utf8")).version,console.log(` epx-frame \u4F9D\u8D56 \u2192 ${c}\uFF08\u5168\u5C40\u5B89\u88C5\u6A21\u5F0F\uFF1Bnpm i \u65F6\u9700 --registry \u516C\u53F8\u6E90\uFF09`);let E=t?v(s,t):s;for(let[x,u]of Object.entries(E)){let g=m.join(e,x.replace("__DIRNAME__",r));l.mkdirSync(m.dirname(g),{recursive:!0}),l.writeFileSync(g,u.replaceAll("__NAME__",a).replaceAll("__DIRNAME__",r).replaceAll("__EPX_FRAME__",c||"").replaceAll("__PACKAGES_VERSION__",t||"").replaceAll("__CLI_VERSION__",p))}return b('git init -q && git add -A && git commit -qm "epx-create: \u9879\u76EE\u521D\u59CB\u5316\uFF08Vite \u5F62\u6001\u811A\u624B\u67B6\uFF09"',{cwd:e}),console.log(`
|
|
464
|
+
\u2713 \u9879\u76EE\u5DF2\u751F\u6210\uFF1A${e}`),t?(console.log(` npm install --prefix "${e}" --registry https://registry.npmjs.org/
|
|
449
465
|
cd "${e}"
|
|
450
466
|
npm run dev # :8080
|
|
451
467
|
npx epxing lib
|
|
@@ -454,4 +470,4 @@ dist/
|
|
|
454
470
|
npm i
|
|
455
471
|
npm run dev # :8080\uFF0C\u8D77\u5B8C\u6574\u5E73\u53F0\uFF08\u7528\u5E73\u53F0\u8D26\u53F7\u767B\u5F55\u540E\u5F00\u53D1\u8C03\u8BD5\uFF09
|
|
456
472
|
npm run build:lib # \u51FA lib/index.js + index.css + index.deps.json\uFF08\u4E09\u4E2A\u540C\u76EE\u5F55\u4E00\u8D77\u4F20\uFF09\u2192 \u90E8\u7F72 FM_SYSTEM_WEBPACK
|
|
457
|
-
\u7EC4\u4EF6\u5199\u5728 src/${
|
|
473
|
+
\u7EC4\u4EF6\u5199\u5728 src/${r}/\uFF08\u793A\u4F8B DemoList.vue \u8DD1\u901A\u540E\u53EF\u5220\uFF09\uFF1B\u6307\u5357\uFF1Aframe \u4ED3\u5E93 docs/PROJECT-GUIDE.md`),e)}d(w,"scaffold");var R=process.argv[1]&&import.meta.url===j(process.argv[1]).href;if(R){let i=process.argv.slice(2),n=d(r=>{let e=i.indexOf(r);if(e===-1)return null;let c=i[e+1];return i.splice(e,2),c},"take"),o=n("--dir"),t=n("--epx-frame"),p=n("--packages-version"),a=i.find(r=>!r.startsWith("-"));a||(console.error("\u7528\u6CD5\uFF1Anode tools/epx-create/scaffold.mjs <\u4EA7\u54C1\u540D> [--dir <\u76EE\u5F55>] [--epx-frame <spec>]"),process.exit(1));try{w({name:a,dir:o||m.resolve(_,"..","product",a),epxFrameSpec:t,packagesVersion:p})}catch(r){console.error("\u2717 "+r.message),process.exit(1)}}export{s as TEMPLATES,w as scaffold};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{
|
|
2
|
+
import{d as h}from"../chunks/ZSFF3IJH.mjs";import{a as g}from"../chunks/TEF5R433.mjs";import{b as x}from"../chunks/Y7JO7Q5F.mjs";import"../chunks/SIBBFYRW.mjs";import{a as l}from"../chunks/OVN5O3EZ.mjs";import r from"node:fs";import c from"node:path";var i=process.argv.slice(2).find(e=>!e.startsWith("--"));(!i||!r.existsSync(i))&&(console.error("\u7528\u6CD5\uFF1Anode tools/epx-migrate/detect-vue3-risks.mjs <\u9879\u76EE\u76EE\u5F55>"),process.exit(1));var p=[],y=l(e=>{for(let s of r.readdirSync(e,{withFileTypes:!0})){let n=c.join(e,s.name);s.isDirectory()&&!/node_modules|\.git|^lib$|^dist$/.test(s.name)?y(n):/\.(?:vue|[cm]?js|jsx|ts|tsx)$/.test(s.name)&&p.push(n)}},"walk"),f=c.join(i,"src");r.existsSync(f)&&y(f);var o=[],a=l(e=>r.existsSync(c.join(i,e))?r.readFileSync(c.join(i,e),"utf8"):"","readIf"),$=a("package.json");$&&h(a("src/main.js"),a("src/App.vue"),JSON.parse($).name)&&o.push({file:"src/main.js",rule:"R4-platform-entry",detail:"\u65E7 CLI \u8BA1\u6570\u6B22\u8FCE\u9875\u5C1A\u672A\u63A5\u5165\u5E73\u53F0\u7CFB\u7EDF\uFF1B\u4F7F\u7528\u65B0\u7248 epxing upgrade . \u9884\u89C8\uFF0C\u518D\u52A0 --apply \u4FEE\u590D\u539F\u59CB\u5165\u53E3\u3002\u81EA\u5B9A\u4E49\u5165\u53E3\u4FDD\u7559\uFF0C\u6309\u4EA7\u54C1\u7528\u9014\u6838\u5BF9\u5E73\u53F0\u8DEF\u7531\u548C\u63D2\u4EF6\u3002"});for(let e of p){let s=r.readFileSync(e,"utf8"),n=c.relative(i,e),m=g(s,{filename:e});for(let t of m.fixes)o.push({file:`${n}:${t.line}`,rule:"R2-date-format",detail:`${t.before} \u2192 ${t.after}\uFF1B\u6267\u884C\u65E5\u671F\u683C\u5F0F\u4FEE\u590D\u5668 --apply\uFF1B\u539F\u751FVue3\u5305\u4E0D\u8D70\u65E7render\u57AB\u7247\uFF08F21\uFF09`});for(let t of m.warnings)o.push({file:n,rule:"R2-date-format\u5F85\u8FFD\u8E2A",detail:t});let S=/<template[>\s]/.test(s),d=/\bextends:\s*(\w+)/.exec(s),u=(/<style[^>]*\bscoped\b[^>]*>([\s\S]*?)<\/style>/.exec(s)||[])[1]||"";if(u&&d&&!S){let t=u.match(/^[ \t]*\.[\w-][^{}\n]*\{/gm)||[];t.length&&o.push({file:n,rule:"R1-scoped\u5F85\u590D\u6838",detail:`extends ${d[1]} + <style scoped> + \u65E0 <template>\uFF0C\u4E14 scoped \u5757\u542B ${t.length} \u4E2A\u88F8\u7C7B\u9009\u62E9\u5668\uFF08\u5982 ${t[0].trim()}\uFF09\u3002\u4EC5\u63D0\u793A\u5F85\u590D\u6838\uFF0C\u4E0D\u8BC1\u660E\u6837\u5F0F\u5931\u6548\uFF1B\u5148\u4FDD\u7559 scoped\uFF0C\u7528\u6700\u7EC8\u4EA7\u7269\u9A8C\u8BC1 DOM \u4E0E CSS \u5339\u914D\u3002\u82E5\u786E\u9700\u53BB scoped\uFF0C\u987B\u540C\u65F6\u5B8C\u6210\u552F\u4E00\u547D\u540D\u7A7A\u95F4\u9694\u79BB\uFF0C\u5E76\u590D\u6D4B\u7EC4\u4EF6\u5916\u540C\u540D\u5143\u7D20\u548C\u5176\u4ED6\u9875\u9762\uFF1B\u4E0D\u8981\u4E3A\u6D88\u9664\u544A\u8B66\u6279\u91CF\u6539\u6837\u5F0F`})}}if(r.existsSync(f))for(let e of x(i)){for(let s of e.fixes)o.push({file:`${e.file}:${s.line}`,rule:"R3-theme",detail:`${s.before} \u2192 ${s.after}\uFF1B\u6267\u884C epxing theme <\u76EE\u5F55> --apply\uFF0C\u6216\u5728\u8FC1\u79FB\u65F6\u81EA\u52A8\u9002\u914D\uFF08E2\uFF09`});for(let s of e.warnings)o.push({file:e.file,rule:"R3-theme\u5F85\u590D\u6838",detail:s})}console.log(`[detect-vue3-risks] \u626B\u63CF ${p.length} \u4E2A\u7EC4\u4EF6/\u811A\u672C\u6587\u4EF6\u53CA src \u6837\u5F0F\u6587\u4EF6`);o.length===0&&(console.log(" \u2713 \u672A\u53D1\u73B0\u5DF2\u77E5\u9759\u6001\u98CE\u9669\u6A21\u5F0F"),process.exit(0));console.log(` \u26A0 \u53D1\u73B0 ${o.length} \u5904\u5F85\u590D\u6838\u98CE\u9669\u6A21\u5F0F\uFF08\u9759\u6001\u547D\u4E2D\u4E0D\u4EE3\u8868\u8FD0\u884C\u65F6\u5DF2\u5931\u6548\uFF09\uFF1A`);for(let e of o)console.log(` [${e.rule}] ${e.file}
|
|
3
3
|
${e.detail}`);process.exit(2);
|