@epxing/cli 0.3.0 → 0.3.1
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/README.md +3 -1
- package/dist/lazy-lib.mjs +5 -5
- package/dist/lib-vite-config.mjs +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
独立的工程开发工具,包含交互菜单、开发服务、工程与产品库构建、创建、Vue3 迁移、静态检查和升级技能安装。CLI 使用自己的版本号,目标平台由 `--epx-frame` 指定;发布包没有 npm 运行时依赖。启动、构建调用当前工程的脚本及本地依赖;迁移代码与框架仓库的 `tools/` 共用,打包时编译为独立 Node 程序。
|
|
4
4
|
|
|
5
5
|
```powershell
|
|
6
|
-
npm install -g @epxing/cli@0.3.
|
|
6
|
+
npm install -g @epxing/cli@0.3.1 --registry https://registry.npmjs.org/
|
|
7
7
|
epx # ↑↓ + Enter 选择;Esc / Ctrl+C 取消
|
|
8
8
|
epx dev --port 3000
|
|
9
9
|
epx build --mode prd
|
|
@@ -42,6 +42,8 @@ epx skill install --dir E:/products/my-product
|
|
|
42
42
|
|
|
43
43
|
产品懒加载构建需要 Vite 库配置(`build.lib`)、Vue 3 编译器和入口中的 `import.meta.glob('./产品目录/**/*.vue', { eager: true })`。CLI 使用产品本地 Vite 加载原配置;未接入按需插件时通过临时配置补入共享插件,不修改产品源码或原配置。已有按需插件保留其 eager 等自定义设置。构建后验证本次生成的 `index.manifest.json`、组件 chunks 和 `index.full.js`,缺少或沿用旧产物会报错,避免完整包被误判为懒加载成功。部署时上传整个输出目录(包含 CSS、chunks 和兜底包)。`--full` 会关闭按需插件;`--full` 与 `--lazy` 互斥。旧 webpack 产品先迁移到 Vite,或使用 `--full` 完整打包。自定义非 Vite 脚本须自行生成标准 `lib/` 按需产物。直接执行 `npm run build:lib` 仍由产品原脚本决定构建方式。
|
|
44
44
|
|
|
45
|
+
0.3.1 同时支持 `{ eager: true, import: 'default' }` 的直接组件入口写法。未显式设置 `assetsInlineLimit` 时,组件拆分保持 Vite 库模式的默认资源内联行为,避免图片改成平台根路径引用。
|
|
46
|
+
|
|
45
47
|
`--mode/-m`、`--port/-p` 支持旧的 `-mprd`、`-p3000` 写法。build 优先匹配 `build:<mode>`;`localize` 也匹配 `build:local`,其余情况向构建脚本传入 `--mode`。平台 `build:component` 包含多步构建,不追加 `--mode`,环境由工程脚本统一配置。
|
|
46
48
|
|
|
47
49
|
平台 `epx build` 保留 `--thin`、`--no-designer`、`--no-dashboard`;产品工程不接受平台裁剪选项。需向工程脚本透传其他参数时使用 `--`,如 `epx dev -- --host 0.0.0.0`。脚本原有的 pre/post 生命周期、自定义环境和多步构建会保留,失败退出码向上传递。
|
package/dist/lazy-lib.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import h from"node:fs";import y from"node:path";import{build as B}from"epxing:project-vite";import j from"node:fs";import v from"node:path";import{parse as V,babelParse as T}from"epxing:project-sfc";function W(e){return j.readFileSync(e,"utf8").split(`\r
|
|
2
2
|
`).join(`
|
|
3
|
-
`)}function
|
|
3
|
+
`)}function G(e){let s=e.split(`\r
|
|
4
4
|
`).join(`
|
|
5
|
-
`),n="";try{let{descriptor:r}=V(s);n=r.script&&r.script.content||r.scriptSetup&&r.scriptSetup.content||""}catch{return null}if(!n)return null;try{let i=T(n,{sourceType:"module",plugins:["jsx","typescript","decorators-legacy"]}).program.body,t=l=>{if(!l||l.type!=="ObjectExpression")return null;for(let u of l.properties){if(u.type!=="ObjectProperty"||u.computed)continue;if((u.key.type==="Identifier"?u.key.name:u.key.type==="StringLiteral"?u.key.value:null)==="name"&&u.value.type==="StringLiteral")return u.value.value}return null},a=i.find(l=>l.type==="ExportDefaultDeclaration");if(!a)return null;let o=t(a.declaration);if(o)return o;if(a.declaration.type==="Identifier"){let l=a.declaration.name;for(let u of i)if(u.type==="VariableDeclaration"){for(let m of u.declarations)if(m.id.type==="Identifier"&&m.id.name===l){let b=t(m.init);if(b)return b}}}if(a.declaration.type==="CallExpression")for(let l of a.declaration.arguments){let u=t(l);if(u)return u}return null}catch{return null}}function
|
|
5
|
+
`),n="";try{let{descriptor:r}=V(s);n=r.script&&r.script.content||r.scriptSetup&&r.scriptSetup.content||""}catch{return null}if(!n)return null;try{let i=T(n,{sourceType:"module",plugins:["jsx","typescript","decorators-legacy"]}).program.body,t=l=>{if(!l||l.type!=="ObjectExpression")return null;for(let u of l.properties){if(u.type!=="ObjectProperty"||u.computed)continue;if((u.key.type==="Identifier"?u.key.name:u.key.type==="StringLiteral"?u.key.value:null)==="name"&&u.value.type==="StringLiteral")return u.value.value}return null},a=i.find(l=>l.type==="ExportDefaultDeclaration");if(!a)return null;let o=t(a.declaration);if(o)return o;if(a.declaration.type==="Identifier"){let l=a.declaration.name;for(let u of i)if(u.type==="VariableDeclaration"){for(let m of u.declarations)if(m.id.type==="Identifier"&&m.id.name===l){let b=t(m.init);if(b)return b}}}if(a.declaration.type==="CallExpression")for(let l of a.declaration.arguments){let u=t(l);if(u)return u}return null}catch{return null}}function K(e){return e.replace(/(\.\/|\.vue|\/)/g,"")}function O(e,s){let n=v.resolve(e,s),r=[],i=t=>{let a=j.readdirSync(t,{withFileTypes:!0}).sort((o,l)=>o.name<l.name?-1:1);for(let o of a){let l=v.join(t,o.name);if(o.isDirectory())i(l);else if(o.name.endsWith(".vue")){let m="./"+v.relative(e,l).split(v.sep).join("/");r.push({globKey:m,file:l,key:G(W(l))||K(m)})}}};return j.existsSync(n)&&i(n),r.sort((t,a)=>t.globKey<a.globKey?-1:1)}function z(e){let s=new Map;for(let n of e){if(s.has(n.key))throw new Error(`[lazy-lib] \u7EC4\u4EF6\u6CE8\u518C\u540D\u51B2\u7A81\uFF1A'${n.key}' \u540C\u65F6\u6765\u81EA
|
|
6
6
|
${s.get(n.key)}
|
|
7
7
|
${n.file}
|
|
8
|
-
\u5355\u4F53\u5F62\u6001\u4E0B\u662F\u540E\u8005\u9759\u9ED8\u8986\u76D6\u524D\u8005\uFF1B\u6309\u9700\u5F62\u6001\u4E0B\u4E24\u4E2A chunk \u62A2\u540C\u4E00\u4E2A\u540D\u5B57\uFF0C\u5FC5\u987B\u5148\u6539\u6389\u5176\u4E2D\u4E00\u4E2A\u7EC4\u4EF6\u7684 name\uFF08\u6216\u6587\u4EF6\u8DEF\u5F84\uFF09\u3002`);s.set(n.key,n.file)}return e}var
|
|
8
|
+
\u5355\u4F53\u5F62\u6001\u4E0B\u662F\u540E\u8005\u9759\u9ED8\u8986\u76D6\u524D\u8005\uFF1B\u6309\u9700\u5F62\u6001\u4E0B\u4E24\u4E2A chunk \u62A2\u540C\u4E00\u4E2A\u540D\u5B57\uFF0C\u5FC5\u987B\u5148\u6539\u6389\u5176\u4E2D\u4E00\u4E2A\u7EC4\u4EF6\u7684 name\uFF08\u6216\u6587\u4EF6\u8DEF\u5F84\uFF09\u3002`);s.set(n.key,n.file)}return e}var U=[{test:e=>e==="vue",global:"window.frame && window.frame.Vue"},{test:e=>e==="vuex",global:"window.frame && window.frame.vuex"},{test:e=>e==="vue-router",global:"window.frame && window.frame.router"},{test:e=>e==="epx-frame"||e.startsWith("epx-frame/"),global:"window.epxFrame"}],L=/^[A-Za-z_$][\w$]*$/,R=(e,s)=>{if(!s)return null;let n=typeof s=="function"?s(e):s[e];return typeof n=="string"&&n?n:null};function q(e,s){let n=U.find(i=>i.test(e));if(n)return n.global;let r=R(e,s);if(r)return`window.${r}`;throw new Error(`[lazy-lib] external '${e}' \u6CA1\u6709\u5BF9\u5E94\u7684\u8FD0\u884C\u65F6\u5168\u5C40\u6620\u5C04\u3002
|
|
9
9
|
ESM chunk \u91CC\u7684\u88F8\u8BF4\u660E\u7B26\u6D4F\u89C8\u5668\u89E3\u6790\u4E0D\u4E86\uFF0C\u5FC5\u987B\u7ECF shim \u6865\u5230 window \u4E0A\u7684\u5168\u5C40\u3002
|
|
10
10
|
\u5E73\u53F0\u5185\u7F6E\u6620\u5C04\uFF1Avue \u2192 window.frame.Vue\uFF1Bvuex \u2192 window.frame.vuex\uFF1B
|
|
11
11
|
vue-router \u2192 window.frame.router\uFF1Bepx-frame\uFF08\u542B\u5B50\u8DEF\u5F84\uFF09\u2192 window.epxFrame\u3002
|
|
@@ -18,7 +18,7 @@ import h from"node:fs";import y from"node:path";import{build as B}from"epxing:pr
|
|
|
18
18
|
\u539F\u56E0\uFF1A'*' \u6765\u81EA import * as ns from '...' \u7C7B\u547D\u540D\u7A7A\u95F4\u5BFC\u5165\uFF1Bshim \u65E0\u6CD5\u9759\u6001\u679A\u4E3E\u4F7F\u7528\u65B9\u4F1A\u8BBF\u95EE\u54EA\u4E9B\u540D\u5B57\u3002
|
|
19
19
|
\u6539\u6CD5\uFF1A\u6539\u7528\u5177\u540D\u5BFC\u5165\uFF0C\u5982 import { someExport } from ... \u800C\u975E import * as ns from ...`);return[`// \u6784\u5EFA\u671F\u751F\u6210\uFF08epx-frame lazy-lib\uFF09\uFF1A\u8FD0\u884C\u65F6\u4ECE ${r} \u53D6\u5E73\u53F0\u5355\u4F8B\uFF0C\u52FF\u624B\u6539\u3002`,`const S = ${r}`,...t.map(o=>`export const ${o} = S[${JSON.stringify(o)}]`),"export default (S && S.default) || S"].join(`
|
|
20
20
|
`)+`
|
|
21
|
-
`}function N(e){let s=new Map;for(let n in e){let r=e[n];if(r.type==="chunk")for(let i in r.importedBindings||{}){s.has(i)||s.set(i,new Set);for(let t of r.importedBindings[i])s.get(i).add(t)}}return s}import k from"node:path";var Z=(e,s)=>{let n=k.resolve(e),r=k.resolve(s);return n===r||n.startsWith(r+k.sep)||n.startsWith(r+"/")},E=e=>k.resolve(String(e).split("?")[0]);function A(e,s,n,r){let i=new Set((r||[]).map(E)),t=[...e()].filter(d=>Z(d,n)),a=new Set(t),o=new Map,l=[],u=[],m=d=>{let g=new Set;for(let f of d){let c=E(f);i.has(c)&&g.add(c)}return g.size},b=d=>{let g=o.get(d)||0;if(g===2)return;if(g===1){let c=[...l.slice(l.indexOf(d)),d];m(c)>=2&&u.push(c);return}o.set(d,1),l.push(d);let f=s(d)||{};for(let c of f.importedIds||[])a.has(c)&&b(c);l.pop(),o.set(d,2)};for(let d of t)b(d);return u}var $="\0epx-lazy-glob",I=/import\.meta\.glob\(\s*(['"])([^'"]+)\1\s*,\s*\{\s*eager\s*:\s*true\s*\}\s*\)/;function X(e={}){let{enabled:s=!1,glob:n,eager:r=[],pkgName:i}=e,t=null,a=null,o=[],l=new Set,u="",m="",b="",d="",g=[];return{name:"epx-lazy-lib",apply:"build",enforce:"pre",config(f){return s?(g=(Array.isArray(f.plugins)?f.plugins.flat(1/0):[]).filter(c=>c&&c.name!=="epx-lazy-lib"),{build:{emptyOutDir:!1}}):null},configResolved(f){t=f,m=y.resolve(f.root,f.build.outDir);let c=f.build.lib&&f.build.lib.entry;b=Array.isArray(c)?c[0]:typeof c=="object"?Object.values(c)[0]:c,u=y.dirname(b),d=i||y.basename(f.root)},async buildStart(){if(!s)return;n||this.error("[lazy-lib] \u7F3A\u5C11 glob \u9009\u9879\uFF08\u5F62\u5982 './<\u4EA7\u54C1\u540D>/**/*.vue'\uFF09");let f=Y(t.root,m);f&&this.error(f);let c=n.replace(/^\.\//,"").split("/")[0];o=z(O(u,c)),o.length||this.error(`[lazy-lib] \u6309 glob \u4E00\u4E2A .vue \u90FD\u6CA1\u626B\u5230\uFF0C\u65E0\u6CD5\u6309\u9700\u62C6\u5305\u3002
|
|
21
|
+
`}function N(e){let s=new Map;for(let n in e){let r=e[n];if(r.type==="chunk")for(let i in r.importedBindings||{}){s.has(i)||s.set(i,new Set);for(let t of r.importedBindings[i])s.get(i).add(t)}}return s}import k from"node:path";var Z=(e,s)=>{let n=k.resolve(e),r=k.resolve(s);return n===r||n.startsWith(r+k.sep)||n.startsWith(r+"/")},E=e=>k.resolve(String(e).split("?")[0]);function A(e,s,n,r){let i=new Set((r||[]).map(E)),t=[...e()].filter(d=>Z(d,n)),a=new Set(t),o=new Map,l=[],u=[],m=d=>{let g=new Set;for(let f of d){let c=E(f);i.has(c)&&g.add(c)}return g.size},b=d=>{let g=o.get(d)||0;if(g===2)return;if(g===1){let c=[...l.slice(l.indexOf(d)),d];m(c)>=2&&u.push(c);return}o.set(d,1),l.push(d);let f=s(d)||{};for(let c of f.importedIds||[])a.has(c)&&b(c);l.pop(),o.set(d,2)};for(let d of t)b(d);return u}var $="\0epx-lazy-glob",I=/import\.meta\.glob\(\s*(['"])([^'"]+)\1\s*,\s*\{\s*(?:import\s*:\s*['"]default['"]\s*,\s*)?eager\s*:\s*true\s*(?:,\s*import\s*:\s*['"]default['"]\s*)?,?\s*\}\s*\)/;function X(e={}){let{enabled:s=!1,glob:n,eager:r=[],pkgName:i}=e,t=null,a=null,o=[],l=new Set,u="",m="",b="",d="",g=[];return{name:"epx-lazy-lib",apply:"build",enforce:"pre",config(f){return s?(g=(Array.isArray(f.plugins)?f.plugins.flat(1/0):[]).filter(c=>c&&c.name!=="epx-lazy-lib"),{build:{emptyOutDir:!1}}):null},configResolved(f){t=f,m=y.resolve(f.root,f.build.outDir);let c=f.build.lib&&f.build.lib.entry;b=Array.isArray(c)?c[0]:typeof c=="object"?Object.values(c)[0]:c,u=y.dirname(b),d=i||y.basename(f.root)},async buildStart(){if(!s)return;n||this.error("[lazy-lib] \u7F3A\u5C11 glob \u9009\u9879\uFF08\u5F62\u5982 './<\u4EA7\u54C1\u540D>/**/*.vue'\uFF09");let f=Y(t.root,m);f&&this.error(f);let c=n.replace(/^\.\//,"").split("/")[0];o=z(O(u,c)),o.length||this.error(`[lazy-lib] \u6309 glob \u4E00\u4E2A .vue \u90FD\u6CA1\u626B\u5230\uFF0C\u65E0\u6CD5\u6309\u9700\u62C6\u5305\u3002
|
|
22
22
|
glob \u9009\u9879\uFF1A${n}
|
|
23
23
|
\u5B9E\u9645\u626B\u63CF\u76EE\u5F55\uFF1A${y.join(u,c)}\uFF08= \u5165\u53E3\u6240\u5728\u76EE\u5F55 ${u} + glob \u7B2C\u4E00\u6BB5 ${c}\uFF09
|
|
24
24
|
\u6700\u53EF\u80FD\u7684\u539F\u56E0\uFF1Aglob \u662F\u76F8\u5BF9**\u5165\u53E3\u6587\u4EF6\u6240\u5728\u76EE\u5F55**\u5199\u7684\uFF0C\u522B\u6309\u4ED3\u5E93\u6839\u591A\u5199\u4E00\u5C42 \`src/\`\u2014\u2014
|
|
@@ -30,7 +30,7 @@ import h from"node:fs";import y from"node:path";import{build as B}from"epxing:pr
|
|
|
30
30
|
\u5165\u53E3\u5B57\u9762\u91CF\uFF1A${x[2]}
|
|
31
31
|
\u6587\u4EF6\uFF1A${b}
|
|
32
32
|
\uFF08\u4E0D\u4E00\u81F4\u65F6\u58F3\u7684\u952E\u96C6\u4F1A\u4E0E\u6574\u4F53\u5355\u4F53\u5206\u53C9\uFF0C\u964D\u7EA7\u515C\u5E95\u4F1A\u627E\u4E0D\u5230\u7EC4\u4EF6\u3002\uFF09`),{code:`import __epxLazyGlob from ${JSON.stringify($)}
|
|
33
|
-
`+f.replace(I,"__epxLazyGlob"),map:null}},async closeBundle(){if(!s||!a)return;let f={};for(let c of o)f[c.key]=l.has(c.key)?null:a[c.key]||null;h.writeFileSync(y.join(m,"index.manifest.json"),JSON.stringify({v:1,pkgName:d,components:f,eager:[...l].sort()},null,2)+`
|
|
33
|
+
`+f.replace(I,/\bimport\s*:/.test(x[0])?"Object.fromEntries(Object.entries(__epxLazyGlob).map(([key, value]) => [key, value.default]))":"__epxLazyGlob"),map:null}},async closeBundle(){if(!s||!a)return;let f={};for(let c of o)f[c.key]=l.has(c.key)?null:a[c.key]||null;h.writeFileSync(y.join(m,"index.manifest.json"),JSON.stringify({v:1,pkgName:d,components:f,eager:[...l].sort()},null,2)+`
|
|
34
34
|
`),ee(m),M(m,t.build.copyPublicDir===!1?"":t.publicDir||""),await ne(t,g,b,m,d),J(m,"index.deps.json"),H(m,t.build.assetsDir)}}}function Y(e,s){let n=y.resolve(e),r=y.resolve(s);return r===n||!r.startsWith(n+y.sep)?`[lazy-lib] build.outDir \u5FC5\u987B\u662F\u9879\u76EE\u6839**\u4E4B\u5185**\u7684\u5B50\u76EE\u5F55\uFF0C\u4E14\u4E0D\u80FD\u5C31\u662F\u9879\u76EE\u6839\u672C\u8EAB\u3002
|
|
35
35
|
\u9879\u76EE\u6839\uFF1A${n}
|
|
36
36
|
outDir\uFF1A${r}
|
package/dist/lib-vite-config.mjs
CHANGED
|
@@ -28,13 +28,15 @@ export async function configureLibrary (env, options) {
|
|
|
28
28
|
if (!lazy) {
|
|
29
29
|
config.plugins = plugins.filter(plugin => plugin.name !== 'epx-lazy-lib')
|
|
30
30
|
} else {
|
|
31
|
+
// Vite 库模式默认内联资源;拆分组件的内部构建也需保持同样行为。
|
|
32
|
+
if (config.build.assetsInlineLimit == null) config.build.assetsInlineLimit = Infinity
|
|
31
33
|
config.plugins = plugins
|
|
32
34
|
if (!plugins.some(plugin => plugin.name === 'epx-lazy-lib')) {
|
|
33
35
|
const entry = config.build.lib.entry
|
|
34
36
|
const file = Array.isArray(entry) ? entry[0] : typeof entry === 'object' ? Object.values(entry)[0] : entry
|
|
35
37
|
if (!file) throw new Error('无法确定产品库入口 build.lib.entry')
|
|
36
38
|
const source = fs.readFileSync(path.resolve(root, file), 'utf8')
|
|
37
|
-
const match = /import\.meta\.glob\(\s*(['"])([^'"]+)\1\s*,\s*\{\s*eager\s*:\s*true\s*\}\s*\)/.exec(source)
|
|
39
|
+
const match = /import\.meta\.glob\(\s*(['"])([^'"]+)\1\s*,\s*\{\s*(?:import\s*:\s*['"]default['"]\s*,\s*)?eager\s*:\s*true\s*(?:,\s*import\s*:\s*['"]default['"]\s*)?,?\s*\}\s*\)/.exec(source)
|
|
38
40
|
if (!match) throw new Error('按需库需要入口中的 eager import.meta.glob;请先迁移产品入口,或使用 epx lib --full。')
|
|
39
41
|
config.plugins.push(lazyLib({ enabled: true, glob: match[2], pkgName }))
|
|
40
42
|
}
|