@doracli/dora 0.0.18 → 0.0.19

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.
Files changed (2) hide show
  1. package/bin/entry-fun.mjs +1 -1
  2. package/package.json +14 -17
package/bin/entry-fun.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #! /usr/bin/env node
2
- import{createProgram as o,dealOptions as e}from"@doracli/commander";import{HtmlAssetManager as t,configCtxWorkflow as a,ConfigCtx as r,collectBaseConfigMw as s,collectPackageJsonMw as i,collectTsconfigJsonMw as n,collectDoraConfigMw as c,collectCdnConfigMw as p,wholeDoraConfigMw as m,wholeDoraInoutMw as l,clearMw as d,createEnvParams as u,cLog as f,picocolors as g}from"@doracli/helper";import{getServerMutipleCtxList as w,childCommands as v}from"@doracli/webpack-react";import h from"@dorabag/open-browser";import{portGetter as C}from"@dorabag/srv-tool";import{conditionalBodyParser as b,proxyMiddleware as y,fileServerMiddleware as k,createServer as D,loggerMiddleware as P,corsMiddleware as R}from"@doracli/express";import{getServerCtx as x,ServerWorkflow as $}from"@doracli/express-server";import{join as j}from"path";import{Compiler as S,collectAssetUrls as A,htmlRouteGeneratorMw as B}from"@doracli/webpack";const E={output:{path:"./dist"},formatList:["cjs"],alias:{},externals:[],internals:[],copy:[],dts:{},clear:!1,minimize:!1,webpackConfig:{},serviceConfig:{host:"localhost",publicPath:"/pages",openBrowser:!0,port:7777,scan:"server",pathRouteMap:{}}},H=async o=>{const e=u({workRootDir:o?.workRootDir,action:"server"}),g=await(async(o,e,t)=>{const u=a(new r);return u.use(s(o.workRootDir,e)),u.use(i()),u.use(n()),u.use(c("build"===o.action?"production":"development")),u.use(p("build"===o.action?"production":"development")),u.use(m(t)),u.use(l()),u.use(d()),await u.getResult()})(e,o,E),v=D({});v.use(P),v.use(R);const H=C(g.getDoraConfig().serviceConfig?.port||3e3),I=await H();await(async(o,e,t)=>{const a=await x(o,e,t);e.use(b(a.serverConfig.proxy)),e.use(y(a));const r=new $(a);await r.scan(),r.listen()})(g,v,e),await(async(o,e,a,r)=>{const{startPort:s}=r,i=C(s),{publicPath:n}=o.getDoraConfig().serviceConfig,c=new t(n),p=await w(o,{...a,action:"server"});p.forEach(o=>{c.updateAssetList((o.getDoraConfig().multiple||[]).map(o=>o.name))}),await Promise.all(p.map(async o=>{const e=await i();o.updateDevServerConfig({port:e,open:!1,host:"0.0.0.0",allowedHosts:"all"});const{compiler:t,server:a}=await new S(o.webpackConfig).context({});A(t,o=>{c.updateAssetMap(o)},{hostname:"localhost",port:o.devServerConfig.port}),await a(o.devServerConfig)})),e.use(await B(c,o))})(g,v,e,{startPort:await H()}),await(async(o,e)=>{const{static:t}=o.getDoraConfig().serviceConfig||{};Object.entries(t||{}).forEach(([t,a])=>{e.use(k(a,j(o.getWorkRoot(),t)))})})(g,v),v.route("/").get((o,e)=>{e.send("Hello, @doracli/express-server!")}),v.listen(I,"0.0.0.0",()=>{const{publicPath:o,openBrowser:e}=g.getDoraConfig().serviceConfig||{};f.info("ser","started",`http://localhost:${I}${o}`),f.info("ser","lan",`局域网请用本机 IP 访问,例如 http://<局域网IP>:${I}${o}`),e&&h(`http://localhost:${I}${o}`)})},I={name:"magic",usage:"magic <command> [option]",version:"0.0.17",childCommands:[{command:"server",description:"run a project by dev",options:[{name:"format",simpleName:"f",type:"['amd','cjs','es','iife','system','umd','commonjs','esm','module','systemjs']",description:"set output module type"},{name:"workRootDir",simpleName:"r",type:"[string]",description:"set work root path",defaultValue:"./"}],action:o=>{H(o)}},...v.filter(o=>["build","dev"].includes(o.command))]},L=o();e(I)(L),L.on("--help",function(){console.log(),console.log(`Run ${g.cyan("dora <command> --help")} for detailed usage of given command.`),console.log()});var M=()=>{L.parse(process.argv)};export{M as default};
2
+ import{logger as n,ansi as e}from"@cclr/logger";import{createProgram as t,dealOptions as r}from"@doracli/commander";import{childCommands as o}from"@doracli/webpack-react";import{resolve as a}from"path";import s from"@dorabag/open-browser";import{getPipelineConfigCtxExpress as i,ExpressCtx as p,createServerApp as d}from"@doracli/express";import{uriPathJoin as l,uriGetPathStr as c}from"@cclr/utils";import{portGetter as g}from"@dorabag/srv-tool";import{proxyHttp as f,getSingleModuleName as m}from"@doracli/tool";import{splitDoraConfigFroWebpack as h,getPipelineWebpackReact as u,getPipeWebpackDevServer as v,WebpackCompiler as b}from"@doracli/webpack";import{URL as x}from"url";import{getPipelineExpressServer as w}from"@doracli/express-server";const $={output:{path:"./dist"},formatList:["cjs"],alias:{},externals:[],internals:[],copy:[],dts:{},clear:!1,minimize:!1,webpackConfig:{},serviceConfig:{host:"localhost",publicPath:"/pages",openBrowser:!0,port:7777,scan:"server",pathRouteMap:{},static:{"./public":"/"}}},y=/\.(?:js|css|map|woff2?|ttf|eot|otf|png|jpe?g|gif|svg|webp|ico|json|wasm)(?:\?.*)?$/i,k=(n,e)=>e.find(e=>n===e.path||n.startsWith(`${e.path}/`)),C=(e,t,r)=>{const o=l("/",t||"/pages"),a=[...r].sort((n,e)=>e.path.length-n.path.length);e.use((n,e,t)=>{const r=c(n.url||"")||"";if(r===o||r===`${o}/`)return t();const s=((n,e,t)=>{const r=k(n,t);if(r)return{page:r,matchedBy:"path"};if(!e)return null;try{const n=new x(e).pathname||"",r=k(n,t);if(r)return{page:r,matchedBy:"referer"}}catch{}return null})(r,n.headers.referer,a);if(!s)return t();if("referer"===s.matchedBy&&!y.test(r))return t();const{page:i,matchedBy:p}=s,d="path"===p&&!y.test(r),g=(n.url||"").indexOf("?"),m=g>=0?(n.url||"").slice(g):"",h=((n,e,t)=>{if(!t)return n;const r=n.slice(e.path.length)||"/";return l("/",e.targetPrefix||"/",r)})(r,i,d),u=new x(`${h}${m}`,i.targetOrigin);f({req:n,res:e,targetUrl:u,logTag:"pages",errorStatus:502})}),n.info("pages",`资源代理已挂载:html 入口路径映射,其它只换域名 → 模块端口(${o}/:name)`)},z=n=>n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"),P=(n,e,t)=>{const r=(n=>{const e=new Map;return n.forEach(n=>{const t=e.get(n.targetOrigin)||[];t.push(n),e.set(n.targetOrigin,t)}),[...e.entries()]})(n),o=r.length,a=l("/",t||"/pages"),s=r.map(([n,e],t)=>{const r=e.map(n=>{const e=(n=>`${n.targetOrigin}${n.targetPrefix||"/"}`)(n);return`<tr>\n <td class="name"><a href="${z(n.url)}">${z(n.name)}</a></td>\n <td><code>${z(n.path)}</code></td>\n <td><code>${z(n.targetPrefix||"/")}</code></td>\n <td class="upstream"><a href="${z(e)}" target="_blank" rel="noreferrer">${z(e)}</a></td>\n</tr>`}).join("\n");return`<section class="service">\n <header class="service-head">\n <span class="badge">#${t+1}</span>\n <div class="service-meta">\n <div class="service-title">热更服务</div>\n <div class="service-sub">\n <span>origin <code>${z(n)}</code></span>\n <span>模块 ${e.length} 个</span>\n </div>\n </div>\n </header>\n <div class="table-wrap">\n <table>\n <thead>\n <tr>\n <th>模块</th>\n <th>代理路径</th>\n <th>WDS 前缀</th>\n <th>上游直连</th>\n </tr>\n </thead>\n <tbody>\n${r}\n </tbody>\n </table>\n </div>\n</section>`}).join("\n");return`<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n <meta charset="UTF-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1.0" />\n <title>${z(e)}</title>\n <style>\n :root {\n --bg: #f6f8fa;\n --panel: #ffffff;\n --text: #1f2328;\n --muted: #656d76;\n --border: #d0d7de;\n --link: #0969da;\n --badge: #eef2f6;\n --row-hover: #f3f6f9;\n }\n * { box-sizing: border-box; }\n body {\n margin: 0;\n color: var(--text);\n background:\n radial-gradient(1200px 400px at 10% -10%, #e8eef5 0%, transparent 55%),\n var(--bg);\n font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;\n line-height: 1.5;\n }\n .wrap {\n max-width: 1080px;\n margin: 0 auto;\n padding: 40px 24px 64px;\n }\n .hero {\n margin-bottom: 28px;\n }\n .hero h1 {\n margin: 0 0 8px;\n font-size: 28px;\n font-weight: 650;\n letter-spacing: -0.02em;\n }\n .hero p {\n margin: 0;\n color: var(--muted);\n font-size: 14px;\n }\n .stats {\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n margin-top: 16px;\n }\n .stat {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border: 1px solid var(--border);\n border-radius: 10px;\n background: var(--panel);\n font-size: 13px;\n color: var(--muted);\n }\n .stat strong {\n color: var(--text);\n font-weight: 650;\n }\n .service {\n margin-bottom: 18px;\n border: 1px solid var(--border);\n border-radius: 14px;\n background: var(--panel);\n overflow: hidden;\n box-shadow: 0 1px 0 rgba(31, 35, 40, 0.04);\n }\n .service-head {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 14px 16px;\n border-bottom: 1px solid var(--border);\n background: linear-gradient(180deg, #fbfcfd 0%, #f7f9fb 100%);\n }\n .badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 36px;\n height: 28px;\n padding: 0 8px;\n border-radius: 8px;\n background: var(--badge);\n color: var(--muted);\n font-size: 12px;\n font-weight: 650;\n font-variant-numeric: tabular-nums;\n }\n .service-title {\n font-size: 15px;\n font-weight: 650;\n }\n .service-sub {\n display: flex;\n flex-wrap: wrap;\n gap: 12px 16px;\n margin-top: 4px;\n color: var(--muted);\n font-size: 12px;\n }\n .table-wrap { overflow-x: auto; }\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n th, td {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--border);\n vertical-align: top;\n }\n th {\n color: var(--muted);\n font-size: 12px;\n font-weight: 600;\n background: #fafbfc;\n white-space: nowrap;\n }\n tr:last-child td { border-bottom: none; }\n tbody tr:hover { background: var(--row-hover); }\n td.name a {\n font-weight: 650;\n font-size: 14px;\n }\n a {\n color: var(--link);\n text-decoration: none;\n }\n a:hover { text-decoration: underline; }\n code {\n font-family: ui-monospace, SFMono-Regular, Consolas, monospace;\n font-size: 12px;\n color: #24292f;\n background: #f3f5f7;\n border: 1px solid #e6eaef;\n border-radius: 6px;\n padding: 2px 6px;\n word-break: break-all;\n }\n .upstream a {\n font-family: ui-monospace, SFMono-Regular, Consolas, monospace;\n font-size: 12px;\n color: var(--muted);\n word-break: break-all;\n }\n .upstream a:hover { color: var(--link); }\n .empty {\n padding: 28px 16px;\n border: 1px dashed var(--border);\n border-radius: 14px;\n background: var(--panel);\n color: var(--muted);\n text-align: center;\n }\n .tip {\n margin-top: 18px;\n color: var(--muted);\n font-size: 12px;\n }\n </style>\n</head>\n<body>\n <div class="wrap">\n <div class="hero">\n <h1>${z(e)}</h1>\n <p>Express 同源代理入口;点击模块名走代理,上游直连可对照调试。</p>\n <div class="stats">\n <div class="stat">页面 <strong>${n.length}</strong></div>\n <div class="stat">热更服务 <strong>${o}</strong></div>\n <div class="stat">代理前缀 <strong>${z(a)}</strong></div>\n </div>\n </div>\n ${n.length?s:'<p class="empty">暂无页面,请检查 multiple / entry 配置</p>'}\n <p class="tip">访问形态:/pages/{name} → 对应端口 WDS;HTML 内资源路径会改写到代理路径下。</p>\n </div>\n</body>\n</html>`},j=n=>"0.0.0.0"===n||"::"===n||"::1"===n||"localhost"===n?"127.0.0.1":n,D=(e={})=>t=>r=>async()=>{if(!1===e.enable)return r();const o=Number(t.serverConfig.port||3e3)+(e.portOffset??1),a=g(o),s=l("/",t.serverConfig.publicPath||"/pages"),i=h(t.configCtx.doracliConfig),p=i.length,d=[];n.info("webpack",`共 ${p} 个热更服务,正在启动...`);for(let e=0;e<p;e++){const r=i[e],o=await a(),c=t.configCtx.copy();c.doracliConfig={...r,serviceConfig:{...r.serviceConfig,port:o,openBrowser:!1,host:"127.0.0.1",allowedHosts:r.serviceConfig?.allowedHosts||"all"}};const g=u(c);g.use("getPipeWebpackDevServer",void 0,v);const f=await g.run(),h=new b,x=await h.context(f.webpackConfig),{host:w,port:$}=await x.server(f.devServerConfig),{moduleMap:y}=f,k=`http://${j(w)}:${$}`,C=(t,r)=>{const o=l(s,t);d.push({name:t,path:o,url:o,targetOrigin:k,targetPrefix:r}),n.info("webpack",`${e+1}/${p} [${t}] ${o} → ${k}${r||"/"}`)},z=y[m()];z?C(z.name,""):Object.keys(y).forEach(n=>{const e=y[n].name;C(e,`/${e}`)})}return((e,t,r)=>{const o=l("/",t||"/pages"),a=(n,e)=>{e.type("html").send(P(r,"Dora Pages",o))};e.get(o,a),"/"!==o&&e.get(`${o}/`,a),n.info("pages",`目录路由已挂载 ${o} (${r.length} 页)`)})(t.app,s,d),C(t.app,s,d),n.info("webpack","热更服务启动完成"),r()},O=async t=>{const{workRootDir:r="./"}=t,o=i({action:"server",env:"development",workRootDir:r,workRootDirAbsolute:a(r)},t);o.set("getPipeDoraConfig",{presetConfig:$});const l=await o.run();let c;try{const n=(n=>{const e=w(n);return e.use("getPipeExpressWebpack",{portOffset:1},D),e})(new p(l,d()));c=await n.run()}catch(e){return n.error("server","服务管道启动失败",e),void(process.exitCode=1)}const g=Number(c.serverConfig.port||3e3),f=c.serverConfig.host||"localhost",m=c.serverConfig.publicPath||"/",h=`http://${f}:${g}${m}`;c.app.listen(g,"0.0.0.0",()=>{n.info("server",`${e.green("ready")} ${e.cyan(h)}`),n.info("server",`局域网请用本机 IP 访问,例如 http://<局域网IP>:${g}${m}`),c.serverConfig.openBrowser&&s(h)})},S={name:"magic",usage:"magic <command> [option]",version:"0.0.18",childCommands:[{command:"server",description:"run a project by dev",options:[{name:"format",simpleName:"f",type:"['amd','cjs','es','iife','system','umd','commonjs','esm','module','systemjs']",description:"set output module type"},{name:"workRootDir",simpleName:"r",type:"[string]",description:"set work root path",defaultValue:"./"},{name:"debug",simpleName:"d",type:"[boolean]",description:"set debug mode",defaultValue:!1}],action:e=>{e.debug&&n.setLevel(0),O(e)}},...o.filter(n=>["build","dev"].includes(n.command))]},B=t();n.setBrand("dora"),r(S)(B),B.on("--help",function(){console.log(),console.log(`Run ${e.cyan("dora <command> --help")} for detailed usage of given command.`),console.log()});var R=()=>{B.parse(process.argv)};export{R as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doracli/dora",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "description": "哆啦 ( dora ),用于开发react项目,基于webpack构建,集成热更新服务功能",
5
5
  "author": "cclr <18843152354@163.com>",
6
6
  "homepage": "",
@@ -34,25 +34,22 @@
34
34
  "g:build:webpack": "npm run build"
35
35
  },
36
36
  "dependencies": {
37
- "@cclr/lang": "^0.1.62",
38
- "@cclr/utils": "^0.1.62",
39
- "@dorabag/file-pro": "^1.0.18",
37
+ "@cclr/lang": "^0.1.67",
38
+ "@cclr/logger": "^0.1.67",
39
+ "@cclr/utils": "^0.1.67",
40
40
  "@dorabag/open-browser": "^1.0.26",
41
41
  "@dorabag/srv-tool": "^1.0.26",
42
- "@doracli/commander": "^0.0.18",
43
- "@doracli/express": "^0.0.18",
44
- "@doracli/express-server": "^0.0.18",
45
- "@doracli/helper": "^0.0.18",
46
- "@doracli/type": "^0.0.18",
47
- "@doracli/webpack": "^0.0.18",
48
- "@doracli/webpack-react": "^0.0.18",
49
- "webpack-dev-middleware": "^7.4.5",
50
- "webpack-hot-middleware": "^2.26.1",
51
- "ws": "^8.21.1"
42
+ "@doracli/commander": "^0.0.19",
43
+ "@doracli/express": "^0.0.19",
44
+ "@doracli/express-server": "^0.0.19",
45
+ "@doracli/tool": "^0.0.19",
46
+ "@doracli/type": "^0.0.19",
47
+ "@doracli/webpack": "^0.0.19",
48
+ "@doracli/webpack-react": "^0.0.19"
52
49
  },
53
- "gitHead": "7d8e223ca570deda1c412d76ad41569525b4f074",
50
+ "gitHead": "ecb5d51e285fd63c9b0574b24d9e823b41207c84",
54
51
  "devDependencies": {
55
- "webpack": "^5.108.4",
56
- "webpack-dev-server": "^5.2.6"
52
+ "webpack": "^5.112.2",
53
+ "webpack-dev-server": "^5.2.7"
57
54
  }
58
55
  }