@bundlekit/cli 0.0.1 → 0.0.2
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 +85 -0
- package/dist/index.mjs +1 -1
- package/package.json +5 -5
package/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# @bundlekit/cli
|
|
2
|
+
|
|
3
|
+
前端项目脚手架 CLI,基于 ink 渲染的交互式命令行工具,支持快速创建 BundleKit 项目。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @bundlekit/cli
|
|
9
|
+
# 或
|
|
10
|
+
pnpm add -g @bundlekit/cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 使用
|
|
14
|
+
|
|
15
|
+
### 创建新项目
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bc create my-app
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
CLI 会引导你完成以下步骤:
|
|
22
|
+
|
|
23
|
+
1. 选择模板:`react-ts` / `react-js` / `vue3-ts` / `vue3-js`
|
|
24
|
+
2. 选择默认 bundler:`vite` / `webpack` / `rspack` / `rollup` / `rolldown`
|
|
25
|
+
3. 输入项目描述(可选)
|
|
26
|
+
4. 选择包管理器:`pnpm`(推荐)/ `yarn` / `npm`
|
|
27
|
+
|
|
28
|
+
### 添加插件或 bundler
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
bc add react # 添加 React 插件
|
|
32
|
+
bc add bundler-vite # 添加 Vite bundler 适配器
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 命令行选项
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
bc create my-app -t react-ts -b vite --pm pnpm
|
|
39
|
+
bc add mock --registry https://registry.npmmirror.com
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
| 选项 | 说明 |
|
|
43
|
+
|------|------|
|
|
44
|
+
| `-t, --template` | 模板类型 |
|
|
45
|
+
| `-b, --bundler` | 打包器 |
|
|
46
|
+
| `-p, --pm` | 包管理器 |
|
|
47
|
+
| `-d, --description` | 项目描述 |
|
|
48
|
+
| `--ssr` | 生成 SSR 骨架文件 |
|
|
49
|
+
| `--registry` | npm registry 地址 |
|
|
50
|
+
|
|
51
|
+
## 项目结构
|
|
52
|
+
|
|
53
|
+
脚手架创建后的项目结构:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
my-app/
|
|
57
|
+
├── .bundlekitrc.ts # 构建配置文件
|
|
58
|
+
├── tsconfig.json # TypeScript 配置
|
|
59
|
+
├── package.json # 项目依赖
|
|
60
|
+
├── src/
|
|
61
|
+
│ ├── index.tsx # 应用入口(CSR)
|
|
62
|
+
│ ├── App.tsx # 根组件
|
|
63
|
+
│ └── api/
|
|
64
|
+
│ └── index.ts # HTTP 请求层
|
|
65
|
+
├── public/
|
|
66
|
+
│ └── index.html # HTML 模板
|
|
67
|
+
└── mock/
|
|
68
|
+
└── db.json # Mock 数据
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 环境变量
|
|
72
|
+
|
|
73
|
+
| 变量 | 说明 |
|
|
74
|
+
|------|------|
|
|
75
|
+
| `DEVKIT_NO_INK` | 禁用 ink TTY 渲染,回退到 enquirer |
|
|
76
|
+
| `DEVKIT_SKIP_INSTALL` | 跳过依赖安装 |
|
|
77
|
+
| `DEVKIT_NO_PROMPT` | 禁用交互式提示 |
|
|
78
|
+
|
|
79
|
+
## 文档
|
|
80
|
+
|
|
81
|
+
完整文档请访问 [https://bundlekit.dev](https://bundlekit.dev)
|
|
82
|
+
|
|
83
|
+
## License
|
|
84
|
+
|
|
85
|
+
ISC
|
package/dist/index.mjs
CHANGED
|
@@ -7,4 +7,4 @@ import t,{useMemo as e,useState as i,useEffect as s,useCallback as r}from"react"
|
|
|
7
7
|
* @project EJS
|
|
8
8
|
* @license {@link http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0}
|
|
9
9
|
*/
|
|
10
|
-
var e=C,i=O,s=Vn,r=!1,n=Mn,o="locals",a=["delimiter","scope","context","debug","compileDebug","client","_with","rmWhitespace","strict","filename","async"],l=a.concat("cache"),c=/^\uFEFF/,h=/^[a-zA-Z_$][0-9a-zA-Z_$]*$/;function u(i,s){var r;if(s.some(function(s){return r=t.resolveInclude(i,s,!0),e.existsSync(r)}))return r}function p(e,i){var s,r=e.filename,n=arguments.length>1;if(e.cache){if(!r)throw new Error("cache option requires a filename");if(s=t.cache.get(r))return s;n||(i=d(r).toString().replace(c,""))}else if(!n){if(!r)throw new Error("Internal EJS error: no file name or template provided");i=d(r).toString().replace(c,"")}return s=t.compile(i,e),e.cache&&t.cache.set(r,s),s}function d(e){return t.fileLoader(e)}function m(i,r){var n=s.shallowCopy(s.createNullProtoObjWherePossible(),r);if(n.filename=function(i,s){var r,n,o=s.views,a=/^[A-Za-z]+:\\|^\//.exec(i);if(a&&a.length)i=i.replace(/^\/*/,""),r=Array.isArray(s.root)?u(i,s.root):t.resolveInclude(i,s.root||"/",!0);else if(s.filename&&(n=t.resolveInclude(i,s.filename),e.existsSync(n)&&(r=n)),!r&&Array.isArray(o)&&(r=u(i,o)),!r&&"function"!=typeof s.includer)throw new Error('Could not find the include file "'+s.escapeFunction(i)+'"');return r}(i,n),"function"==typeof r.includer){var o=r.includer(i,n.filename);if(o&&(o.filename&&(n.filename=o.filename),o.template))return p(n,o.template)}return p(n)}function f(t,e,i,s,r){var n=e.split("\n"),o=Math.max(s-3,0),a=Math.min(n.length,s+3),l=r(i),c=n.slice(o,a).map(function(t,e){var i=e+o+1;return(i==s?" >> ":" ")+i+"| "+t}).join("\n");throw t.path=l,t.message=(l||"ejs")+":"+s+"\n"+c+"\n\n"+t.message,t}function g(t){return t.replace(/;(\s*$)/,"$1")}function y(e,i){var r=s.hasOwnOnlyObject(i),n=s.createNullProtoObjWherePossible();this.templateText=e,this.mode=null,this.truncate=!1,this.currentLine=1,this.source="",n.client=r.client||!1,n.escapeFunction=r.escape||r.escapeFunction||s.escapeXML,n.compileDebug=!1!==r.compileDebug,n.debug=!!r.debug,n.filename=r.filename,n.openDelimiter=r.openDelimiter||t.openDelimiter||"<",n.closeDelimiter=r.closeDelimiter||t.closeDelimiter||">",n.delimiter=r.delimiter||t.delimiter||"%",n.strict=r.strict||!1,n.context=r.context,n.cache=r.cache||!1,n.rmWhitespace=r.rmWhitespace,n.root=r.root,n.includer=r.includer,n.outputFunctionName=r.outputFunctionName,n.localsName=r.localsName||t.localsName||o,n.views=r.views,n.async=r.async,n.destructuredLocals=r.destructuredLocals,n.legacyInclude=void 0===r.legacyInclude||!!r.legacyInclude,n.strict?n._with=!1:n._with=void 0===r._with||r._with,this.opts=n,this.regex=this.createRegex()}t.cache=s.cache,t.fileLoader=e.readFileSync,t.localsName=o,t.promiseImpl=new Function("return this;")().Promise,t.resolveInclude=function(t,e,s){var r=i.dirname,n=i.extname,o=(0,i.resolve)(s?e:r(e),t);return n(t)||(o+=".ejs"),o},t.compile=function(t,e){return e&&e.scope&&(r||(console.warn("`scope` option is deprecated and will be removed in EJS 3"),r=!0),e.context||(e.context=e.scope),delete e.scope),new y(t,e).compile()},t.render=function(t,e,i){var r=e||s.createNullProtoObjWherePossible(),n=i||s.createNullProtoObjWherePossible();return 2==arguments.length&&s.shallowCopyFromList(n,r,a),p(n,t)(r)},t.renderFile=function(){var e,i,r,n=Array.prototype.slice.call(arguments),o=n.shift(),a={filename:o};return"function"==typeof arguments[arguments.length-1]&&(e=n.pop()),n.length?(i=n.shift(),n.length?s.shallowCopy(a,n.pop()):(i.settings&&(i.settings.views&&(a.views=i.settings.views),i.settings["view cache"]&&(a.cache=!0),(r=i.settings["view options"])&&s.shallowCopy(a,r)),s.shallowCopyFromList(a,i,l)),a.filename=o):i=s.createNullProtoObjWherePossible(),function(e,i,s){var r;if(!s){if("function"==typeof t.promiseImpl)return new t.promiseImpl(function(t,s){try{t(r=p(e)(i))}catch(t){s(t)}});throw new Error("Please provide a callback function")}try{r=p(e)(i)}catch(t){return s(t)}s(null,r)}(a,i,e)},t.Template=y,t.clearCache=function(){t.cache.reset()},y.modes={EVAL:"eval",ESCAPED:"escaped",RAW:"raw",COMMENT:"comment",LITERAL:"literal"},y.prototype={createRegex:function(){var t="(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)",e=s.escapeRegExpChars(this.opts.delimiter),i=s.escapeRegExpChars(this.opts.openDelimiter),r=s.escapeRegExpChars(this.opts.closeDelimiter);return t=t.replace(/%/g,e).replace(/</g,i).replace(/>/g,r),new RegExp(t)},compile:function(){var t,e,r,n=this.opts,o="",a="",l=n.escapeFunction,c=n.filename?JSON.stringify(n.filename):"undefined";if(!this.source){if(this.generateSource(),o+=' var __output = "";\n function __append(s) { if (s !== undefined && s !== null) __output += s }\n',n.outputFunctionName){if(!h.test(n.outputFunctionName))throw new Error("outputFunctionName is not a valid JS identifier.");o+=" var "+n.outputFunctionName+" = __append;\n"}if(n.localsName&&!h.test(n.localsName))throw new Error("localsName is not a valid JS identifier.");if(n.destructuredLocals&&n.destructuredLocals.length){for(var u=" var __locals = ("+n.localsName+" || {}),\n",p=0;p<n.destructuredLocals.length;p++){var d=n.destructuredLocals[p];if(!h.test(d))throw new Error("destructuredLocals["+p+"] is not a valid JS identifier.");p>0&&(u+=",\n "),u+=d+" = __locals."+d}o+=u+";\n"}!1!==n._with&&(o+=" with ("+n.localsName+" || {}) {\n",a+=" }\n"),a+=" return __output;\n",this.source=o+this.source+a}t=n.compileDebug?"var __line = 1\n , __lines = "+JSON.stringify(this.templateText)+"\n , __filename = "+c+";\ntry {\n"+this.source+"} catch (e) {\n rethrow(e, __lines, __filename, __line, escapeFn);\n}\n":this.source,n.client&&(t="escapeFn = escapeFn || "+l.toString()+";\n"+t,n.compileDebug&&(t="rethrow = rethrow || "+f.toString()+";\n"+t)),n.strict&&(t='"use strict";\n'+t),n.debug&&console.log(t),n.compileDebug&&n.filename&&(t=t+"\n//# sourceURL="+c+"\n");try{if(n.async)try{r=new Function("return (async function(){}).constructor;")()}catch(t){throw t instanceof SyntaxError?new Error("This environment does not support async/await"):t}else r=Function;e=new r(n.localsName+", escapeFn, include, rethrow",t)}catch(t){throw t instanceof SyntaxError&&(n.filename&&(t.message+=" in "+n.filename),t.message+=" while compiling ejs\n\n",t.message+="If the above error is not helpful, you may want to try EJS-Lint:\n",t.message+="https://github.com/RyanZim/EJS-Lint",n.async||(t.message+="\n",t.message+="Or, if you meant to create an async function, pass `async: true` as an option.")),t}var g=n.client?e:function(t){return e.apply(n.context,[t||s.createNullProtoObjWherePossible(),l,function(e,i){var r=s.shallowCopy(s.createNullProtoObjWherePossible(),t);return i&&(r=s.shallowCopy(r,i)),m(e,n)(r)},f])};if(n.filename&&"function"==typeof Object.defineProperty){var y=n.filename,w=i.basename(y,i.extname(y));try{Object.defineProperty(g,"name",{value:w,writable:!1,enumerable:!1,configurable:!0})}catch(t){}}return g},generateSource:function(){this.opts.rmWhitespace&&(this.templateText=this.templateText.replace(/[\r\n]+/g,"\n").replace(/^\s+|\s+$/gm,"")),this.templateText=this.templateText.replace(/[ \t]*<%_/gm,"<%_").replace(/_%>[ \t]*/gm,"_%>");var t=this,e=this.parseTemplateText(),i=this.opts.delimiter,s=this.opts.openDelimiter,r=this.opts.closeDelimiter;e&&e.length&&e.forEach(function(n,o){var a;if(0===n.indexOf(s+i)&&0!==n.indexOf(s+i+i)&&(a=e[o+2])!=i+r&&a!="-"+i+r&&a!="_"+i+r)throw new Error('Could not find matching close tag for "'+n+'".');t.scanLine(n)})},parseTemplateText:function(){for(var t,e=this.templateText,i=this.regex,s=i.exec(e),r=[];s;)0!==(t=s.index)&&(r.push(e.substring(0,t)),e=e.slice(t)),r.push(s[0]),e=e.slice(s[0].length),s=i.exec(e);return e&&r.push(e),r},_addOutput:function(t){if(this.truncate&&(t=t.replace(/^(?:\r\n|\r|\n)/,""),this.truncate=!1),!t)return t;t=(t=(t=(t=t.replace(/\\/g,"\\\\")).replace(/\n/g,"\\n")).replace(/\r/g,"\\r")).replace(/"/g,'\\"'),this.source+=' ; __append("'+t+'")\n'},scanLine:function(t){var e,i=this.opts.delimiter,s=this.opts.openDelimiter,r=this.opts.closeDelimiter;switch(e=t.split("\n").length-1,t){case s+i:case s+i+"_":this.mode=y.modes.EVAL;break;case s+i+"=":this.mode=y.modes.ESCAPED;break;case s+i+"-":this.mode=y.modes.RAW;break;case s+i+"#":this.mode=y.modes.COMMENT;break;case s+i+i:this.mode=y.modes.LITERAL,this.source+=' ; __append("'+t.replace(s+i+i,s+i)+'")\n';break;case i+i+r:this.mode=y.modes.LITERAL,this.source+=' ; __append("'+t.replace(i+i+r,i+r)+'")\n';break;case i+r:case"-"+i+r:case"_"+i+r:this.mode==y.modes.LITERAL&&this._addOutput(t),this.mode=null,this.truncate=0===t.indexOf("-")||0===t.indexOf("_");break;default:if(this.mode){switch(this.mode){case y.modes.EVAL:case y.modes.ESCAPED:case y.modes.RAW:t.lastIndexOf("//")>t.lastIndexOf("\n")&&(t+="\n")}switch(this.mode){case y.modes.EVAL:this.source+=" ; "+t+"\n";break;case y.modes.ESCAPED:this.source+=" ; __append(escapeFn("+g(t)+"))\n";break;case y.modes.RAW:this.source+=" ; __append("+g(t)+")\n";break;case y.modes.COMMENT:break;case y.modes.LITERAL:this._addOutput(t)}}else this._addOutput(t)}this.opts.compileDebug&&e&&(this.currentLine+=e,this.source+=" ; __line = "+this.currentLine+"\n")}},t.escapeXML=s.escapeXML,t.__express=t.renderFile,t.VERSION=n,t.name="ejs","undefined"!=typeof window&&(window.ejs=t)}(Rn);var Hn=H(Rn);class Wn{constructor(t){this.templateDir=t.templateDir,this.targetDir=t.targetDir,this.context=t.context,this.fileManager=new w(t.targetDir),this.logger=new b}async generate(){await this.processDir(this.templateDir,this.targetDir),this.logger.info(`模板渲染完成: ${this.targetDir}`)}async processDir(t,e){const i=await Ln.readdir(t,{withFileTypes:!0});for(const s of i){const i=O.join(t,s.name),r=s.name.replace(/\.ejs$/,""),n=O.join(e,r);if(s.isDirectory())await Ln.ensureDir(n),await this.processDir(i,n);else if(s.name.endsWith(".ejs")){const t=await Ln.readFile(i,"utf-8"),e=Hn.render(t,this.context);await Ln.outputFile(n,e)}else await Ln.copyFile(i,n)}}}function Bn(t,e){const i=new Ni,s=[],r={prompt:t=>i.prompt(t),log:t=>e.done(t),addDependency(t,e="latest",i=!1){s.push({pkgName:t,version:e,dev:i})}};return r.__pendingDeps=s,r}async function qn(t,e,i,s){const r=`${t}/generator`;try{const n=E(import.meta.url).resolve(r,{paths:[e]}),o=await import(n),a=o.default??o;if("function"!=typeof a)return s.warn(`${t} 的 generator 不是函数,跳过`),!1;await a(e,i);const l=i.__pendingDeps??[];return function(t,e){if(!e.length)return;const i=O.join(t,"package.json");if(!C.existsSync(i))return;const s=JSON.parse(C.readFileSync(i,"utf-8"));for(const{pkgName:t,version:i,dev:r}of e){const e=r?"devDependencies":"dependencies";s[e]=s[e]||{},s[e][t]=i}C.writeFileSync(i,JSON.stringify(s,null,2)+"\n","utf-8")}(e,l),l.length>0}catch(e){return"MODULE_NOT_FOUND"===e?.code?s.warn(`${t} 未提供 generator,跳过`):s.error(`generator 执行失败: ${e?.message??e}`),!1}}function Un(t,e){return{kind:"npm",cliVersion:function(){try{const t=T(import.meta.url),e=t.resolve("@bundlekit/cli/package.json",{paths:[process.cwd()]}),i=t(e);if(i?.version)return i.version}catch{}try{const t=a.dirname(j(import.meta.url)),e=[a.resolve(t,"../package.json"),a.resolve(t,"../../package.json")];for(const t of e)try{const e=T(import.meta.url)(t);if("@bundlekit/cli"===e?.name&&e?.version)return e.version}catch{}}catch{}return"*"}()}}function zn(t,e){return`^${e.cliVersion}`}function Jn(t){const e=/^@bundlekit\/(.+)$/.exec(t.trim());return e?e[1]:null}function Gn(t,e){if(!/^[a-z0-9@.\-_]+$/.test(t))throw new Error(`项目名称 "${t}" 不合法,只能包含小写字母、数字、@、.、-、_`);const i=O.resolve(e,t);if(new w(e).isFilePathExist(i))throw new Error(`目录 ${i} 已存在,请选择其他项目名称`);return{targetDir:i}}function Kn(t){return Yn(t).startsWith("vue")?"@bundlekit/plugin-vue":"@bundlekit/plugin-react"}function Yn(t){return{react:"react-ts",vue:"vue3-ts",vue3:"vue3-ts","react-ts":"react-ts","react-js":"react-js","vue3-ts":"vue3-ts","vue3-js":"vue3-js"}[t]??t}function Zn(t){const e=Yn(t),i=Kn(t);try{const t=E(import.meta.url).resolve(`${i}/package.json`,{paths:[process.cwd()]}),s=O.join(O.dirname(t),"templates",`template-${e}`);if(C.existsSync(s))return s}catch{}const s=O.dirname(A(import.meta.url)),r=i.replace("@bundlekit/","bundlekit-"),n=O.resolve(s,"../..",r,"templates",`template-${e}`);if(C.existsSync(n))return n;throw new Error(`模板 "${t}" 未找到,可用模板:react-ts / react-js / vue3-ts / vue3-js`)}async function Xn(t){const e=new Wn({templateDir:t.templateDir,targetDir:t.targetDir,context:{projectName:t.projectName,description:t.description||"",bundler:t.bundler,ssr:!!t.ssr}});await e.generate()}function Qn(t,e,i){const s=_(e);return s?function(t,e,i){const s=v[e],r=zn(0,i),n=a.join(t,"package.json"),o=JSON.parse(l.readFileSync(n,"utf-8"));return o.devDependencies=o.devDependencies||{},o.devDependencies[s]=r,o.devDependencies=Object.fromEntries(Object.entries(o.devDependencies).sort(([t],[e])=>t.localeCompare(e))),l.writeFileSync(n,JSON.stringify(o,null,2)+"\n"),[s,r]}(t,s,i):null}function to(t,e){!function(t,e){const i=a.join(t,"package.json"),s=l.readFileSync(i,"utf-8"),r=JSON.parse(s),n=[],o=["dependencies","devDependencies","peerDependencies","optionalDependencies"];for(const t of o){const i=r[t];if(i&&"object"==typeof i)for(const t of Object.keys(i)){const s=i[t];if("string"!=typeof s)continue;if(!s.startsWith("workspace:"))continue;if(!Jn(t)){i[t]=s.replace(/^workspace:/,"");continue}const r=zn(0,e);n.push([t,s,r]),i[t]=r}}l.writeFileSync(i,JSON.stringify(r,null,2)+"\n")}(t,e)}async function eo(t,e){const i=e?.pm?e.pm:void 0,s=new S({context:t,forcePackageManager:i});await s.install()}function io(){const t=t=>{try{return 0===k(t,["--version"],{stdio:"ignore",shell:"win32"===process.platform}).status}catch{return!1}};return{pnpm:t("pnpm"),yarn:t("yarn"),npm:t("npm")}}async function so(t,e,i){return qn(t,e,Bn(0,i),i)}class ro{constructor(){this.logger=new b}async create(t,e={}){const i=new x,s=e.cwd||process.cwd(),r=e.template||"react-ts",n=e.bundler||"webpack",o=e.pm||void 0,a=Un();let l;try{({targetDir:l}=Gn(t,s))}catch(t){this.logger.error(t.message),process.exit(1)}i.logWithSpinner("📦",`正在创建项目 ${t}...`);const c=Zn(r);await Xn({targetDir:l,templateDir:c,projectName:t,description:e.description,bundler:n,ssr:!!e.ssr}),to(l,a),this.logger.info(`依赖模式:npm 模式(^${a.cliVersion})`);const h=Qn(l,n,a);if(h){const[t,e]=h;this.logger.info(`已写入 ${t}@${e} 到 devDependencies`)}else this.logger.warn(`bundler "${n}" 不在内置列表中,跳过 devDeps 写入`);const u="1"===process.env.DEVKIT_SKIP_INSTALL;u||(i.logWithSpinner("📦","正在安装依赖..."),await eo(l,{pm:o}),i.stopSpinner(!1)),this.logger.done(`项目 ${t} 创建成功!`);const p=process.env.DEVKIT_NO_PROMPT;process.env.DEVKIT_NO_PROMPT="1";let d=!1;try{const t=Kn(r);d=await so(t,l,this.logger)}finally{void 0===p?delete process.env.DEVKIT_NO_PROMPT:process.env.DEVKIT_NO_PROMPT=p}d&&(to(l,a),u||(this.logger.info("正在安装追加的依赖..."),await eo(l,{pm:o})));const m="npm"===o?"npm run dev":`${o||"pnpm"} dev`;this.logger.log(`\n cd ${t}`),this.logger.log(` ${m}\n`)}}const no={mock:"@bundlekit/plugin-mock",react:"@bundlekit/plugin-react",vue:"@bundlekit/plugin-vue",request:"@bundlekit/request"};class oo{constructor(t){this.context=t||process.cwd(),this.logger=new b}async add(t){const e=function(t){const e=(()=>{const e=_(t);return e?v[e]:null})();if(e)return e;const[i]=t.split("@").filter(Boolean);return no[i]??t}(t),i=function(t){return/\/plugin-|^plugin-/.test(t)}(e),s=function(t){return/^@bundlekit\/bundler-/.test(t)}(e),r=i||s;this.logger.info(`解析插件: ${t} → ${e}`),this.logger.info("类型: "+(s?"构建工具适配器(devDependency)":i?"构建插件(devDependency)":"运行时库(dependency)"));const n=new S({context:this.context});if(await n.add(e,{dev:r})){if(this.logger.done(`已安装 ${e}`),i&&!s){const t=Bn(this.context,this.logger);if(await qn(e,this.context,t,this.logger)){this.logger.info("正在安装追加的依赖...");const t=new S({context:this.context});await t.install()}}}else this.logger.error(`安装 ${e} 失败`)}}const ao=({version:t=""})=>N(d,{flexDirection:"column",marginBottom:1,children:[F(I,{name:"atlas",children:F(L,{text:"DEVKIT-CLI",font:"block"})}),F(d,{marginLeft:1,children:F(m,{dimColor:!0,children:`bundlekit${t?` v${t}`:""} · 多打包器构建工具`})})]}),lo=({title:t,step:e,total:i,children:s})=>N(d,{flexDirection:"column",borderStyle:"round",borderColor:"cyan",paddingX:1,marginBottom:1,children:[F(d,{marginBottom:1,children:F(m,{bold:!0,color:"cyan",children:e&&i?`Step ${e}/${i} · ${t}`:t})}),s]});function co(t,e,i){if(0===t.length)return-1;const s=t.length;let r=e;for(let e=0;e<s;e++)if(r=(r+i+s)%s,!t[r].disabled)return r;return-1}function ho(t){const{items:r,initialValue:n,onSelect:o,onBack:a}=t,l=e(()=>{if(n){const t=r.findIndex(t=>t.value===n&&!t.disabled);if(t>=0)return t}const t=r.findIndex(t=>!t.disabled);return t>=0?t:0},[r,n]),[c,h]=i(l);return s(()=>{if(c>=r.length||r[c]?.disabled){const t=r.findIndex(t=>!t.disabled);h(t>=0?t:0)}},[r]),f((t,e)=>{if(e.upArrow||"k"===t){const t=co(r,c,-1);return void(t>=0&&h(t))}if(e.downArrow||"j"===t){const t=co(r,c,1);return void(t>=0&&h(t))}if(e.return){const t=r[c];return void(t&&!t.disabled&&o(t.value))}(e.escape||e.backspace||e.delete)&&a&&a()}),F(d,{flexDirection:"column",children:r.map((t,e)=>{const i=e===c,s=!!t.disabled,r=i?"▶ ":" ",n=s?void 0:i?"cyan":void 0,o=s||!i,a=s&&t.disabledReason?` ${t.disabledReason}`:"";return N(d,{children:[F(m,{color:i&&!s?"cyan":void 0,children:r}),N(m,{color:n,dimColor:o,children:[t.label,a]})]},String(t.value))})})}const uo=({value:t,placeholder:e,onChange:i,onSubmit:s})=>F(R,{value:t,placeholder:e,onChange:i,onSubmit:s}),po={pending:"○",running:"",done:"✔",error:"✘"},mo={pending:"gray",running:"cyan",done:"green",error:"red"},fo=({tasks:t})=>F(d,{flexDirection:"column",children:t.map(t=>N(d,{children:[F(d,{width:3,children:"running"===t.status?F(m,{color:"cyan",children:F(V,{type:"dots"})}):F(m,{color:mo[t.status],children:po[t.status]})}),F(m,{color:"pending"===t.status?"gray":void 0,children:t.label}),t.detail?N(m,{dimColor:!0,children:[" (",t.detail,")"]}):null]},t.id))});function go(t,e){return"npm"===t?`npm run ${e}`:`${t} ${e}`}const yo=({name:t,bundler:e,template:i,pm:s="pnpm"})=>{const r=go(s,"dev"),n=go(s,"build");return N(d,{flexDirection:"column",marginTop:1,children:[N(d,{children:[F(m,{color:"green",bold:!0,children:" ✔ 项目 "}),F(m,{color:"cyan",bold:!0,children:t}),F(m,{color:"green",bold:!0,children:" 创建成功"})]}),N(d,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"green",paddingX:1,children:[i&&N(d,{children:[F(m,{dimColor:!0,children:"模板 "}),F(m,{color:"cyan",children:i})]}),N(d,{children:[F(m,{dimColor:!0,children:"打包器 "}),F(m,{color:"cyan",children:e})]}),N(d,{children:[F(m,{dimColor:!0,children:"包管理器 "}),F(m,{color:"cyan",children:s})]}),N(d,{children:[F(m,{dimColor:!0,children:"位置 "}),F(m,{color:"cyan",children:`./${t}`})]})]}),N(d,{flexDirection:"column",marginTop:1,children:[F(m,{dimColor:!0,children:"下一步:"}),N(d,{marginLeft:2,marginTop:1,flexDirection:"column",children:[N(d,{children:[F(m,{color:"gray",children:"$ "}),F(m,{color:"cyan",children:`cd ${t}`})]}),N(d,{children:[F(m,{color:"gray",children:"$ "}),F(m,{color:"cyan",children:r}),F(m,{dimColor:!0,children:` 使用 ${e} 启动开发服务`})]}),N(d,{children:[F(m,{color:"gray",children:"$ "}),F(m,{color:"cyan",children:n}),F(m,{dimColor:!0,children:" 生产构建"})]})]})]}),N(d,{marginTop:1,children:[F(m,{dimColor:!0,children:"提示:"}),N(m,{dimColor:!0,children:["使用 ",N(m,{color:"cyan",children:["dc add bundler-","<name>"]})," 切换打包器,使用 ",N(m,{color:"cyan",children:["dc add ","<plugin>"]})," 追加插件"]})]})]})},wo=({step:t,message:e,stack:i})=>N(d,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:[F(d,{children:N(m,{color:"red",bold:!0,children:["✘ ",t," 失败"]})}),F(d,{marginTop:1,children:F(m,{color:"redBright",children:e})}),i?F(d,{marginTop:1,children:F(m,{dimColor:!0,children:i})}):null]}),bo=[{label:"React + TypeScript",value:"react-ts"},{label:"React + JavaScript",value:"react-js"},{label:"Vue 3 + TypeScript",value:"vue3-ts"},{label:"Vue 3 + JavaScript",value:"vue3-js"}],vo=[{label:"Vite —— 开发体感最佳",value:"vite"},{label:"Webpack —— 生态最完整",value:"webpack"},{label:"Rspack —— Rust 实现,极速",value:"rspack"},{label:"更多打包器 →",value:"__more__"}],_o=[{label:"Rollup —— 适合库构建",value:"rollup"},{label:"Rolldown —— 实验性",value:"rolldown"},{label:"← 返回",value:"__back__"}],So=["pnpm","yarn","npm"],xo={pnpm:"pnpm —— 推荐,磁盘占用最小",yarn:"yarn —— 兼容性好",npm:"npm —— Node 内置"};const Oo=({params:t})=>{const{exit:n}=g(),[o,a]=i(t.template),[l,c]=i(t.bundler),[h,u]=i("primary"),p=e(()=>io(),[]),f=e(()=>function(){const t=process.env.DEVKIT_PM;if("pnpm"===t||"yarn"===t||"npm"===t)return t}(),[]),[y,w]=i(function(t,e,i){return t&&i[t]?t:e&&i[e]?e:void 0}(t.pm,f,p));e(()=>Un(t.cwd||process.cwd()),[t.cwd]);const[v,_]=i(t.description||""),[S,x]=i(void 0!==t.description),[O,C]=i([]),[k,E]=i(null);let A;A=k?"error":O.length>0&&O.every(t=>"done"===t.status)?"done":O.length>0?"tasks":o?l?y?S?"tasks":"description":"pm":"bundler":"template";const $=r((t,e)=>{C(i=>i.map(i=>i.id===t?{...i,...e}:i))},[]);s(()=>{if("tasks"!==A)return;if(O.length>0)return;C([{id:"render",label:"渲染模板",status:"pending"},{id:"normalize",label:"规范化依赖版本",status:"pending"},{id:"deps",label:"写入 bundler 到 devDependencies",status:"pending"},{id:"install",label:"安装依赖",status:"pending"},{id:"generator",label:"调用框架插件 generator",status:"pending"}]),(async()=>{const e=t.cwd||process.cwd();let i;try{({targetDir:i}=Gn(t.name,e))}catch(t){return void E({step:"校验项目",message:t.message})}const s=new b,r=Un();try{$("render",{status:"running"});const e=Zn(o);await Xn({targetDir:i,templateDir:e,projectName:t.name,description:v,bundler:l,ssr:!!t.ssr}),$("render",{status:"done"})}catch(t){const e=t;return $("render",{status:"error"}),void E({step:"渲染模板",message:e.message,stack:e.stack})}try{$("normalize",{status:"running"}),to(i,r);const t=`npm 模式 → ^${r.cliVersion}`;$("normalize",{status:"done",detail:t})}catch(t){const e=t;return $("normalize",{status:"error"}),void E({step:"规范化依赖版本",message:e.message,stack:e.stack})}try{$("deps",{status:"running"});const t=Qn(i,l,r);if(t){const[e,i]=t;$("deps",{status:"done",detail:`${e}@${i}`})}else $("deps",{status:"done",detail:"未识别的 bundler,跳过"})}catch(t){const e=t;return $("deps",{status:"error"}),void E({step:"写入 devDependencies",message:e.message,stack:e.stack})}try{$("install",{status:"running"}),await eo(i,{pm:y}),$("install",{status:"done"})}catch(t){const e=t;return $("install",{status:"error"}),void E({step:"安装依赖",message:e.message,stack:e.stack})}try{$("generator",{status:"running"});const t=Kn(o),e=process.env.DEVKIT_NO_PROMPT;process.env.DEVKIT_NO_PROMPT="1";let n=!1;try{n=await so(t,i,s)}finally{void 0===e?delete process.env.DEVKIT_NO_PROMPT:process.env.DEVKIT_NO_PROMPT=e}n&&(to(i,r),await eo(i,{pm:y})),$("generator",{status:"done"})}catch(t){const e=t;return $("generator",{status:"error"}),void E({step:"调用 generator",message:e.message,stack:e.stack})}})()},[A,O.length,o,l,y,v,t,$]),s(()=>{if("done"===A){const t=setTimeout(()=>n(),100);return()=>clearTimeout(t)}if("error"===A){const t=setTimeout(()=>{n(),process.exit(1)},100);return()=>clearTimeout(t)}},[A,n]);const P=e(()=>So.map(t=>({label:xo[t],value:t,disabled:!p[t],disabledReason:p[t]?void 0:"(未安装)"})),[p]);return N(d,{flexDirection:"column",children:[F(ao,{}),"template"===A&&F(lo,{title:"模板",step:1,total:4,children:F(ho,{items:bo,initialValue:o,onSelect:t=>a(t)})}),"bundler"===A&&N(lo,{title:"打包器",step:2,total:4,children:[N(d,{marginBottom:1,children:[F(m,{dimColor:!0,children:"已选模板:"}),N(m,{color:"cyan",children:[" ",o]})]}),F(ho,"primary"===h?{items:vo,initialValue:l,onSelect:t=>{"__more__"===t?u("secondary"):c(t)}}:{items:_o,onSelect:t=>{"__back__"===t?u("primary"):c(t)},onBack:()=>u("primary")})]}),"pm"===A&&N(lo,{title:"包管理器",step:3,total:4,children:[F(d,{marginBottom:1,children:F(m,{dimColor:!0,children:"用于安装项目依赖:"})}),F(ho,{items:P,onSelect:t=>w(t)})]}),"description"===A&&F(lo,{title:"项目描述(可选,按回车跳过)",step:4,total:4,children:F(uo,{value:v,placeholder:"A demo app",onChange:_,onSubmit:t=>{_(t||" "),x(!0)}})}),("tasks"===A||"done"===A)&&N(d,{flexDirection:"column",borderStyle:"round",borderColor:"cyan",paddingX:1,marginBottom:1,children:[N(d,{marginBottom:1,children:[F(m,{bold:!0,color:"cyan",children:"创建项目 "}),F(m,{bold:!0,children:t.name}),F(m,{dimColor:!0,children:` ${o} · ${l} · ${y}`})]}),F(fo,{tasks:O})]}),"done"===A&&F(yo,{name:t.name,bundler:l,template:o,pm:y}),"error"===A&&k&&F(wo,{step:k.step,message:k.message,stack:k.stack})]})},Co=({params:t})=>{const{exit:e}=g(),[r,n]=i([{id:"resolve",label:`解析 ${t.plugin}`,status:"pending"},{id:"install",label:"安装依赖",status:"pending"},{id:"generator",label:"调用 generator (如有)",status:"pending"}]),[o,a]=i(null);return s(()=>{const i=(t,e)=>{n(i=>i.map(i=>i.id===t?{...i,...e}:i))};(async()=>{try{i("resolve",{status:"running"});const e=t.cwd||process.cwd(),s=new oo(e);i("resolve",{status:"done"}),i("install",{status:"running"}),await s.add(t.plugin),i("install",{status:"done"}),i("generator",{status:"done"})}catch(t){const e=t;a({step:"add",message:e.message,stack:e.stack})}finally{setTimeout(()=>e(),100)}})()},[t,e]),N(d,{flexDirection:"column",children:[F(ao,{}),N(d,{marginBottom:1,children:[F(m,{children:"追加:"}),N(m,{color:"cyan",bold:!0,children:[" ",t.plugin]})]}),F(fo,{tasks:r}),o&&F(wo,{step:o.step,message:o.message,stack:o.stack})]})},ko=t=>"create"===t.command?F(Oo,{params:t.params}):"add"===t.command?F(Co,{params:t.params}):null,Eo=new St,Ao=[{name:"react-ts",message:"React + TypeScript"},{name:"react-js",message:"React + JavaScript"},{name:"vue3-ts",message:"Vue 3 + TypeScript"},{name:"vue3-js",message:"Vue 3 + JavaScript"}],$o=[{name:"vite",message:"Vite"},{name:"webpack",message:"Webpack"},{name:"rspack",message:"Rspack"},{name:"rollup",message:"Rollup"},{name:"rolldown",message:"Rolldown"}];function Po(){return"1"!==process.env.DEVKIT_NO_INK&&(!!process.stdout.isTTY&&!!process.stdin.isTTY)}function Do(t){return"pnpm"===t||"yarn"===t||"npm"===t}async function To(t,e){const i=new Ni;if(!e.template){const t=await i.prompt({type:"select",name:"template",message:"请选择项目模板:",choices:Ao});e.template=t.template}if(!e.bundler){const t=await i.prompt({type:"select",name:"bundler",message:"请选择默认构建工具:",choices:$o});e.bundler=t.bundler}let s=Do(e.pm)?e.pm:void 0;if(s||(s=function(){const t=process.env.DEVKIT_PM;if("pnpm"===t||"yarn"===t||"npm"===t)return t}()),!s){const t=io(),e=["pnpm","yarn","npm"].filter(e=>t[e]).map(t=>({name:t,message:t}));if(0===e.length)s="npm";else if(1===e.length)s=e[0].name;else{s=(await i.prompt({type:"select",name:"pm",message:"请选择包管理器:",choices:e})).pm}}e.pm=s;const r=new ro;await r.create(t,e)}Eo.command("create <name>").description("create a new project powered by bundlekit-service").option("-t, --template <template>","模板类型 (react-ts, react-js, vue3-ts, vue3-js)").option("-b, --bundler <bundler>","默认构建工具 (vite, webpack, rspack, rollup, rolldown)").option("-d, --description <desc>","项目描述").option("--pm <pm>","包管理器 (pnpm, yarn, npm)").option("--ssr","启用 SSR:模板生成 entry-client/entry-server + .bundlekitrc.ts 加 ssr 配置块",!1).action(async(e,i)=>{if(!Po())return void await To(e,i);process.env.DEVKIT_QUIET="1";const s=Do(i.pm)?i.pm:void 0,{waitUntilExit:r}=y(t.createElement(ko,{command:"create",params:{name:e,template:i.template,bundler:i.bundler,pm:s,description:i.description,ssr:!!i.ssr}}));await r()}),Eo.command("add <plugin>").description("向已有项目添加插件 / bundler 适配器").action(async e=>{if(!Po()){const t=new oo(process.cwd());return void await t.add(e)}process.env.DEVKIT_QUIET="1";const{waitUntilExit:i}=y(t.createElement(ko,{command:"add",params:{plugin:e}}));await i()}),Eo.command("help").alias("h").description("处理帮助信息 -h").action(()=>{Eo.outputHelp()}),Eo.command("version").alias("v").description("bundlekit-cli版本 -v").action(()=>{const t=require("../package.json");console.log(`bundlekit-cli v${t.version}`)}),Eo.parse(process.argv);
|
|
10
|
+
var e=C,i=O,s=Vn,r=!1,n=Mn,o="locals",a=["delimiter","scope","context","debug","compileDebug","client","_with","rmWhitespace","strict","filename","async"],l=a.concat("cache"),c=/^\uFEFF/,h=/^[a-zA-Z_$][0-9a-zA-Z_$]*$/;function u(i,s){var r;if(s.some(function(s){return r=t.resolveInclude(i,s,!0),e.existsSync(r)}))return r}function p(e,i){var s,r=e.filename,n=arguments.length>1;if(e.cache){if(!r)throw new Error("cache option requires a filename");if(s=t.cache.get(r))return s;n||(i=d(r).toString().replace(c,""))}else if(!n){if(!r)throw new Error("Internal EJS error: no file name or template provided");i=d(r).toString().replace(c,"")}return s=t.compile(i,e),e.cache&&t.cache.set(r,s),s}function d(e){return t.fileLoader(e)}function m(i,r){var n=s.shallowCopy(s.createNullProtoObjWherePossible(),r);if(n.filename=function(i,s){var r,n,o=s.views,a=/^[A-Za-z]+:\\|^\//.exec(i);if(a&&a.length)i=i.replace(/^\/*/,""),r=Array.isArray(s.root)?u(i,s.root):t.resolveInclude(i,s.root||"/",!0);else if(s.filename&&(n=t.resolveInclude(i,s.filename),e.existsSync(n)&&(r=n)),!r&&Array.isArray(o)&&(r=u(i,o)),!r&&"function"!=typeof s.includer)throw new Error('Could not find the include file "'+s.escapeFunction(i)+'"');return r}(i,n),"function"==typeof r.includer){var o=r.includer(i,n.filename);if(o&&(o.filename&&(n.filename=o.filename),o.template))return p(n,o.template)}return p(n)}function f(t,e,i,s,r){var n=e.split("\n"),o=Math.max(s-3,0),a=Math.min(n.length,s+3),l=r(i),c=n.slice(o,a).map(function(t,e){var i=e+o+1;return(i==s?" >> ":" ")+i+"| "+t}).join("\n");throw t.path=l,t.message=(l||"ejs")+":"+s+"\n"+c+"\n\n"+t.message,t}function g(t){return t.replace(/;(\s*$)/,"$1")}function y(e,i){var r=s.hasOwnOnlyObject(i),n=s.createNullProtoObjWherePossible();this.templateText=e,this.mode=null,this.truncate=!1,this.currentLine=1,this.source="",n.client=r.client||!1,n.escapeFunction=r.escape||r.escapeFunction||s.escapeXML,n.compileDebug=!1!==r.compileDebug,n.debug=!!r.debug,n.filename=r.filename,n.openDelimiter=r.openDelimiter||t.openDelimiter||"<",n.closeDelimiter=r.closeDelimiter||t.closeDelimiter||">",n.delimiter=r.delimiter||t.delimiter||"%",n.strict=r.strict||!1,n.context=r.context,n.cache=r.cache||!1,n.rmWhitespace=r.rmWhitespace,n.root=r.root,n.includer=r.includer,n.outputFunctionName=r.outputFunctionName,n.localsName=r.localsName||t.localsName||o,n.views=r.views,n.async=r.async,n.destructuredLocals=r.destructuredLocals,n.legacyInclude=void 0===r.legacyInclude||!!r.legacyInclude,n.strict?n._with=!1:n._with=void 0===r._with||r._with,this.opts=n,this.regex=this.createRegex()}t.cache=s.cache,t.fileLoader=e.readFileSync,t.localsName=o,t.promiseImpl=new Function("return this;")().Promise,t.resolveInclude=function(t,e,s){var r=i.dirname,n=i.extname,o=(0,i.resolve)(s?e:r(e),t);return n(t)||(o+=".ejs"),o},t.compile=function(t,e){return e&&e.scope&&(r||(console.warn("`scope` option is deprecated and will be removed in EJS 3"),r=!0),e.context||(e.context=e.scope),delete e.scope),new y(t,e).compile()},t.render=function(t,e,i){var r=e||s.createNullProtoObjWherePossible(),n=i||s.createNullProtoObjWherePossible();return 2==arguments.length&&s.shallowCopyFromList(n,r,a),p(n,t)(r)},t.renderFile=function(){var e,i,r,n=Array.prototype.slice.call(arguments),o=n.shift(),a={filename:o};return"function"==typeof arguments[arguments.length-1]&&(e=n.pop()),n.length?(i=n.shift(),n.length?s.shallowCopy(a,n.pop()):(i.settings&&(i.settings.views&&(a.views=i.settings.views),i.settings["view cache"]&&(a.cache=!0),(r=i.settings["view options"])&&s.shallowCopy(a,r)),s.shallowCopyFromList(a,i,l)),a.filename=o):i=s.createNullProtoObjWherePossible(),function(e,i,s){var r;if(!s){if("function"==typeof t.promiseImpl)return new t.promiseImpl(function(t,s){try{t(r=p(e)(i))}catch(t){s(t)}});throw new Error("Please provide a callback function")}try{r=p(e)(i)}catch(t){return s(t)}s(null,r)}(a,i,e)},t.Template=y,t.clearCache=function(){t.cache.reset()},y.modes={EVAL:"eval",ESCAPED:"escaped",RAW:"raw",COMMENT:"comment",LITERAL:"literal"},y.prototype={createRegex:function(){var t="(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)",e=s.escapeRegExpChars(this.opts.delimiter),i=s.escapeRegExpChars(this.opts.openDelimiter),r=s.escapeRegExpChars(this.opts.closeDelimiter);return t=t.replace(/%/g,e).replace(/</g,i).replace(/>/g,r),new RegExp(t)},compile:function(){var t,e,r,n=this.opts,o="",a="",l=n.escapeFunction,c=n.filename?JSON.stringify(n.filename):"undefined";if(!this.source){if(this.generateSource(),o+=' var __output = "";\n function __append(s) { if (s !== undefined && s !== null) __output += s }\n',n.outputFunctionName){if(!h.test(n.outputFunctionName))throw new Error("outputFunctionName is not a valid JS identifier.");o+=" var "+n.outputFunctionName+" = __append;\n"}if(n.localsName&&!h.test(n.localsName))throw new Error("localsName is not a valid JS identifier.");if(n.destructuredLocals&&n.destructuredLocals.length){for(var u=" var __locals = ("+n.localsName+" || {}),\n",p=0;p<n.destructuredLocals.length;p++){var d=n.destructuredLocals[p];if(!h.test(d))throw new Error("destructuredLocals["+p+"] is not a valid JS identifier.");p>0&&(u+=",\n "),u+=d+" = __locals."+d}o+=u+";\n"}!1!==n._with&&(o+=" with ("+n.localsName+" || {}) {\n",a+=" }\n"),a+=" return __output;\n",this.source=o+this.source+a}t=n.compileDebug?"var __line = 1\n , __lines = "+JSON.stringify(this.templateText)+"\n , __filename = "+c+";\ntry {\n"+this.source+"} catch (e) {\n rethrow(e, __lines, __filename, __line, escapeFn);\n}\n":this.source,n.client&&(t="escapeFn = escapeFn || "+l.toString()+";\n"+t,n.compileDebug&&(t="rethrow = rethrow || "+f.toString()+";\n"+t)),n.strict&&(t='"use strict";\n'+t),n.debug&&console.log(t),n.compileDebug&&n.filename&&(t=t+"\n//# sourceURL="+c+"\n");try{if(n.async)try{r=new Function("return (async function(){}).constructor;")()}catch(t){throw t instanceof SyntaxError?new Error("This environment does not support async/await"):t}else r=Function;e=new r(n.localsName+", escapeFn, include, rethrow",t)}catch(t){throw t instanceof SyntaxError&&(n.filename&&(t.message+=" in "+n.filename),t.message+=" while compiling ejs\n\n",t.message+="If the above error is not helpful, you may want to try EJS-Lint:\n",t.message+="https://github.com/RyanZim/EJS-Lint",n.async||(t.message+="\n",t.message+="Or, if you meant to create an async function, pass `async: true` as an option.")),t}var g=n.client?e:function(t){return e.apply(n.context,[t||s.createNullProtoObjWherePossible(),l,function(e,i){var r=s.shallowCopy(s.createNullProtoObjWherePossible(),t);return i&&(r=s.shallowCopy(r,i)),m(e,n)(r)},f])};if(n.filename&&"function"==typeof Object.defineProperty){var y=n.filename,w=i.basename(y,i.extname(y));try{Object.defineProperty(g,"name",{value:w,writable:!1,enumerable:!1,configurable:!0})}catch(t){}}return g},generateSource:function(){this.opts.rmWhitespace&&(this.templateText=this.templateText.replace(/[\r\n]+/g,"\n").replace(/^\s+|\s+$/gm,"")),this.templateText=this.templateText.replace(/[ \t]*<%_/gm,"<%_").replace(/_%>[ \t]*/gm,"_%>");var t=this,e=this.parseTemplateText(),i=this.opts.delimiter,s=this.opts.openDelimiter,r=this.opts.closeDelimiter;e&&e.length&&e.forEach(function(n,o){var a;if(0===n.indexOf(s+i)&&0!==n.indexOf(s+i+i)&&(a=e[o+2])!=i+r&&a!="-"+i+r&&a!="_"+i+r)throw new Error('Could not find matching close tag for "'+n+'".');t.scanLine(n)})},parseTemplateText:function(){for(var t,e=this.templateText,i=this.regex,s=i.exec(e),r=[];s;)0!==(t=s.index)&&(r.push(e.substring(0,t)),e=e.slice(t)),r.push(s[0]),e=e.slice(s[0].length),s=i.exec(e);return e&&r.push(e),r},_addOutput:function(t){if(this.truncate&&(t=t.replace(/^(?:\r\n|\r|\n)/,""),this.truncate=!1),!t)return t;t=(t=(t=(t=t.replace(/\\/g,"\\\\")).replace(/\n/g,"\\n")).replace(/\r/g,"\\r")).replace(/"/g,'\\"'),this.source+=' ; __append("'+t+'")\n'},scanLine:function(t){var e,i=this.opts.delimiter,s=this.opts.openDelimiter,r=this.opts.closeDelimiter;switch(e=t.split("\n").length-1,t){case s+i:case s+i+"_":this.mode=y.modes.EVAL;break;case s+i+"=":this.mode=y.modes.ESCAPED;break;case s+i+"-":this.mode=y.modes.RAW;break;case s+i+"#":this.mode=y.modes.COMMENT;break;case s+i+i:this.mode=y.modes.LITERAL,this.source+=' ; __append("'+t.replace(s+i+i,s+i)+'")\n';break;case i+i+r:this.mode=y.modes.LITERAL,this.source+=' ; __append("'+t.replace(i+i+r,i+r)+'")\n';break;case i+r:case"-"+i+r:case"_"+i+r:this.mode==y.modes.LITERAL&&this._addOutput(t),this.mode=null,this.truncate=0===t.indexOf("-")||0===t.indexOf("_");break;default:if(this.mode){switch(this.mode){case y.modes.EVAL:case y.modes.ESCAPED:case y.modes.RAW:t.lastIndexOf("//")>t.lastIndexOf("\n")&&(t+="\n")}switch(this.mode){case y.modes.EVAL:this.source+=" ; "+t+"\n";break;case y.modes.ESCAPED:this.source+=" ; __append(escapeFn("+g(t)+"))\n";break;case y.modes.RAW:this.source+=" ; __append("+g(t)+")\n";break;case y.modes.COMMENT:break;case y.modes.LITERAL:this._addOutput(t)}}else this._addOutput(t)}this.opts.compileDebug&&e&&(this.currentLine+=e,this.source+=" ; __line = "+this.currentLine+"\n")}},t.escapeXML=s.escapeXML,t.__express=t.renderFile,t.VERSION=n,t.name="ejs","undefined"!=typeof window&&(window.ejs=t)}(Rn);var Hn=H(Rn);class Wn{constructor(t){this.templateDir=t.templateDir,this.targetDir=t.targetDir,this.context=t.context,this.fileManager=new w(t.targetDir),this.logger=new b}async generate(){await this.processDir(this.templateDir,this.targetDir),this.logger.info(`模板渲染完成: ${this.targetDir}`)}async processDir(t,e){const i=await Ln.readdir(t,{withFileTypes:!0});for(const s of i){if(!this.context.ssr&&s.name.includes("entry-server"))continue;const i=O.join(t,s.name),r=s.name.replace(/\.ejs$/,""),n=O.join(e,r);if(s.isDirectory())await Ln.ensureDir(n),await this.processDir(i,n);else if(s.name.endsWith(".ejs")){const t=await Ln.readFile(i,"utf-8"),e=Hn.render(t,this.context);await Ln.outputFile(n,e)}else await Ln.copyFile(i,n)}}}function Bn(t,e){const i=new Ni,s=[],r={prompt:t=>i.prompt(t),log:t=>e.done(t),addDependency(t,e="latest",i=!1){s.push({pkgName:t,version:e,dev:i})}};return r.__pendingDeps=s,r}async function qn(t,e,i,s){const r=`${t}/generator`;try{const n=E(import.meta.url).resolve(r,{paths:[e]}),o=await import(n),a=o.default??o;if("function"!=typeof a)return s.warn(`${t} 的 generator 不是函数,跳过`),!1;await a(e,i);const l=i.__pendingDeps??[];return function(t,e){if(!e.length)return;const i=O.join(t,"package.json");if(!C.existsSync(i))return;const s=JSON.parse(C.readFileSync(i,"utf-8"));for(const{pkgName:t,version:i,dev:r}of e){const e=r?"devDependencies":"dependencies";s[e]=s[e]||{},s[e][t]=i}C.writeFileSync(i,JSON.stringify(s,null,2)+"\n","utf-8")}(e,l),l.length>0}catch(e){return"MODULE_NOT_FOUND"===e?.code?s.warn(`${t} 未提供 generator,跳过`):s.error(`generator 执行失败: ${e?.message??e}`),!1}}function Un(t,e){return{kind:"npm",cliVersion:function(){try{const t=T(import.meta.url),e=t.resolve("@bundlekit/cli/package.json",{paths:[process.cwd()]}),i=t(e);if(i?.version)return i.version}catch{}try{const t=a.dirname(j(import.meta.url)),e=[a.resolve(t,"../package.json"),a.resolve(t,"../../package.json")];for(const t of e)try{const e=T(import.meta.url)(t);if("@bundlekit/cli"===e?.name&&e?.version)return e.version}catch{}}catch{}return"*"}()}}function zn(t,e){return`^${e.cliVersion}`}function Jn(t){const e=/^@bundlekit\/(.+)$/.exec(t.trim());return e?e[1]:null}function Gn(t,e){if(!/^[a-z0-9@.\-_]+$/.test(t))throw new Error(`项目名称 "${t}" 不合法,只能包含小写字母、数字、@、.、-、_`);const i=O.resolve(e,t);if(new w(e).isFilePathExist(i))throw new Error(`目录 ${i} 已存在,请选择其他项目名称`);return{targetDir:i}}function Kn(t){return Yn(t).startsWith("vue")?"@bundlekit/plugin-vue":"@bundlekit/plugin-react"}function Yn(t){return{react:"react-ts",vue:"vue3-ts",vue3:"vue3-ts","react-ts":"react-ts","react-js":"react-js","vue3-ts":"vue3-ts","vue3-js":"vue3-js"}[t]??t}function Zn(t){const e=Yn(t),i=Kn(t);try{const t=E(import.meta.url).resolve(`${i}/package.json`),s=O.join(O.dirname(t),"templates",`template-${e}`);if(C.existsSync(s))return s}catch{}const s=O.dirname(A(import.meta.url)),r=i.replace("@bundlekit/","bundlekit-"),n=O.resolve(s,"../..",r,"templates",`template-${e}`);if(C.existsSync(n))return n;throw new Error(`模板 "${t}" 未找到,可用模板:react-ts / react-js / vue3-ts / vue3-js`)}async function Xn(t){const e=new Wn({templateDir:t.templateDir,targetDir:t.targetDir,context:{projectName:t.projectName,description:t.description||"",bundler:t.bundler,ssr:!!t.ssr}});await e.generate()}function Qn(t,e,i){const s=_(e);return s?function(t,e,i){const s=v[e],r=zn(0,i),n=a.join(t,"package.json"),o=JSON.parse(l.readFileSync(n,"utf-8"));return o.devDependencies=o.devDependencies||{},o.devDependencies[s]=r,o.devDependencies=Object.fromEntries(Object.entries(o.devDependencies).sort(([t],[e])=>t.localeCompare(e))),l.writeFileSync(n,JSON.stringify(o,null,2)+"\n"),[s,r]}(t,s,i):null}function to(t,e){!function(t,e){const i=a.join(t,"package.json"),s=l.readFileSync(i,"utf-8"),r=JSON.parse(s),n=[],o=["dependencies","devDependencies","peerDependencies","optionalDependencies"];for(const t of o){const i=r[t];if(i&&"object"==typeof i)for(const t of Object.keys(i)){const s=i[t];if("string"!=typeof s)continue;if(!s.startsWith("workspace:"))continue;if(!Jn(t)){i[t]=s.replace(/^workspace:/,"");continue}const r=zn(0,e);n.push([t,s,r]),i[t]=r}}l.writeFileSync(i,JSON.stringify(r,null,2)+"\n")}(t,e)}async function eo(t,e){const i=e?.pm?e.pm:void 0,s=new S({context:t,forcePackageManager:i});await s.install()}function io(){const t=t=>{try{return 0===k(t,["--version"],{stdio:"ignore",shell:"win32"===process.platform}).status}catch{return!1}};return{pnpm:t("pnpm"),yarn:t("yarn"),npm:t("npm")}}async function so(t,e,i){return qn(t,e,Bn(0,i),i)}class ro{constructor(){this.logger=new b}async create(t,e={}){const i=new x,s=e.cwd||process.cwd(),r=e.template||"react-ts",n=e.bundler||"webpack",o=e.pm||void 0,a=Un();let l;try{({targetDir:l}=Gn(t,s))}catch(t){this.logger.error(t.message),process.exit(1)}i.logWithSpinner("📦",`正在创建项目 ${t}...`);const c=Zn(r);await Xn({targetDir:l,templateDir:c,projectName:t,description:e.description,bundler:n,ssr:!!e.ssr}),to(l,a),this.logger.info(`依赖模式:npm 模式(^${a.cliVersion})`);const h=Qn(l,n,a);if(h){const[t,e]=h;this.logger.info(`已写入 ${t}@${e} 到 devDependencies`)}else this.logger.warn(`bundler "${n}" 不在内置列表中,跳过 devDeps 写入`);const u="1"===process.env.DEVKIT_SKIP_INSTALL;u||(i.logWithSpinner("📦","正在安装依赖..."),await eo(l,{pm:o}),i.stopSpinner(!1)),this.logger.done(`项目 ${t} 创建成功!`);const p=process.env.DEVKIT_NO_PROMPT;process.env.DEVKIT_NO_PROMPT="1";let d=!1;try{const t=Kn(r);d=await so(t,l,this.logger)}finally{void 0===p?delete process.env.DEVKIT_NO_PROMPT:process.env.DEVKIT_NO_PROMPT=p}d&&(to(l,a),u||(this.logger.info("正在安装追加的依赖..."),await eo(l,{pm:o})));const m="npm"===o?"npm run dev":`${o||"pnpm"} dev`;this.logger.log(`\n cd ${t}`),this.logger.log(` ${m}\n`)}}const no={mock:"@bundlekit/plugin-mock",react:"@bundlekit/plugin-react",vue:"@bundlekit/plugin-vue",request:"@bundlekit/request"};class oo{constructor(t){this.context=t||process.cwd(),this.logger=new b}async add(t){const e=function(t){const e=(()=>{const e=_(t);return e?v[e]:null})();if(e)return e;const[i]=t.split("@").filter(Boolean);return no[i]??t}(t),i=function(t){return/\/plugin-|^plugin-/.test(t)}(e),s=function(t){return/^@bundlekit\/bundler-/.test(t)}(e),r=i||s;this.logger.info(`解析插件: ${t} → ${e}`),this.logger.info("类型: "+(s?"构建工具适配器(devDependency)":i?"构建插件(devDependency)":"运行时库(dependency)"));const n=new S({context:this.context});if(await n.add(e,{dev:r})){if(this.logger.done(`已安装 ${e}`),i&&!s){const t=Bn(this.context,this.logger);if(await qn(e,this.context,t,this.logger)){this.logger.info("正在安装追加的依赖...");const t=new S({context:this.context});await t.install()}}}else this.logger.error(`安装 ${e} 失败`)}}const ao=({version:t=""})=>N(d,{flexDirection:"column",marginBottom:1,children:[F(I,{name:"atlas",children:F(L,{text:"DEVKIT-CLI",font:"block"})}),F(d,{marginLeft:1,children:F(m,{dimColor:!0,children:`bundlekit${t?` v${t}`:""} · 多打包器构建工具`})})]}),lo=({title:t,step:e,total:i,children:s})=>N(d,{flexDirection:"column",borderStyle:"round",borderColor:"cyan",paddingX:1,marginBottom:1,children:[F(d,{marginBottom:1,children:F(m,{bold:!0,color:"cyan",children:e&&i?`Step ${e}/${i} · ${t}`:t})}),s]});function co(t,e,i){if(0===t.length)return-1;const s=t.length;let r=e;for(let e=0;e<s;e++)if(r=(r+i+s)%s,!t[r].disabled)return r;return-1}function ho(t){const{items:r,initialValue:n,onSelect:o,onBack:a}=t,l=e(()=>{if(n){const t=r.findIndex(t=>t.value===n&&!t.disabled);if(t>=0)return t}const t=r.findIndex(t=>!t.disabled);return t>=0?t:0},[r,n]),[c,h]=i(l);return s(()=>{if(c>=r.length||r[c]?.disabled){const t=r.findIndex(t=>!t.disabled);h(t>=0?t:0)}},[r]),f((t,e)=>{if(e.upArrow||"k"===t){const t=co(r,c,-1);return void(t>=0&&h(t))}if(e.downArrow||"j"===t){const t=co(r,c,1);return void(t>=0&&h(t))}if(e.return){const t=r[c];return void(t&&!t.disabled&&o(t.value))}(e.escape||e.backspace||e.delete)&&a&&a()}),F(d,{flexDirection:"column",children:r.map((t,e)=>{const i=e===c,s=!!t.disabled,r=i?"▶ ":" ",n=s?void 0:i?"cyan":void 0,o=s||!i,a=s&&t.disabledReason?` ${t.disabledReason}`:"";return N(d,{children:[F(m,{color:i&&!s?"cyan":void 0,children:r}),N(m,{color:n,dimColor:o,children:[t.label,a]})]},String(t.value))})})}const uo=({value:t,placeholder:e,onChange:i,onSubmit:s})=>F(R,{value:t,placeholder:e,onChange:i,onSubmit:s}),po={pending:"○",running:"",done:"✔",error:"✘"},mo={pending:"gray",running:"cyan",done:"green",error:"red"},fo=({tasks:t})=>F(d,{flexDirection:"column",children:t.map(t=>N(d,{children:[F(d,{width:3,children:"running"===t.status?F(m,{color:"cyan",children:F(V,{type:"dots"})}):F(m,{color:mo[t.status],children:po[t.status]})}),F(m,{color:"pending"===t.status?"gray":void 0,children:t.label}),t.detail?N(m,{dimColor:!0,children:[" (",t.detail,")"]}):null]},t.id))});function go(t,e){return"npm"===t?`npm run ${e}`:`${t} ${e}`}const yo=({name:t,bundler:e,template:i,pm:s="pnpm"})=>{const r=go(s,"dev"),n=go(s,"build");return N(d,{flexDirection:"column",marginTop:1,children:[N(d,{children:[F(m,{color:"green",bold:!0,children:" ✔ 项目 "}),F(m,{color:"cyan",bold:!0,children:t}),F(m,{color:"green",bold:!0,children:" 创建成功"})]}),N(d,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"green",paddingX:1,children:[i&&N(d,{children:[F(m,{dimColor:!0,children:"模板 "}),F(m,{color:"cyan",children:i})]}),N(d,{children:[F(m,{dimColor:!0,children:"打包器 "}),F(m,{color:"cyan",children:e})]}),N(d,{children:[F(m,{dimColor:!0,children:"包管理器 "}),F(m,{color:"cyan",children:s})]}),N(d,{children:[F(m,{dimColor:!0,children:"位置 "}),F(m,{color:"cyan",children:`./${t}`})]})]}),N(d,{flexDirection:"column",marginTop:1,children:[F(m,{dimColor:!0,children:"下一步:"}),N(d,{marginLeft:2,marginTop:1,flexDirection:"column",children:[N(d,{children:[F(m,{color:"gray",children:"$ "}),F(m,{color:"cyan",children:`cd ${t}`})]}),N(d,{children:[F(m,{color:"gray",children:"$ "}),F(m,{color:"cyan",children:r}),F(m,{dimColor:!0,children:` 使用 ${e} 启动开发服务`})]}),N(d,{children:[F(m,{color:"gray",children:"$ "}),F(m,{color:"cyan",children:n}),F(m,{dimColor:!0,children:" 生产构建"})]})]})]}),N(d,{marginTop:1,children:[F(m,{dimColor:!0,children:"提示:"}),N(m,{dimColor:!0,children:["使用 ",N(m,{color:"cyan",children:["dc add bundler-","<name>"]})," 切换打包器,使用 ",N(m,{color:"cyan",children:["dc add ","<plugin>"]})," 追加插件"]})]})]})},wo=({step:t,message:e,stack:i})=>N(d,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:[F(d,{children:N(m,{color:"red",bold:!0,children:["✘ ",t," 失败"]})}),F(d,{marginTop:1,children:F(m,{color:"redBright",children:e})}),i?F(d,{marginTop:1,children:F(m,{dimColor:!0,children:i})}):null]}),bo=[{label:"React + TypeScript",value:"react-ts"},{label:"React + JavaScript",value:"react-js"},{label:"Vue 3 + TypeScript",value:"vue3-ts"},{label:"Vue 3 + JavaScript",value:"vue3-js"}],vo=[{label:"Vite —— 开发体感最佳",value:"vite"},{label:"Webpack —— 生态最完整",value:"webpack"},{label:"Rspack —— Rust 实现,极速",value:"rspack"},{label:"更多打包器 →",value:"__more__"}],_o=[{label:"Rollup —— 适合库构建",value:"rollup"},{label:"Rolldown —— 实验性",value:"rolldown"},{label:"← 返回",value:"__back__"}],So=["pnpm","yarn","npm"],xo={pnpm:"pnpm —— 推荐,磁盘占用最小",yarn:"yarn —— 兼容性好",npm:"npm —— Node 内置"};const Oo=({params:t})=>{const{exit:n}=g(),[o,a]=i(t.template),[l,c]=i(t.bundler),[h,u]=i("primary"),p=e(()=>io(),[]),f=e(()=>function(){const t=process.env.DEVKIT_PM;if("pnpm"===t||"yarn"===t||"npm"===t)return t}(),[]),[y,w]=i(function(t,e,i){return t&&i[t]?t:e&&i[e]?e:void 0}(t.pm,f,p));e(()=>Un(t.cwd||process.cwd()),[t.cwd]);const[v,_]=i(t.description||""),[S,x]=i(void 0!==t.description),[O,C]=i([]),[k,E]=i(null);let A;A=k?"error":O.length>0&&O.every(t=>"done"===t.status)?"done":O.length>0?"tasks":o?l?y?S?"tasks":"description":"pm":"bundler":"template";const $=r((t,e)=>{C(i=>i.map(i=>i.id===t?{...i,...e}:i))},[]);s(()=>{if("tasks"!==A)return;if(O.length>0)return;C([{id:"render",label:"渲染模板",status:"pending"},{id:"normalize",label:"规范化依赖版本",status:"pending"},{id:"deps",label:"写入 bundler 到 devDependencies",status:"pending"},{id:"install",label:"安装依赖",status:"pending"},{id:"generator",label:"调用框架插件 generator",status:"pending"}]),(async()=>{const e=t.cwd||process.cwd();let i;try{({targetDir:i}=Gn(t.name,e))}catch(t){return void E({step:"校验项目",message:t.message})}const s=new b,r=Un();try{$("render",{status:"running"});const e=Zn(o);await Xn({targetDir:i,templateDir:e,projectName:t.name,description:v,bundler:l,ssr:!!t.ssr}),$("render",{status:"done"})}catch(t){const e=t;return $("render",{status:"error"}),void E({step:"渲染模板",message:e.message,stack:e.stack})}try{$("normalize",{status:"running"}),to(i,r);const t=`npm 模式 → ^${r.cliVersion}`;$("normalize",{status:"done",detail:t})}catch(t){const e=t;return $("normalize",{status:"error"}),void E({step:"规范化依赖版本",message:e.message,stack:e.stack})}try{$("deps",{status:"running"});const t=Qn(i,l,r);if(t){const[e,i]=t;$("deps",{status:"done",detail:`${e}@${i}`})}else $("deps",{status:"done",detail:"未识别的 bundler,跳过"})}catch(t){const e=t;return $("deps",{status:"error"}),void E({step:"写入 devDependencies",message:e.message,stack:e.stack})}try{$("install",{status:"running"}),await eo(i,{pm:y}),$("install",{status:"done"})}catch(t){const e=t;return $("install",{status:"error"}),void E({step:"安装依赖",message:e.message,stack:e.stack})}try{$("generator",{status:"running"});const t=Kn(o),e=process.env.DEVKIT_NO_PROMPT;process.env.DEVKIT_NO_PROMPT="1";let n=!1;try{n=await so(t,i,s)}finally{void 0===e?delete process.env.DEVKIT_NO_PROMPT:process.env.DEVKIT_NO_PROMPT=e}n&&(to(i,r),await eo(i,{pm:y})),$("generator",{status:"done"})}catch(t){const e=t;return $("generator",{status:"error"}),void E({step:"调用 generator",message:e.message,stack:e.stack})}})()},[A,O.length,o,l,y,v,t,$]),s(()=>{if("done"===A){const t=setTimeout(()=>n(),100);return()=>clearTimeout(t)}if("error"===A){const t=setTimeout(()=>{n(),process.exit(1)},100);return()=>clearTimeout(t)}},[A,n]);const P=e(()=>So.map(t=>({label:xo[t],value:t,disabled:!p[t],disabledReason:p[t]?void 0:"(未安装)"})),[p]);return N(d,{flexDirection:"column",children:[F(ao,{}),"template"===A&&F(lo,{title:"模板",step:1,total:4,children:F(ho,{items:bo,initialValue:o,onSelect:t=>a(t)})}),"bundler"===A&&N(lo,{title:"打包器",step:2,total:4,children:[N(d,{marginBottom:1,children:[F(m,{dimColor:!0,children:"已选模板:"}),N(m,{color:"cyan",children:[" ",o]})]}),F(ho,"primary"===h?{items:vo,initialValue:l,onSelect:t=>{"__more__"===t?u("secondary"):c(t)}}:{items:_o,onSelect:t=>{"__back__"===t?u("primary"):c(t)},onBack:()=>u("primary")})]}),"pm"===A&&N(lo,{title:"包管理器",step:3,total:4,children:[F(d,{marginBottom:1,children:F(m,{dimColor:!0,children:"用于安装项目依赖:"})}),F(ho,{items:P,onSelect:t=>w(t)})]}),"description"===A&&F(lo,{title:"项目描述(可选,按回车跳过)",step:4,total:4,children:F(uo,{value:v,placeholder:"A demo app",onChange:_,onSubmit:t=>{_(t||" "),x(!0)}})}),("tasks"===A||"done"===A)&&N(d,{flexDirection:"column",borderStyle:"round",borderColor:"cyan",paddingX:1,marginBottom:1,children:[N(d,{marginBottom:1,children:[F(m,{bold:!0,color:"cyan",children:"创建项目 "}),F(m,{bold:!0,children:t.name}),F(m,{dimColor:!0,children:` ${o} · ${l} · ${y}`})]}),F(fo,{tasks:O})]}),"done"===A&&F(yo,{name:t.name,bundler:l,template:o,pm:y}),"error"===A&&k&&F(wo,{step:k.step,message:k.message,stack:k.stack})]})},Co=({params:t})=>{const{exit:e}=g(),[r,n]=i([{id:"resolve",label:`解析 ${t.plugin}`,status:"pending"},{id:"install",label:"安装依赖",status:"pending"},{id:"generator",label:"调用 generator (如有)",status:"pending"}]),[o,a]=i(null);return s(()=>{const i=(t,e)=>{n(i=>i.map(i=>i.id===t?{...i,...e}:i))};(async()=>{try{i("resolve",{status:"running"});const e=t.cwd||process.cwd(),s=new oo(e);i("resolve",{status:"done"}),i("install",{status:"running"}),await s.add(t.plugin),i("install",{status:"done"}),i("generator",{status:"done"})}catch(t){const e=t;a({step:"add",message:e.message,stack:e.stack})}finally{setTimeout(()=>e(),100)}})()},[t,e]),N(d,{flexDirection:"column",children:[F(ao,{}),N(d,{marginBottom:1,children:[F(m,{children:"追加:"}),N(m,{color:"cyan",bold:!0,children:[" ",t.plugin]})]}),F(fo,{tasks:r}),o&&F(wo,{step:o.step,message:o.message,stack:o.stack})]})},ko=t=>"create"===t.command?F(Oo,{params:t.params}):"add"===t.command?F(Co,{params:t.params}):null,Eo=new St,Ao=[{name:"react-ts",message:"React + TypeScript"},{name:"react-js",message:"React + JavaScript"},{name:"vue3-ts",message:"Vue 3 + TypeScript"},{name:"vue3-js",message:"Vue 3 + JavaScript"}],$o=[{name:"vite",message:"Vite"},{name:"webpack",message:"Webpack"},{name:"rspack",message:"Rspack"},{name:"rollup",message:"Rollup"},{name:"rolldown",message:"Rolldown"}];function Po(){return"1"!==process.env.DEVKIT_NO_INK&&(!!process.stdout.isTTY&&!!process.stdin.isTTY)}function Do(t){return"pnpm"===t||"yarn"===t||"npm"===t}async function To(t,e){const i=new Ni;if(!e.template){const t=await i.prompt({type:"select",name:"template",message:"请选择项目模板:",choices:Ao});e.template=t.template}if(!e.bundler){const t=await i.prompt({type:"select",name:"bundler",message:"请选择默认构建工具:",choices:$o});e.bundler=t.bundler}let s=Do(e.pm)?e.pm:void 0;if(s||(s=function(){const t=process.env.DEVKIT_PM;if("pnpm"===t||"yarn"===t||"npm"===t)return t}()),!s){const t=io(),e=["pnpm","yarn","npm"].filter(e=>t[e]).map(t=>({name:t,message:t}));if(0===e.length)s="npm";else if(1===e.length)s=e[0].name;else{s=(await i.prompt({type:"select",name:"pm",message:"请选择包管理器:",choices:e})).pm}}e.pm=s;const r=new ro;await r.create(t,e)}Eo.command("create <name>").description("create a new project powered by bundlekit-service").option("-t, --template <template>","模板类型 (react-ts, react-js, vue3-ts, vue3-js)").option("-b, --bundler <bundler>","默认构建工具 (vite, webpack, rspack, rollup, rolldown)").option("-d, --description <desc>","项目描述").option("--pm <pm>","包管理器 (pnpm, yarn, npm)").option("--ssr","启用 SSR:模板生成 entry-client/entry-server + .bundlekitrc.ts 加 ssr 配置块",!1).action(async(e,i)=>{if(!Po())return void await To(e,i);process.env.DEVKIT_QUIET="1";const s=Do(i.pm)?i.pm:void 0,{waitUntilExit:r}=y(t.createElement(ko,{command:"create",params:{name:e,template:i.template,bundler:i.bundler,pm:s,description:i.description,ssr:!!i.ssr}}));await r()}),Eo.command("add <plugin>").description("向已有项目添加插件 / bundler 适配器").action(async e=>{if(!Po()){const t=new oo(process.cwd());return void await t.add(e)}process.env.DEVKIT_QUIET="1";const{waitUntilExit:i}=y(t.createElement(ko,{command:"add",params:{plugin:e}}));await i()}),Eo.command("help").alias("h").description("处理帮助信息 -h").action(()=>{Eo.outputHelp()}),Eo.command("version").alias("v").description("bundlekit-cli版本 -v").action(()=>{const t=require("../package.json");console.log(`bundlekit-cli v${t.version}`)}),Eo.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bundlekit/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "a cli tool serve for generate frontend project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.mjs",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"bin": {
|
|
15
15
|
"bundlekit-cli": "./dist/index.mjs",
|
|
16
|
-
"
|
|
16
|
+
"bc": "./dist/index.mjs"
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
19
|
"dist"
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"ink-spinner": "^5.0.0",
|
|
42
42
|
"ink-text-input": "^6.0.0",
|
|
43
43
|
"react": "^18.3.0",
|
|
44
|
-
"@bundlekit/plugin-react": "0.0.
|
|
45
|
-
"@bundlekit/
|
|
46
|
-
"@bundlekit/
|
|
44
|
+
"@bundlekit/plugin-react": "0.0.2",
|
|
45
|
+
"@bundlekit/plugin-vue": "0.0.2",
|
|
46
|
+
"@bundlekit/shared-utils": "0.0.2"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@rollup/plugin-commonjs": "^25.0.7",
|