@bundlekit/bundler-rollup 0.0.3 → 0.0.5
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/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("path"),t=require("fs"),r=require("rollup"),s=require("@rollup/plugin-node-resolve"),o=require("@rollup/plugin-commonjs"),i=require("@rollup/plugin-typescript"),n=require("@rollup/plugin-babel"),l=require("@rollup/plugin-image"),a=require("@rollup/plugin-json"),c=require("@rollup/plugin-replace"),u=require("rollup-plugin-postcss"),p=require("@bundlekit/shared-utils"),d=require("http"),h=require("https"),m=require("os"),g=require("child_process");const f={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".cjs":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml; charset=utf-8",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject",".map":"application/json",".txt":"text/plain; charset=utf-8",".xml":"application/xml",".webp":"image/webp"},v="<script data-bundlekit=\"livereload\">\n(function () {\n var sse = new EventSource('/__bundlekit_sse');\n sse.addEventListener('message', function (e) {\n if (e.data === 'reload') {\n console.log('[bundlekit] livereload triggered');\n location.reload();\n }\n });\n sse.onerror = function () {\n sse.close();\n setTimeout(function () { location.reload(); }, 2000);\n };\n})();\n<\/script>";class y{constructor(e,t){this.server=null,this.sseClients=new Set,this.options=e,this.logger=t}reload(){const e=[];for(const t of this.sseClients)try{t.write("data: reload\n\n")}catch{e.push(t)}e.forEach(e=>this.sseClients.delete(e))}start(){return new Promise((r,s)=>{this.server=d.createServer(async(r,s)=>{const o=r.url??"/";if(o.startsWith("/__bundlekit_sse"))return s.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"}),s.write(":ok\n\n"),this.sseClients.add(s),void r.on("close",()=>this.sseClients.delete(s));if(await this.handleProxy(r,s))return;const i=this.resolveFilePath(o);if(!i)return s.writeHead(404,{"Content-Type":"text/plain"}),void s.end(`Cannot GET ${o}`);const n=e.extname(i).toLowerCase(),l=f[n]??"application/octet-stream";try{if(".html"===n){let e=t.readFileSync(i,"utf-8");e=e.includes("</body>")?e.replace("</body>",`${v}\n</body>`):e+v,s.writeHead(200,{"Content-Type":l}),s.end(e)}else{const e=t.statSync(i).size;s.writeHead(200,{"Content-Type":l,"Content-Length":e}),t.createReadStream(i).pipe(s)}}catch(e){this.logger.error(`[bundlekit] 读取文件失败: ${e.message}`),s.writeHead(500),s.end("Internal Server Error")}}),this.server.on("error",s),this.server.listen(this.options.port,this.options.host,()=>{const e=this.server.address().port,t=this.getLocalIP();this.logger.clearConsole("Dev Server 启动成功"),this.logger.done("服务已启动:","🌐"),this.logger.log(` - 本地: http://localhost:${e}`),this.logger.log(` - 网络: http://${t}:${e}`),this.logger.log(""),this.options.open&&this.openBrowser(`http://localhost:${e}`),r()})})}close(){for(const e of this.sseClients)try{e.end()}catch{}this.sseClients.clear(),this.server?.close(),this.server=null}resolveFilePath(r){let s=r.split("?")[0];try{s=decodeURIComponent(s)}catch{}const o=this.options.outDir,i=[e.join(o,s),e.join(o,s,"index.html"),e.join(o,"index.html")];for(const e of i)try{if(t.statSync(e).isFile())return e}catch{}return null}async handleProxy(e,t){const r=this.options.proxy??{},s=e.url??"/";for(const[o,i]of Object.entries(r)){if(!s.startsWith(o))continue;const r="string"==typeof i?{target:i}:i;let n;try{n=new URL(r.target)}catch{return this.logger.error(`[bundlekit] 代理目标 URL 无效: ${r.target}`),t.writeHead(502),t.end("Bad Gateway: invalid proxy target"),!0}const l=r.rewrite?r.rewrite(s):s,a="https:"===n.protocol,c=a?h:d,u=a?443:80;return new Promise(s=>{const o=c.request({hostname:n.hostname,port:Number(n.port)||u,path:l,method:e.method,headers:{...e.headers,...!1!==r.changeOrigin?{host:n.host}:{}}},e=>{t.writeHead(e.statusCode??200,e.headers),e.pipe(t,{end:!0}),s(!0)});o.on("error",e=>{this.logger.error(`[bundlekit] 代理请求失败: ${e.message}`),t.headersSent||(t.writeHead(502),t.end(`Bad Gateway: ${e.message}`)),s(!0)}),e.pipe(o,{end:!0})})}return!1}getLocalIP(){for(const e of Object.values(m.networkInterfaces()))for(const t of e??[])if("IPv4"===t.family&&!t.internal)return t.address;return"localhost"}openBrowser(e){const t="darwin"===process.platform?`open "${e}"`:"win32"===process.platform?`start "" "${e}"`:`xdg-open "${e}"`;g.exec(t,e=>{e&&this.logger.warn(`[bundlekit] 打开浏览器失败: ${e.message}`)})}}const x={es:".mjs",esm:".mjs",cjs:".cjs",commonjs:".cjs",umd:".umd.js",iife:".iife.js"},w=e=>({commonjs:"cjs",esm:"es",es:"es",cjs:"cjs",umd:"umd",iife:"iife"}[e]??"es");function j(r){let s=[],o=[];try{const e=t.readdirSync(r.outDir);s=e.filter(e=>/\.(js|mjs|cjs)$/.test(e)&&!e.endsWith(".map")),o=e.filter(e=>e.endsWith(".css")&&!e.endsWith(".map"))}catch{}const i=o.map(e=>` <link rel="stylesheet" href="${e}">`).join("\n"),n=s.map(e=>` <script src="${e}"><\/script>`).join("\n");let l;const a=r.template?e.resolve(r.context,r.template):null;if(a&&t.existsSync(a)){l=t.readFileSync(a,"utf-8"),i&&(l=l.includes("</head>")?l.replace("</head>",`${i}\n</head>`):i+"\n"+l);const e="head"===r.inject?"</head>":"</body>";l=l.includes(e)?l.replace(e,`${n}\n${e}`):l+n}else l=["<!DOCTYPE html>",'<html lang="en">',"<head>",' <meta charset="UTF-8">',' <meta name="viewport" content="width=device-width, initial-scale=1.0">'," <title>App</title>",...i?[i]:[],..."head"===r.inject?[n]:[],"</head>","<body>",' <div id="root"></div>',..."head"!==r.inject?[n]:[],"</body>","</html>"].join("\n");t.mkdirSync(r.outDir,{recursive:!0}),t.writeFileSync(e.join(r.outDir,r.filename),l,"utf-8")}const S=new Set(["cache","context","experimentalCacheExpiry","experimentalLogSideEffects","external","fs","input","jsx","logLevel","makeAbsoluteExternalsRelative","maxParallelFileOps","moduleContext","onLog","onwarn","output","perf","plugins","preserveEntrySignatures","preserveSymlinks","shimMissingExports","strictDeprecations","treeshake","watch"]);function b(e){return Object.fromEntries(Object.entries(e).filter(([e])=>S.has(e)))}module.exports=class{constructor(e,t){this.logger=new p.Logger,this.devServerConfig=null,this.htmlWriteConfig=null,this.name="@bundlekit/bundler-rollup",this.mode=t,this.context=e.context||process.cwd(),this.fse=new p.FileManager(this.context)}transformConfig(t){const r=[".js",".jsx",".ts",".tsx"],p=t.config?.[this.mode]||t.config?.development||{},d="node"===p.target,h=p.entry?"string"==typeof p.entry?p.entry:Object.values(p.entry)[0]:e.resolve(this.context,"src/index.ts"),m=(p.output&&!Array.isArray(p.output)?p.output.dir:void 0)||(Array.isArray(p.output)?p.output[0]?.dir:void 0)||"dist",g=e.resolve(this.context,m),f=p.css||{},v=!0===p.library,y=p.libraryName,j=p.output?.formats,S=Array.isArray(j)?j:[j||"es"],b=p.output?.filename||"index.js",C=/\[.+?\]/.test(b)?"index.js":b,E=b.replace(/\[.+?\]/g,"").replace(/\.[^.]+$/,"")||"index",$="production"===this.mode?"production":"development",D=[c({preventAssignment:!0,values:{"process.env.NODE_ENV":JSON.stringify($),"import.meta.env.MODE":JSON.stringify($),"import.meta.env.PROD":String("production"===$),"import.meta.env.DEV":String("production"!==$),"import.meta.env.SSR":"false","import.meta.env":JSON.stringify({MODE:$,DEV:"production"!==$,PROD:"production"===$,SSR:!1})}}),s({extensions:r,browser:!0,preferBuiltins:!1}),o(),a(),l(),u({extract:f.extract||!1,modules:f.modules||!1,sourceMap:f.sourcemap||!1,use:[...f.loaders?.includes("less")?["less"]:[],...f.loaders?.includes("sass")||f.loaders?.includes("scss")?["sass"]:[]]}),i({tsconfig:e.resolve(this.context,"tsconfig.json"),outDir:g,declaration:v,noEmit:!1,sourceMap:p.js?.sourcemap??!1}),n({babelHelpers:"bundled",extensions:r,exclude:["node_modules/**"],presets:[["@babel/preset-env",{modules:!1}],"@babel/preset-typescript"]})];if(!v&&!d){const e=p.pages,t=e?.[0];this.htmlWriteConfig={outDir:g,template:t?.template,filename:t?.filename||"index.html",inject:t?.inject||"body",context:this.context}}const R=d?this.resolveServerExternals(p):p.externals||[];let k;if(d){const t=p.ssr,r="esm"===t?.output?.formats?"es":"cjs";k={file:e.resolve(g,t?.output?.filename||"server.cjs"),format:r,sourcemap:p.js?.sourcemap||!1,exports:"named",inlineDynamicImports:!0}}else if(v&&S.length>1)k=S.map(t=>{const r=w(t),s=x[t]??".js";return{file:e.resolve(g,`${E}${s}`),format:r,sourcemap:p.js?.sourcemap||!1,name:["umd","iife"].includes(r)?y||e.basename(String(h),e.extname(String(h))):void 0,inlineDynamicImports:["umd","iife"].includes(r),exports:"named"}});else{const t=S[0]??"es",r=w(t);k=v?{file:e.resolve(g,`${E}${x[t]??".js"}`),format:r,sourcemap:p.js?.sourcemap||!1,name:["umd","iife"].includes(r)?y||e.basename(String(h),e.extname(String(h))):void 0,inlineDynamicImports:["umd","iife"].includes(r)}:{dir:g,entryFileNames:C,format:r,sourcemap:p.js?.sourcemap||!1}}return this.devServerConfig={host:p.devServer?.host??"0.0.0.0",port:p.devServer?.port??3e3,open:p.devServer?.open??!1,proxy:p.devServer?.proxy??{},outDir:g,library:v},{input:e.resolve(this.context,String(h)),output:k,plugins:D,external:R}}validateConfig(e,t){return!t||p.validateBuildConfig(t,this.mode).valid}resolveServerExternals(r){const s=r.ssr?.externals;if(Array.isArray(s))return s;const o=new Set;try{const r=e.join(this.context,"package.json");if(t.existsSync(r)){const e=JSON.parse(t.readFileSync(r,"utf-8"));Object.keys(e.dependencies||{}).forEach(e=>o.add(e)),Object.keys(e.peerDependencies||{}).forEach(e=>o.add(e))}}catch{}return t=>{if(t.startsWith("node:"))return!0;if(t.startsWith(".")||e.isAbsolute(t))return!1;if(o.has(t))return!0;for(const e of o)if(t===e||t.startsWith(e+"/"))return!0;return!1}}async run(e){try{this.logger.info("开始使用rollup进行打包");e.__isServerPass;switch(this.mode){case"development":if((!this.devServerConfig||!1!==this.devServerConfig.library||!Array.isArray(e.output))&&("cjs"===e.output?.format&&e.output?.file?.endsWith(".cjs"))){await this.prodBuild(e);break}await this.devBuild(e);break;case"production":case"test":case"staging":case"gray":await this.prodBuild(e)}}catch(e){throw this.logger.error(`打包失败, 错误信息: ${e}`),e}}async devBuild(t){const s=this.devServerConfig,o=s?.library??!1,i=b(t),n=r.watch({...i,watch:{clearScreen:!1,exclude:"node_modules/**"}});if(o)return this.logger.info("rollup library watch 模式已启动","rollup"),void n.on("event",e=>{"START"===e.code&&this.logger.log("rollup 开始重新构建...","rollup"),"END"===e.code&&this.logger.done("rollup 构建完成","rollup"),"ERROR"===e.code&&this.logger.error(`rollup 构建错误: ${e.error}`,"rollup"),e.result&&e.result.close()});const l=new y({host:s?.host??"0.0.0.0",port:s?.port??3e3,outDir:s?.outDir??e.resolve(this.context,"dist"),open:s?.open??!1,proxy:s?.proxy??{}},this.logger);await new Promise(e=>{let t=!1;n.on("event",async r=>{if("START"===r.code&&this.logger.log("rollup 开始重新构建...","rollup"),"END"===r.code){if(this.logger.done("rollup 构建完成","rollup"),this.htmlWriteConfig)try{j(this.htmlWriteConfig)}catch(e){this.logger.warn(`[bundlekit] 写入 HTML 失败: ${e.message}`)}t?l.reload():(t=!0,await l.start(),e())}"ERROR"===r.code&&(this.logger.error(`rollup 构建错误: ${r.error}`,"rollup"),t||e()),r.result&&r.result.close()})})}async prodBuild(e){const t=b(e),s=await r.rollup(t),o=Array.isArray(t.output)?t.output:[t.output];for(const e of o)await s.write(e);this.htmlWriteConfig&&j(this.htmlWriteConfig),this.logger.done("rollup 生产构建完成","rollup"),await s.close()}async createSSRMiddleware(t,s){const o=t.config?.[this.mode]||t.config?.development,i=o?.ssr;if(!i)throw new Error("ssr config not found in envConfig");const n=p.buildSSRView(t,this.mode),l=b(this.transformConfig(n)),a=e.resolve(this.context,i.output.dir),c=i.output.filename||"server.cjs",u=e.resolve(a,c);let d=!1,h=[];r.watch({...l,watch:{clearScreen:!1,exclude:"node_modules/**"}}).on("event",e=>{if("END"===e.code){d=!0;const e=h;h=[],e.forEach(e=>e())}"ERROR"===e.code&&this.logger.error(`rollup server compiler 错误: ${e.error}`,"rollup"),e.result&&e.result.close()});return[p.createSSRRequestHandler({context:this.context,ssrConfig:i,serverBundlePath:()=>u,waitUntilReady:()=>d?Promise.resolve():new Promise(e=>h.push(e)),onError:e=>this.logger.error(`SSR 渲染失败: ${e?.message??e}`,"rollup")})]}};
|
|
1
|
+
"use strict";var e=require("path"),t=require("fs"),r=require("rollup"),s=require("@rollup/plugin-node-resolve"),o=require("@rollup/plugin-commonjs"),i=require("@rollup/plugin-typescript"),n=require("@rollup/plugin-babel"),l=require("@rollup/plugin-image"),a=require("@rollup/plugin-json"),c=require("@rollup/plugin-replace"),u=require("rollup-plugin-postcss"),p=require("@bundlekit/shared-utils"),d=require("http"),h=require("https"),m=require("os"),f=require("child_process");const g={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".cjs":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml; charset=utf-8",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject",".map":"application/json",".txt":"text/plain; charset=utf-8",".xml":"application/xml",".webp":"image/webp"},v="<script data-bundlekit=\"livereload\">\n(function () {\n var sse = new EventSource('/__bundlekit_sse');\n sse.addEventListener('message', function (e) {\n if (e.data === 'reload') {\n console.log('[bundlekit] livereload triggered');\n location.reload();\n }\n });\n sse.onerror = function () {\n sse.close();\n setTimeout(function () { location.reload(); }, 2000);\n };\n})();\n<\/script>";class y{constructor(e,t){this.server=null,this.sseClients=new Set,this.options=e,this.logger=t}reload(){const e=[];for(const t of this.sseClients)try{t.write("data: reload\n\n")}catch{e.push(t)}e.forEach(e=>this.sseClients.delete(e))}start(){return new Promise((r,s)=>{this.server=d.createServer(async(r,s)=>{const o=r.url??"/";if(o.startsWith("/__bundlekit_sse"))return s.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"}),s.write(":ok\n\n"),this.sseClients.add(s),void r.on("close",()=>this.sseClients.delete(s));if(await this.handleProxy(r,s))return;const i=this.resolveFilePath(o);if(!i)return s.writeHead(404,{"Content-Type":"text/plain"}),void s.end(`Cannot GET ${o}`);const n=e.extname(i).toLowerCase(),l=g[n]??"application/octet-stream";try{if(".html"===n){let e=t.readFileSync(i,"utf-8");e=e.includes("</body>")?e.replace("</body>",`${v}\n</body>`):e+v,s.writeHead(200,{"Content-Type":l}),s.end(e)}else{const e=t.statSync(i).size;s.writeHead(200,{"Content-Type":l,"Content-Length":e}),t.createReadStream(i).pipe(s)}}catch(e){this.logger.error(`[bundlekit] 读取文件失败: ${e.message}`),s.writeHead(500),s.end("Internal Server Error")}}),this.server.on("error",s),this.server.listen(this.options.port,this.options.host,()=>{const e=this.server.address().port,t=this.getLocalIP();this.logger.clearConsole("Dev Server 启动成功"),this.logger.done("服务已启动:","🌐"),this.logger.log(` - 本地: http://localhost:${e}`),this.logger.log(` - 网络: http://${t}:${e}`),this.logger.log(""),this.options.open&&this.openBrowser(`http://localhost:${e}`),r()})})}close(){for(const e of this.sseClients)try{e.end()}catch{}this.sseClients.clear(),this.server?.close(),this.server=null}resolveFilePath(r){let s=r.split("?")[0];try{s=decodeURIComponent(s)}catch{}const o=this.options.outDir,i=[e.join(o,s),e.join(o,s,"index.html"),e.join(o,"index.html")];for(const e of i)try{if(t.statSync(e).isFile())return e}catch{}return null}async handleProxy(e,t){const r=this.options.proxy??{},s=e.url??"/";for(const[o,i]of Object.entries(r)){if(!s.startsWith(o))continue;const r="string"==typeof i?{target:i}:i;let n;try{n=new URL(r.target)}catch{return this.logger.error(`[bundlekit] 代理目标 URL 无效: ${r.target}`),t.writeHead(502),t.end("Bad Gateway: invalid proxy target"),!0}const l=r.rewrite?r.rewrite(s):s,a="https:"===n.protocol,c=a?h:d,u=a?443:80;return new Promise(s=>{const o=c.request({hostname:n.hostname,port:Number(n.port)||u,path:l,method:e.method,headers:{...e.headers,...!1!==r.changeOrigin?{host:n.host}:{}}},e=>{t.writeHead(e.statusCode??200,e.headers),e.pipe(t,{end:!0}),s(!0)});o.on("error",e=>{this.logger.error(`[bundlekit] 代理请求失败: ${e.message}`),t.headersSent||(t.writeHead(502),t.end(`Bad Gateway: ${e.message}`)),s(!0)}),e.pipe(o,{end:!0})})}return!1}getLocalIP(){for(const e of Object.values(m.networkInterfaces()))for(const t of e??[])if("IPv4"===t.family&&!t.internal)return t.address;return"localhost"}openBrowser(e){const t="darwin"===process.platform?`open "${e}"`:"win32"===process.platform?`start "" "${e}"`:`xdg-open "${e}"`;f.exec(t,e=>{e&&this.logger.warn(`[bundlekit] 打开浏览器失败: ${e.message}`)})}}const x={es:".mjs",esm:".mjs",cjs:".cjs",commonjs:".cjs",umd:".umd.js",iife:".iife.js"},w=e=>({commonjs:"cjs",esm:"es",es:"es",cjs:"cjs",umd:"umd",iife:"iife"}[e]??"es");function j(r){let s=[],o=[];try{const e=t.readdirSync(r.outDir);s=e.filter(e=>/\.(js|mjs|cjs)$/.test(e)&&!e.endsWith(".map")),o=e.filter(e=>e.endsWith(".css")&&!e.endsWith(".map"))}catch{}const i="es"===r.format;i&&r.entryFilename&&(s=s.filter(e=>e===r.entryFilename));const n=o.map(e=>` <link rel="stylesheet" href="${e}">`).join("\n"),l=s.map(e=>i?` <script type="module" src="${e}"><\/script>`:` <script src="${e}"><\/script>`).join("\n");let a;const c=r.template?e.resolve(r.context,r.template):null;if(c&&t.existsSync(c)){a=t.readFileSync(c,"utf-8"),n&&(a=a.includes("</head>")?a.replace("</head>",`${n}\n</head>`):n+"\n"+a);const e="head"===r.inject?"</head>":"</body>";a=a.includes(e)?a.replace(e,`${l}\n${e}`):a+l}else a=["<!DOCTYPE html>",'<html lang="en">',"<head>",' <meta charset="UTF-8">',' <meta name="viewport" content="width=device-width, initial-scale=1.0">'," <title>App</title>",...n?[n]:[],..."head"===r.inject?[l]:[],"</head>","<body>",' <div id="root"></div>',..."head"!==r.inject?[l]:[],"</body>","</html>"].join("\n");t.mkdirSync(r.outDir,{recursive:!0}),t.writeFileSync(e.join(r.outDir,r.filename),a,"utf-8")}const S=new Set(["cache","context","experimentalCacheExpiry","experimentalLogSideEffects","external","fs","input","jsx","logLevel","makeAbsoluteExternalsRelative","maxParallelFileOps","moduleContext","onLog","onwarn","output","perf","plugins","preserveEntrySignatures","preserveSymlinks","shimMissingExports","strictDeprecations","treeshake","watch"]);function b(e){return Object.fromEntries(Object.entries(e).filter(([e])=>S.has(e)))}module.exports=class{constructor(e,t){this.logger=new p.Logger,this.devServerConfig=null,this.htmlWriteConfig=null,this.name="@bundlekit/bundler-rollup",this.mode=t,this.context=e.context||process.cwd(),this.fse=new p.FileManager(this.context)}transformConfig(t){const r=[".js",".jsx",".ts",".tsx"],p=t.config?.[this.mode]||t.config?.development||{},d="node"===p.target,h=p.entry?"string"==typeof p.entry?p.entry:Object.values(p.entry)[0]:e.resolve(this.context,"src/index.ts"),m=(p.output&&!Array.isArray(p.output)?p.output.dir:void 0)||(Array.isArray(p.output)?p.output[0]?.dir:void 0)||"dist",f=e.resolve(this.context,m),g=p.css||{},v=!0===p.library,y=p.libraryName,j=p.output?.formats,S=Array.isArray(j)?j:[j||"es"],b=p.output?.filename||"index.js",C=/\[.+?\]/.test(b)?"index.js":b,$=b.replace(/\[.+?\]/g,"").replace(/\.[^.]+$/,"")||"index",E="production"===this.mode?"production":"development",D=[c({preventAssignment:!0,values:{"process.env.NODE_ENV":JSON.stringify(E),"import.meta.env.MODE":JSON.stringify(E),"import.meta.env.PROD":String("production"===E),"import.meta.env.DEV":String("production"!==E),"import.meta.env.SSR":"false","import.meta.env":JSON.stringify({MODE:E,DEV:"production"!==E,PROD:"production"===E,SSR:!1})}}),s({extensions:r,browser:!0,preferBuiltins:!1}),o(),a(),l(),u({extract:g.extract||!1,modules:g.modules||!1,sourceMap:g.sourcemap||!1,use:[...g.loaders?.includes("less")?["less"]:[],...g.loaders?.includes("sass")||g.loaders?.includes("scss")?["sass"]:[]]}),i({tsconfig:e.resolve(this.context,"tsconfig.json"),outDir:f,declaration:v,noEmit:!1,sourceMap:p.js?.sourcemap??!1}),n({babelHelpers:"bundled",extensions:r,exclude:["node_modules/**"],presets:[["@babel/preset-env",{modules:!1}],"@babel/preset-typescript"]})],R=d?this.resolveServerExternals(p):p.externals||[];let k;if(d){const t=p.ssr,r="esm"===t?.output?.formats?"es":"cjs";k={file:e.resolve(f,t?.output?.filename||"server.cjs"),format:r,sourcemap:p.js?.sourcemap||!1,exports:"named",inlineDynamicImports:!0}}else if(v&&S.length>1)k=S.map(t=>{const r=w(t),s=x[t]??".js";return{file:e.resolve(f,`${$}${s}`),format:r,sourcemap:p.js?.sourcemap||!1,name:["umd","iife"].includes(r)?y||e.basename(String(h),e.extname(String(h))):void 0,inlineDynamicImports:["umd","iife"].includes(r),exports:"named"}});else{const t=S[0]??"es",r=w(t);if(v)k={file:e.resolve(f,`${$}${x[t]??".js"}`),format:r,sourcemap:p.js?.sourcemap||!1,name:["umd","iife"].includes(r)?y||e.basename(String(h),e.extname(String(h))):void 0,inlineDynamicImports:["umd","iife"].includes(r)};else{const e=["es","cjs"].includes(r)?r:"es";e!==r&&this.logger.warn(`应用模式不支持 "${t}" 格式(不支持 code-splitting),已自动切换为 "es"`,"rollup"),k={dir:f,entryFileNames:C,format:e,sourcemap:p.js?.sourcemap||!1}}}if(this.devServerConfig={host:p.devServer?.host??"0.0.0.0",port:p.devServer?.port??3e3,open:p.devServer?.open??!1,proxy:p.devServer?.proxy??{},outDir:f,library:v},!v&&!d){const e=p.pages,t=e?.[0],r=Array.isArray(k)?k[0]?.format??"es":k?.format??"es";this.htmlWriteConfig={outDir:f,template:t?.template,filename:t?.filename||"index.html",inject:t?.inject||"body",context:this.context,entryFilename:C,format:r}}return{input:e.resolve(this.context,String(h)),output:k,plugins:D,external:R}}validateConfig(e,t){return!t||p.validateBuildConfig(t,this.mode).valid}resolveServerExternals(r){const s=r.ssr?.externals;if(Array.isArray(s))return s;const o=new Set;try{const r=e.join(this.context,"package.json");if(t.existsSync(r)){const e=JSON.parse(t.readFileSync(r,"utf-8"));Object.keys(e.dependencies||{}).forEach(e=>o.add(e)),Object.keys(e.peerDependencies||{}).forEach(e=>o.add(e))}}catch{}return t=>{if(t.startsWith("node:"))return!0;if(t.startsWith(".")||e.isAbsolute(t))return!1;if(o.has(t))return!0;for(const e of o)if(t===e||t.startsWith(e+"/"))return!0;return!1}}async run(e){try{this.logger.info("开始使用rollup进行打包");e.__isServerPass;switch(this.mode){case"development":if((!this.devServerConfig||!1!==this.devServerConfig.library||!Array.isArray(e.output))&&("cjs"===e.output?.format&&e.output?.file?.endsWith(".cjs"))){await this.prodBuild(e);break}await this.devBuild(e);break;case"production":case"test":case"staging":case"gray":await this.prodBuild(e)}}catch(e){throw this.logger.error(`打包失败, 错误信息: ${e}`),e}}async devBuild(t){const s=this.devServerConfig,o=s?.library??!1,i=b(t),n=r.watch({...i,watch:{clearScreen:!1,exclude:"node_modules/**"}});if(o)return this.logger.info("rollup library watch 模式已启动","rollup"),void n.on("event",e=>{"START"===e.code&&this.logger.log("rollup 开始重新构建...","rollup"),"END"===e.code&&this.logger.done("rollup 构建完成","rollup"),"ERROR"===e.code&&this.logger.error(`rollup 构建错误: ${e.error}`,"rollup"),e.result&&e.result.close()});const l=new y({host:s?.host??"0.0.0.0",port:s?.port??3e3,outDir:s?.outDir??e.resolve(this.context,"dist"),open:s?.open??!1,proxy:s?.proxy??{}},this.logger);await new Promise(e=>{let t=!1,r=!1;n.on("event",async s=>{if("START"===s.code&&(r=!1,this.logger.log("rollup 开始重新构建...","rollup")),"ERROR"===s.code&&(r=!0,this.logger.error(`rollup 构建错误: ${s.error}`,"rollup"),t||e()),"END"===s.code){if(this.logger.done("rollup 构建完成","rollup"),r)return void(s.result&&s.result.close());if(this.htmlWriteConfig)try{j(this.htmlWriteConfig)}catch(e){this.logger.warn(`[bundlekit] 写入 HTML 失败: ${e.message}`)}t?l.reload():(t=!0,await l.start(),e())}s.result&&s.result.close()})})}async prodBuild(e){const t=b(e),s=await r.rollup(t),o=Array.isArray(t.output)?t.output:[t.output];for(const e of o)await s.write(e);this.htmlWriteConfig&&j(this.htmlWriteConfig),this.logger.done("rollup 生产构建完成","rollup"),await s.close()}async createSSRMiddleware(t,s){const o=t.config?.[this.mode]||t.config?.development,i=o?.ssr;if(!i)throw new Error("ssr config not found in envConfig");const n=p.buildSSRView(t,this.mode),l=b(this.transformConfig(n)),a=e.resolve(this.context,i.output.dir),c=i.output.filename||"server.cjs",u=e.resolve(a,c);let d=!1,h=[];r.watch({...l,watch:{clearScreen:!1,exclude:"node_modules/**"}}).on("event",e=>{if("END"===e.code){d=!0;const e=h;h=[],e.forEach(e=>e())}"ERROR"===e.code&&this.logger.error(`rollup server compiler 错误: ${e.error}`,"rollup"),e.result&&e.result.close()});return[p.createSSRRequestHandler({context:this.context,ssrConfig:i,serverBundlePath:()=>u,waitUntilReady:()=>d?Promise.resolve():new Promise(e=>h.push(e)),onError:e=>this.logger.error(`SSR 渲染失败: ${e?.message??e}`,"rollup")})]}};
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"path";import{readFileSync as t,statSync as r,createReadStream as o,existsSync as s,readdirSync as i,mkdirSync as n,writeFileSync as l}from"fs";import{watch as a,rollup as c}from"rollup";import p from"@rollup/plugin-node-resolve";import u from"@rollup/plugin-commonjs";import d from"@rollup/plugin-typescript";import h from"@rollup/plugin-babel";import m from"@rollup/plugin-image";import f from"@rollup/plugin-json";import g from"@rollup/plugin-replace";import v from"rollup-plugin-postcss";import{Logger as y,FileManager as x,validateBuildConfig as j,buildSSRView as w,createSSRRequestHandler as b}from"@bundlekit/shared-utils";import S from"http";import C from"https";import E from"os";import{exec as $}from"child_process";const D={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".cjs":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml; charset=utf-8",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject",".map":"application/json",".txt":"text/plain; charset=utf-8",".xml":"application/xml",".webp":"image/webp"},k="<script data-bundlekit=\"livereload\">\n(function () {\n var sse = new EventSource('/__bundlekit_sse');\n sse.addEventListener('message', function (e) {\n if (e.data === 'reload') {\n console.log('[bundlekit] livereload triggered');\n location.reload();\n }\n });\n sse.onerror = function () {\n sse.close();\n setTimeout(function () { location.reload(); }, 2000);\n };\n})();\n<\/script>";class O{constructor(e,t){this.server=null,this.sseClients=new Set,this.options=e,this.logger=t}reload(){const e=[];for(const t of this.sseClients)try{t.write("data: reload\n\n")}catch{e.push(t)}e.forEach(e=>this.sseClients.delete(e))}start(){return new Promise((s,i)=>{this.server=S.createServer(async(s,i)=>{const n=s.url??"/";if(n.startsWith("/__bundlekit_sse"))return i.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"}),i.write(":ok\n\n"),this.sseClients.add(i),void s.on("close",()=>this.sseClients.delete(i));if(await this.handleProxy(s,i))return;const l=this.resolveFilePath(n);if(!l)return i.writeHead(404,{"Content-Type":"text/plain"}),void i.end(`Cannot GET ${n}`);const a=e.extname(l).toLowerCase(),c=D[a]??"application/octet-stream";try{if(".html"===a){let e=t(l,"utf-8");e=e.includes("</body>")?e.replace("</body>",`${k}\n</body>`):e+k,i.writeHead(200,{"Content-Type":c}),i.end(e)}else{const e=r(l).size;i.writeHead(200,{"Content-Type":c,"Content-Length":e}),o(l).pipe(i)}}catch(e){this.logger.error(`[bundlekit] 读取文件失败: ${e.message}`),i.writeHead(500),i.end("Internal Server Error")}}),this.server.on("error",i),this.server.listen(this.options.port,this.options.host,()=>{const e=this.server.address().port,t=this.getLocalIP();this.logger.clearConsole("Dev Server 启动成功"),this.logger.done("服务已启动:","🌐"),this.logger.log(` - 本地: http://localhost:${e}`),this.logger.log(` - 网络: http://${t}:${e}`),this.logger.log(""),this.options.open&&this.openBrowser(`http://localhost:${e}`),s()})})}close(){for(const e of this.sseClients)try{e.end()}catch{}this.sseClients.clear(),this.server?.close(),this.server=null}resolveFilePath(t){let o=t.split("?")[0];try{o=decodeURIComponent(o)}catch{}const s=this.options.outDir,i=[e.join(s,o),e.join(s,o,"index.html"),e.join(s,"index.html")];for(const e of i)try{if(r(e).isFile())return e}catch{}return null}async handleProxy(e,t){const r=this.options.proxy??{},o=e.url??"/";for(const[s,i]of Object.entries(r)){if(!o.startsWith(s))continue;const r="string"==typeof i?{target:i}:i;let n;try{n=new URL(r.target)}catch{return this.logger.error(`[bundlekit] 代理目标 URL 无效: ${r.target}`),t.writeHead(502),t.end("Bad Gateway: invalid proxy target"),!0}const l=r.rewrite?r.rewrite(o):o,a="https:"===n.protocol,c=a?C:S,p=a?443:80;return new Promise(o=>{const s=c.request({hostname:n.hostname,port:Number(n.port)||p,path:l,method:e.method,headers:{...e.headers,...!1!==r.changeOrigin?{host:n.host}:{}}},e=>{t.writeHead(e.statusCode??200,e.headers),e.pipe(t,{end:!0}),o(!0)});s.on("error",e=>{this.logger.error(`[bundlekit] 代理请求失败: ${e.message}`),t.headersSent||(t.writeHead(502),t.end(`Bad Gateway: ${e.message}`)),o(!0)}),e.pipe(s,{end:!0})})}return!1}getLocalIP(){for(const e of Object.values(E.networkInterfaces()))for(const t of e??[])if("IPv4"===t.family&&!t.internal)return t.address;return"localhost"}openBrowser(e){const t="darwin"===process.platform?`open "${e}"`:"win32"===process.platform?`start "" "${e}"`:`xdg-open "${e}"`;$(t,e=>{e&&this.logger.warn(`[bundlekit] 打开浏览器失败: ${e.message}`)})}}const R={es:".mjs",esm:".mjs",cjs:".cjs",commonjs:".cjs",umd:".umd.js",iife:".iife.js"},A=e=>({commonjs:"cjs",esm:"es",es:"es",cjs:"cjs",umd:"umd",iife:"iife"}[e]??"es");function P(r){let o=[],a=[];try{const e=i(r.outDir);o=e.filter(e=>/\.(js|mjs|cjs)$/.test(e)&&!e.endsWith(".map")),a=e.filter(e=>e.endsWith(".css")&&!e.endsWith(".map"))}catch{}const c=a.map(e=>` <link rel="stylesheet" href="${e}">`).join("\n"),p=o.map(e=>` <script src="${e}"><\/script>`).join("\n");let u;const d=r.template?e.resolve(r.context,r.template):null;if(d&&s(d)){u=t(d,"utf-8"),c&&(u=u.includes("</head>")?u.replace("</head>",`${c}\n</head>`):c+"\n"+u);const e="head"===r.inject?"</head>":"</body>";u=u.includes(e)?u.replace(e,`${p}\n${e}`):u+p}else u=["<!DOCTYPE html>",'<html lang="en">',"<head>",' <meta charset="UTF-8">',' <meta name="viewport" content="width=device-width, initial-scale=1.0">'," <title>App</title>",...c?[c]:[],..."head"===r.inject?[p]:[],"</head>","<body>",' <div id="root"></div>',..."head"!==r.inject?[p]:[],"</body>","</html>"].join("\n");n(r.outDir,{recursive:!0}),l(e.join(r.outDir,r.filename),u,"utf-8")}const W=new Set(["cache","context","experimentalCacheExpiry","experimentalLogSideEffects","external","fs","input","jsx","logLevel","makeAbsoluteExternalsRelative","maxParallelFileOps","moduleContext","onLog","onwarn","output","perf","plugins","preserveEntrySignatures","preserveSymlinks","shimMissingExports","strictDeprecations","treeshake","watch"]);function T(e){return Object.fromEntries(Object.entries(e).filter(([e])=>W.has(e)))}class _{constructor(e,t){this.logger=new y,this.devServerConfig=null,this.htmlWriteConfig=null,this.name="@bundlekit/bundler-rollup",this.mode=t,this.context=e.context||process.cwd(),this.fse=new x(this.context)}transformConfig(t){const r=[".js",".jsx",".ts",".tsx"],o=t.config?.[this.mode]||t.config?.development||{},s="node"===o.target,i=o.entry?"string"==typeof o.entry?o.entry:Object.values(o.entry)[0]:e.resolve(this.context,"src/index.ts"),n=(o.output&&!Array.isArray(o.output)?o.output.dir:void 0)||(Array.isArray(o.output)?o.output[0]?.dir:void 0)||"dist",l=e.resolve(this.context,n),a=o.css||{},c=!0===o.library,y=o.libraryName,x=o.output?.formats,j=Array.isArray(x)?x:[x||"es"],w=o.output?.filename||"index.js",b=/\[.+?\]/.test(w)?"index.js":w,S=w.replace(/\[.+?\]/g,"").replace(/\.[^.]+$/,"")||"index",C="production"===this.mode?"production":"development",E=[g({preventAssignment:!0,values:{"process.env.NODE_ENV":JSON.stringify(C),"import.meta.env.MODE":JSON.stringify(C),"import.meta.env.PROD":String("production"===C),"import.meta.env.DEV":String("production"!==C),"import.meta.env.SSR":"false","import.meta.env":JSON.stringify({MODE:C,DEV:"production"!==C,PROD:"production"===C,SSR:!1})}}),p({extensions:r,browser:!0,preferBuiltins:!1}),u(),f(),m(),v({extract:a.extract||!1,modules:a.modules||!1,sourceMap:a.sourcemap||!1,use:[...a.loaders?.includes("less")?["less"]:[],...a.loaders?.includes("sass")||a.loaders?.includes("scss")?["sass"]:[]]}),d({tsconfig:e.resolve(this.context,"tsconfig.json"),outDir:l,declaration:c,noEmit:!1,sourceMap:o.js?.sourcemap??!1}),h({babelHelpers:"bundled",extensions:r,exclude:["node_modules/**"],presets:[["@babel/preset-env",{modules:!1}],"@babel/preset-typescript"]})];if(!c&&!s){const e=o.pages,t=e?.[0];this.htmlWriteConfig={outDir:l,template:t?.template,filename:t?.filename||"index.html",inject:t?.inject||"body",context:this.context}}const $=s?this.resolveServerExternals(o):o.externals||[];let D;if(s){const t=o.ssr,r="esm"===t?.output?.formats?"es":"cjs";D={file:e.resolve(l,t?.output?.filename||"server.cjs"),format:r,sourcemap:o.js?.sourcemap||!1,exports:"named",inlineDynamicImports:!0}}else if(c&&j.length>1)D=j.map(t=>{const r=A(t),s=R[t]??".js";return{file:e.resolve(l,`${S}${s}`),format:r,sourcemap:o.js?.sourcemap||!1,name:["umd","iife"].includes(r)?y||e.basename(String(i),e.extname(String(i))):void 0,inlineDynamicImports:["umd","iife"].includes(r),exports:"named"}});else{const t=j[0]??"es",r=A(t);D=c?{file:e.resolve(l,`${S}${R[t]??".js"}`),format:r,sourcemap:o.js?.sourcemap||!1,name:["umd","iife"].includes(r)?y||e.basename(String(i),e.extname(String(i))):void 0,inlineDynamicImports:["umd","iife"].includes(r)}:{dir:l,entryFileNames:b,format:r,sourcemap:o.js?.sourcemap||!1}}return this.devServerConfig={host:o.devServer?.host??"0.0.0.0",port:o.devServer?.port??3e3,open:o.devServer?.open??!1,proxy:o.devServer?.proxy??{},outDir:l,library:c},{input:e.resolve(this.context,String(i)),output:D,plugins:E,external:$}}validateConfig(e,t){return!t||j(t,this.mode).valid}resolveServerExternals(r){const o=r.ssr?.externals;if(Array.isArray(o))return o;const i=new Set;try{const r=e.join(this.context,"package.json");if(s(r)){const e=JSON.parse(t(r,"utf-8"));Object.keys(e.dependencies||{}).forEach(e=>i.add(e)),Object.keys(e.peerDependencies||{}).forEach(e=>i.add(e))}}catch{}return t=>{if(t.startsWith("node:"))return!0;if(t.startsWith(".")||e.isAbsolute(t))return!1;if(i.has(t))return!0;for(const e of i)if(t===e||t.startsWith(e+"/"))return!0;return!1}}async run(e){try{this.logger.info("开始使用rollup进行打包");e.__isServerPass;switch(this.mode){case"development":if((!this.devServerConfig||!1!==this.devServerConfig.library||!Array.isArray(e.output))&&("cjs"===e.output?.format&&e.output?.file?.endsWith(".cjs"))){await this.prodBuild(e);break}await this.devBuild(e);break;case"production":case"test":case"staging":case"gray":await this.prodBuild(e)}}catch(e){throw this.logger.error(`打包失败, 错误信息: ${e}`),e}}async devBuild(t){const r=this.devServerConfig,o=r?.library??!1,s=T(t),i=a({...s,watch:{clearScreen:!1,exclude:"node_modules/**"}});if(o)return this.logger.info("rollup library watch 模式已启动","rollup"),void i.on("event",e=>{"START"===e.code&&this.logger.log("rollup 开始重新构建...","rollup"),"END"===e.code&&this.logger.done("rollup 构建完成","rollup"),"ERROR"===e.code&&this.logger.error(`rollup 构建错误: ${e.error}`,"rollup"),e.result&&e.result.close()});const n=new O({host:r?.host??"0.0.0.0",port:r?.port??3e3,outDir:r?.outDir??e.resolve(this.context,"dist"),open:r?.open??!1,proxy:r?.proxy??{}},this.logger);await new Promise(e=>{let t=!1;i.on("event",async r=>{if("START"===r.code&&this.logger.log("rollup 开始重新构建...","rollup"),"END"===r.code){if(this.logger.done("rollup 构建完成","rollup"),this.htmlWriteConfig)try{P(this.htmlWriteConfig)}catch(e){this.logger.warn(`[bundlekit] 写入 HTML 失败: ${e.message}`)}t?n.reload():(t=!0,await n.start(),e())}"ERROR"===r.code&&(this.logger.error(`rollup 构建错误: ${r.error}`,"rollup"),t||e()),r.result&&r.result.close()})})}async prodBuild(e){const t=T(e),r=await c(t),o=Array.isArray(t.output)?t.output:[t.output];for(const e of o)await r.write(e);this.htmlWriteConfig&&P(this.htmlWriteConfig),this.logger.done("rollup 生产构建完成","rollup"),await r.close()}async createSSRMiddleware(t,r){const o=t.config?.[this.mode]||t.config?.development,s=o?.ssr;if(!s)throw new Error("ssr config not found in envConfig");const i=w(t,this.mode),n=T(this.transformConfig(i)),l=e.resolve(this.context,s.output.dir),c=s.output.filename||"server.cjs",p=e.resolve(l,c);let u=!1,d=[];a({...n,watch:{clearScreen:!1,exclude:"node_modules/**"}}).on("event",e=>{if("END"===e.code){u=!0;const e=d;d=[],e.forEach(e=>e())}"ERROR"===e.code&&this.logger.error(`rollup server compiler 错误: ${e.error}`,"rollup"),e.result&&e.result.close()});return[b({context:this.context,ssrConfig:s,serverBundlePath:()=>p,waitUntilReady:()=>u?Promise.resolve():new Promise(e=>d.push(e)),onError:e=>this.logger.error(`SSR 渲染失败: ${e?.message??e}`,"rollup")})]}}export{_ as default};
|
|
1
|
+
import e from"path";import{readFileSync as t,statSync as r,createReadStream as o,existsSync as s,readdirSync as i,mkdirSync as n,writeFileSync as l}from"fs";import{watch as a,rollup as c}from"rollup";import p from"@rollup/plugin-node-resolve";import u from"@rollup/plugin-commonjs";import d from"@rollup/plugin-typescript";import m from"@rollup/plugin-babel";import h from"@rollup/plugin-image";import f from"@rollup/plugin-json";import g from"@rollup/plugin-replace";import v from"rollup-plugin-postcss";import{Logger as y,FileManager as j,validateBuildConfig as x,buildSSRView as w,createSSRRequestHandler as b}from"@bundlekit/shared-utils";import S from"http";import C from"https";import $ from"os";import{exec as E}from"child_process";const D={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".cjs":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml; charset=utf-8",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject",".map":"application/json",".txt":"text/plain; charset=utf-8",".xml":"application/xml",".webp":"image/webp"},k="<script data-bundlekit=\"livereload\">\n(function () {\n var sse = new EventSource('/__bundlekit_sse');\n sse.addEventListener('message', function (e) {\n if (e.data === 'reload') {\n console.log('[bundlekit] livereload triggered');\n location.reload();\n }\n });\n sse.onerror = function () {\n sse.close();\n setTimeout(function () { location.reload(); }, 2000);\n };\n})();\n<\/script>";class O{constructor(e,t){this.server=null,this.sseClients=new Set,this.options=e,this.logger=t}reload(){const e=[];for(const t of this.sseClients)try{t.write("data: reload\n\n")}catch{e.push(t)}e.forEach(e=>this.sseClients.delete(e))}start(){return new Promise((s,i)=>{this.server=S.createServer(async(s,i)=>{const n=s.url??"/";if(n.startsWith("/__bundlekit_sse"))return i.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"}),i.write(":ok\n\n"),this.sseClients.add(i),void s.on("close",()=>this.sseClients.delete(i));if(await this.handleProxy(s,i))return;const l=this.resolveFilePath(n);if(!l)return i.writeHead(404,{"Content-Type":"text/plain"}),void i.end(`Cannot GET ${n}`);const a=e.extname(l).toLowerCase(),c=D[a]??"application/octet-stream";try{if(".html"===a){let e=t(l,"utf-8");e=e.includes("</body>")?e.replace("</body>",`${k}\n</body>`):e+k,i.writeHead(200,{"Content-Type":c}),i.end(e)}else{const e=r(l).size;i.writeHead(200,{"Content-Type":c,"Content-Length":e}),o(l).pipe(i)}}catch(e){this.logger.error(`[bundlekit] 读取文件失败: ${e.message}`),i.writeHead(500),i.end("Internal Server Error")}}),this.server.on("error",i),this.server.listen(this.options.port,this.options.host,()=>{const e=this.server.address().port,t=this.getLocalIP();this.logger.clearConsole("Dev Server 启动成功"),this.logger.done("服务已启动:","🌐"),this.logger.log(` - 本地: http://localhost:${e}`),this.logger.log(` - 网络: http://${t}:${e}`),this.logger.log(""),this.options.open&&this.openBrowser(`http://localhost:${e}`),s()})})}close(){for(const e of this.sseClients)try{e.end()}catch{}this.sseClients.clear(),this.server?.close(),this.server=null}resolveFilePath(t){let o=t.split("?")[0];try{o=decodeURIComponent(o)}catch{}const s=this.options.outDir,i=[e.join(s,o),e.join(s,o,"index.html"),e.join(s,"index.html")];for(const e of i)try{if(r(e).isFile())return e}catch{}return null}async handleProxy(e,t){const r=this.options.proxy??{},o=e.url??"/";for(const[s,i]of Object.entries(r)){if(!o.startsWith(s))continue;const r="string"==typeof i?{target:i}:i;let n;try{n=new URL(r.target)}catch{return this.logger.error(`[bundlekit] 代理目标 URL 无效: ${r.target}`),t.writeHead(502),t.end("Bad Gateway: invalid proxy target"),!0}const l=r.rewrite?r.rewrite(o):o,a="https:"===n.protocol,c=a?C:S,p=a?443:80;return new Promise(o=>{const s=c.request({hostname:n.hostname,port:Number(n.port)||p,path:l,method:e.method,headers:{...e.headers,...!1!==r.changeOrigin?{host:n.host}:{}}},e=>{t.writeHead(e.statusCode??200,e.headers),e.pipe(t,{end:!0}),o(!0)});s.on("error",e=>{this.logger.error(`[bundlekit] 代理请求失败: ${e.message}`),t.headersSent||(t.writeHead(502),t.end(`Bad Gateway: ${e.message}`)),o(!0)}),e.pipe(s,{end:!0})})}return!1}getLocalIP(){for(const e of Object.values($.networkInterfaces()))for(const t of e??[])if("IPv4"===t.family&&!t.internal)return t.address;return"localhost"}openBrowser(e){const t="darwin"===process.platform?`open "${e}"`:"win32"===process.platform?`start "" "${e}"`:`xdg-open "${e}"`;E(t,e=>{e&&this.logger.warn(`[bundlekit] 打开浏览器失败: ${e.message}`)})}}const A={es:".mjs",esm:".mjs",cjs:".cjs",commonjs:".cjs",umd:".umd.js",iife:".iife.js"},R=e=>({commonjs:"cjs",esm:"es",es:"es",cjs:"cjs",umd:"umd",iife:"iife"}[e]??"es");function P(r){let o=[],a=[];try{const e=i(r.outDir);o=e.filter(e=>/\.(js|mjs|cjs)$/.test(e)&&!e.endsWith(".map")),a=e.filter(e=>e.endsWith(".css")&&!e.endsWith(".map"))}catch{}const c="es"===r.format;c&&r.entryFilename&&(o=o.filter(e=>e===r.entryFilename));const p=a.map(e=>` <link rel="stylesheet" href="${e}">`).join("\n"),u=o.map(e=>c?` <script type="module" src="${e}"><\/script>`:` <script src="${e}"><\/script>`).join("\n");let d;const m=r.template?e.resolve(r.context,r.template):null;if(m&&s(m)){d=t(m,"utf-8"),p&&(d=d.includes("</head>")?d.replace("</head>",`${p}\n</head>`):p+"\n"+d);const e="head"===r.inject?"</head>":"</body>";d=d.includes(e)?d.replace(e,`${u}\n${e}`):d+u}else d=["<!DOCTYPE html>",'<html lang="en">',"<head>",' <meta charset="UTF-8">',' <meta name="viewport" content="width=device-width, initial-scale=1.0">'," <title>App</title>",...p?[p]:[],..."head"===r.inject?[u]:[],"</head>","<body>",' <div id="root"></div>',..."head"!==r.inject?[u]:[],"</body>","</html>"].join("\n");n(r.outDir,{recursive:!0}),l(e.join(r.outDir,r.filename),d,"utf-8")}const W=new Set(["cache","context","experimentalCacheExpiry","experimentalLogSideEffects","external","fs","input","jsx","logLevel","makeAbsoluteExternalsRelative","maxParallelFileOps","moduleContext","onLog","onwarn","output","perf","plugins","preserveEntrySignatures","preserveSymlinks","shimMissingExports","strictDeprecations","treeshake","watch"]);function T(e){return Object.fromEntries(Object.entries(e).filter(([e])=>W.has(e)))}class _{constructor(e,t){this.logger=new y,this.devServerConfig=null,this.htmlWriteConfig=null,this.name="@bundlekit/bundler-rollup",this.mode=t,this.context=e.context||process.cwd(),this.fse=new j(this.context)}transformConfig(t){const r=[".js",".jsx",".ts",".tsx"],o=t.config?.[this.mode]||t.config?.development||{},s="node"===o.target,i=o.entry?"string"==typeof o.entry?o.entry:Object.values(o.entry)[0]:e.resolve(this.context,"src/index.ts"),n=(o.output&&!Array.isArray(o.output)?o.output.dir:void 0)||(Array.isArray(o.output)?o.output[0]?.dir:void 0)||"dist",l=e.resolve(this.context,n),a=o.css||{},c=!0===o.library,y=o.libraryName,j=o.output?.formats,x=Array.isArray(j)?j:[j||"es"],w=o.output?.filename||"index.js",b=/\[.+?\]/.test(w)?"index.js":w,S=w.replace(/\[.+?\]/g,"").replace(/\.[^.]+$/,"")||"index",C="production"===this.mode?"production":"development",$=[g({preventAssignment:!0,values:{"process.env.NODE_ENV":JSON.stringify(C),"import.meta.env.MODE":JSON.stringify(C),"import.meta.env.PROD":String("production"===C),"import.meta.env.DEV":String("production"!==C),"import.meta.env.SSR":"false","import.meta.env":JSON.stringify({MODE:C,DEV:"production"!==C,PROD:"production"===C,SSR:!1})}}),p({extensions:r,browser:!0,preferBuiltins:!1}),u(),f(),h(),v({extract:a.extract||!1,modules:a.modules||!1,sourceMap:a.sourcemap||!1,use:[...a.loaders?.includes("less")?["less"]:[],...a.loaders?.includes("sass")||a.loaders?.includes("scss")?["sass"]:[]]}),d({tsconfig:e.resolve(this.context,"tsconfig.json"),outDir:l,declaration:c,noEmit:!1,sourceMap:o.js?.sourcemap??!1}),m({babelHelpers:"bundled",extensions:r,exclude:["node_modules/**"],presets:[["@babel/preset-env",{modules:!1}],"@babel/preset-typescript"]})],E=s?this.resolveServerExternals(o):o.externals||[];let D;if(s){const t=o.ssr,r="esm"===t?.output?.formats?"es":"cjs";D={file:e.resolve(l,t?.output?.filename||"server.cjs"),format:r,sourcemap:o.js?.sourcemap||!1,exports:"named",inlineDynamicImports:!0}}else if(c&&x.length>1)D=x.map(t=>{const r=R(t),s=A[t]??".js";return{file:e.resolve(l,`${S}${s}`),format:r,sourcemap:o.js?.sourcemap||!1,name:["umd","iife"].includes(r)?y||e.basename(String(i),e.extname(String(i))):void 0,inlineDynamicImports:["umd","iife"].includes(r),exports:"named"}});else{const t=x[0]??"es",r=R(t);if(c)D={file:e.resolve(l,`${S}${A[t]??".js"}`),format:r,sourcemap:o.js?.sourcemap||!1,name:["umd","iife"].includes(r)?y||e.basename(String(i),e.extname(String(i))):void 0,inlineDynamicImports:["umd","iife"].includes(r)};else{const e=["es","cjs"].includes(r)?r:"es";e!==r&&this.logger.warn(`应用模式不支持 "${t}" 格式(不支持 code-splitting),已自动切换为 "es"`,"rollup"),D={dir:l,entryFileNames:b,format:e,sourcemap:o.js?.sourcemap||!1}}}if(this.devServerConfig={host:o.devServer?.host??"0.0.0.0",port:o.devServer?.port??3e3,open:o.devServer?.open??!1,proxy:o.devServer?.proxy??{},outDir:l,library:c},!c&&!s){const e=o.pages,t=e?.[0],r=Array.isArray(D)?D[0]?.format??"es":D?.format??"es";this.htmlWriteConfig={outDir:l,template:t?.template,filename:t?.filename||"index.html",inject:t?.inject||"body",context:this.context,entryFilename:b,format:r}}return{input:e.resolve(this.context,String(i)),output:D,plugins:$,external:E}}validateConfig(e,t){return!t||x(t,this.mode).valid}resolveServerExternals(r){const o=r.ssr?.externals;if(Array.isArray(o))return o;const i=new Set;try{const r=e.join(this.context,"package.json");if(s(r)){const e=JSON.parse(t(r,"utf-8"));Object.keys(e.dependencies||{}).forEach(e=>i.add(e)),Object.keys(e.peerDependencies||{}).forEach(e=>i.add(e))}}catch{}return t=>{if(t.startsWith("node:"))return!0;if(t.startsWith(".")||e.isAbsolute(t))return!1;if(i.has(t))return!0;for(const e of i)if(t===e||t.startsWith(e+"/"))return!0;return!1}}async run(e){try{this.logger.info("开始使用rollup进行打包");e.__isServerPass;switch(this.mode){case"development":if((!this.devServerConfig||!1!==this.devServerConfig.library||!Array.isArray(e.output))&&("cjs"===e.output?.format&&e.output?.file?.endsWith(".cjs"))){await this.prodBuild(e);break}await this.devBuild(e);break;case"production":case"test":case"staging":case"gray":await this.prodBuild(e)}}catch(e){throw this.logger.error(`打包失败, 错误信息: ${e}`),e}}async devBuild(t){const r=this.devServerConfig,o=r?.library??!1,s=T(t),i=a({...s,watch:{clearScreen:!1,exclude:"node_modules/**"}});if(o)return this.logger.info("rollup library watch 模式已启动","rollup"),void i.on("event",e=>{"START"===e.code&&this.logger.log("rollup 开始重新构建...","rollup"),"END"===e.code&&this.logger.done("rollup 构建完成","rollup"),"ERROR"===e.code&&this.logger.error(`rollup 构建错误: ${e.error}`,"rollup"),e.result&&e.result.close()});const n=new O({host:r?.host??"0.0.0.0",port:r?.port??3e3,outDir:r?.outDir??e.resolve(this.context,"dist"),open:r?.open??!1,proxy:r?.proxy??{}},this.logger);await new Promise(e=>{let t=!1,r=!1;i.on("event",async o=>{if("START"===o.code&&(r=!1,this.logger.log("rollup 开始重新构建...","rollup")),"ERROR"===o.code&&(r=!0,this.logger.error(`rollup 构建错误: ${o.error}`,"rollup"),t||e()),"END"===o.code){if(this.logger.done("rollup 构建完成","rollup"),r)return void(o.result&&o.result.close());if(this.htmlWriteConfig)try{P(this.htmlWriteConfig)}catch(e){this.logger.warn(`[bundlekit] 写入 HTML 失败: ${e.message}`)}t?n.reload():(t=!0,await n.start(),e())}o.result&&o.result.close()})})}async prodBuild(e){const t=T(e),r=await c(t),o=Array.isArray(t.output)?t.output:[t.output];for(const e of o)await r.write(e);this.htmlWriteConfig&&P(this.htmlWriteConfig),this.logger.done("rollup 生产构建完成","rollup"),await r.close()}async createSSRMiddleware(t,r){const o=t.config?.[this.mode]||t.config?.development,s=o?.ssr;if(!s)throw new Error("ssr config not found in envConfig");const i=w(t,this.mode),n=T(this.transformConfig(i)),l=e.resolve(this.context,s.output.dir),c=s.output.filename||"server.cjs",p=e.resolve(l,c);let u=!1,d=[];a({...n,watch:{clearScreen:!1,exclude:"node_modules/**"}}).on("event",e=>{if("END"===e.code){u=!0;const e=d;d=[],e.forEach(e=>e())}"ERROR"===e.code&&this.logger.error(`rollup server compiler 错误: ${e.error}`,"rollup"),e.result&&e.result.close()});return[b({context:this.context,ssrConfig:s,serverBundlePath:()=>p,waitUntilReady:()=>u?Promise.resolve():new Promise(e=>d.push(e)),onError:e=>this.logger.error(`SSR 渲染失败: ${e?.message??e}`,"rollup")})]}}export{_ as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bundlekit/bundler-rollup",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "A rollup bundler for @bundlekit/service",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"rollup": "^4.40.0",
|
|
31
31
|
"rollup-plugin-postcss": "^4.0.2",
|
|
32
32
|
"schema-utils": "^4.3.0",
|
|
33
|
-
"@bundlekit/shared-utils": "0.0.
|
|
33
|
+
"@bundlekit/shared-utils": "0.0.4"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@rollup/plugin-terser": "^0.4.4",
|