@bundlekit/bundler-rollup 0.0.2 → 0.0.3
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 +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +1 -1
- package/package.json +9 -3
package/README.md
CHANGED
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"),n=require("@rollup/plugin-typescript"),i=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 n=this.resolveFilePath(o);if(!n)return s.writeHead(404,{"Content-Type":"text/plain"}),void s.end(`Cannot GET ${o}`);const i=e.extname(n).toLowerCase(),l=f[i]??"application/octet-stream";try{if(".html"===i){let e=t.readFileSync(n,"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(n).size;s.writeHead(200,{"Content-Type":l,"Content-Length":e}),t.createReadStream(n).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,n=[e.join(o,s),e.join(o,s,"index.html"),e.join(o,"index.html")];for(const e of n)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,n]of Object.entries(r)){if(!s.startsWith(o))continue;const r="string"==typeof n?{target:n}:n;let i;try{i=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:"===i.protocol,c=a?h:d,u=a?443:80;return new Promise(s=>{const o=c.request({hostname:i.hostname,port:Number(i.port)||u,path:l,method:e.method,headers:{...e.headers,...!1!==r.changeOrigin?{host:i.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");const j=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 S(e){return Object.fromEntries(Object.entries(e).filter(([e])=>j.has(e)))}module.exports=class{constructor(e,t){this.logger=new p.Logger,this.devServerConfig=null,this.name="@bundlekit/bundler-rollup",this.mode=t,this.context=e.context||process.cwd(),this.fse=new p.FileManager(this.context)}transformConfig(r){const p=[".js",".jsx",".ts",".tsx"],d=r.config?.[this.mode]||r.config?.development||{},h="node"===d.target,m=d.entry?"string"==typeof d.entry?d.entry:Object.values(d.entry)[0]:e.resolve(this.context,"src/index.ts"),g=(d.output&&!Array.isArray(d.output)?d.output.dir:void 0)||(Array.isArray(d.output)?d.output[0]?.dir:void 0)||"dist",f=e.resolve(this.context,g),v=d.css||{},y=!0===d.library,j=d.libraryName,S=d.output?.formats,b=Array.isArray(S)?S:[S||"es"],C=d.output?.filename||"index.js",E=/\[.+?\]/.test(C)?"index.js":C,$=C.replace(/\[.+?\]/g,"").replace(/\.[^.]+$/,"")||"index",k="production"===this.mode?"production":"development",R=[c({preventAssignment:!0,values:{"process.env.NODE_ENV":JSON.stringify(k),"import.meta.env.MODE":JSON.stringify(k),"import.meta.env.PROD":String("production"===k),"import.meta.env.DEV":String("production"!==k),"import.meta.env.SSR":"false","import.meta.env":JSON.stringify({MODE:k,DEV:"production"!==k,PROD:"production"===k,SSR:!1})}}),s({extensions:p,browser:!0,preferBuiltins:!1}),o(),a(),l(),u({extract:v.extract||!1,modules:v.modules||!1,sourceMap:v.sourcemap||!1,use:[...v.loaders?.includes("less")?["less"]:[],...v.loaders?.includes("sass")||v.loaders?.includes("scss")?["sass"]:[]]}),n({tsconfig:e.resolve(this.context,"tsconfig.json"),outDir:f,declaration:y,noEmit:!1,sourceMap:d.js?.sourcemap??!1}),i({babelHelpers:"bundled",extensions:p,exclude:["node_modules/**"],presets:[["@babel/preset-env",{modules:!1}],"@babel/preset-typescript"]})];if(!y&&!h){const r=d.pages,s=r?.[0];R.push((O={context:this.context,template:s?.template,filename:s?.filename||"index.html",inject:s?.inject||"body"},{name:"bundlekit-html",generateBundle(r,s){const o=Object.keys(s).filter(e=>"chunk"===s[e].type).map(t=>e.basename(t)),n=Object.keys(s).filter(e=>"asset"===s[e].type&&e.endsWith(".css")).map(t=>e.basename(t)).map(e=>` <link rel="stylesheet" href="${e}">`).join("\n"),i=o.map(e=>` <script src="${e}"><\/script>`).join("\n");let l;const a=O.template?e.resolve(O.context,O.template):null;if(a&&t.existsSync(a)){l=t.readFileSync(a,"utf-8"),n&&(l=l.includes("</head>")?l.replace("</head>",`${n}\n</head>`):n+"\n"+l);const e="head"===O.inject?"</head>":"</body>";l=l.includes(e)?l.replace(e,`${i}\n${e}`):l+i}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>",...n?[n]:[],..."head"===O.inject?[i]:[],"</head>","<body>",' <div id="root"></div>',..."head"!==O.inject?[i]:[],"</body>","</html>"].join("\n");this.emitFile({type:"asset",fileName:O.filename,source:l})}}))}var O;const D=h?this.resolveServerExternals(d):d.externals||[];let A;if(h){const t=d.ssr,r="esm"===t?.output?.formats?"es":"cjs";A={file:e.resolve(f,t?.output?.filename||"server.cjs"),format:r,sourcemap:d.js?.sourcemap||!1,exports:"named",inlineDynamicImports:!0}}else if(y&&b.length>1)A=b.map(t=>{const r=w(t),s=x[t]??".js";return{file:e.resolve(f,`${$}${s}`),format:r,sourcemap:d.js?.sourcemap||!1,name:["umd","iife"].includes(r)?j||e.basename(String(m),e.extname(String(m))):void 0,inlineDynamicImports:["umd","iife"].includes(r),exports:"named"}});else{const t=b[0]??"es",r=w(t);A={file:e.resolve(f,y?`${$}${x[t]??".js"}`:E),format:r,sourcemap:d.js?.sourcemap||!1,name:["umd","iife"].includes(r)?j||e.basename(String(m),e.extname(String(m))):void 0,inlineDynamicImports:["umd","iife"].includes(r)}}return this.devServerConfig={host:d.devServer?.host??"0.0.0.0",port:d.devServer?.port??3e3,open:d.devServer?.open??!1,proxy:d.devServer?.proxy??{},outDir:f,library:y},{input:e.resolve(this.context,String(m)),output:A,plugins:R,external:D}}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,n=S(t),i=r.watch({...n,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 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;i.on("event",async r=>{"START"===r.code&&this.logger.log("rollup 开始重新构建...","rollup"),"END"===r.code&&(this.logger.done("rollup 构建完成","rollup"),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=S(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.logger.done("rollup 生产构建完成","rollup"),await s.close()}async createSSRMiddleware(t,s){const o=t.config?.[this.mode]||t.config?.development,n=o?.ssr;if(!n)throw new Error("ssr config not found in envConfig");const i=p.buildSSRView(t,this.mode),l=S(this.transformConfig(i)),a=e.resolve(this.context,n.output.dir),c=n.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:n,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"),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")})]}};
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export default class rollupBundler implements IBuildToolAdapter<RollupOptions> {
|
|
|
7
7
|
private fse;
|
|
8
8
|
/** transformConfig 阶段存储,run 阶段使用 */
|
|
9
9
|
private devServerConfig;
|
|
10
|
+
private htmlWriteConfig;
|
|
10
11
|
name: string;
|
|
11
12
|
constructor(api: IService, mode: IBuildEnv);
|
|
12
13
|
transformConfig(config: IBuildConfig): RollupOptions;
|
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}from"fs";import{watch as n,rollup as i}from"rollup";import l from"@rollup/plugin-node-resolve";import a from"@rollup/plugin-commonjs";import c from"@rollup/plugin-typescript";import p from"@rollup/plugin-babel";import u from"@rollup/plugin-image";import d from"@rollup/plugin-json";import m from"@rollup/plugin-replace";import h from"rollup-plugin-postcss";import{Logger as f,FileManager as g,validateBuildConfig as v,buildSSRView as y,createSSRRequestHandler as x}from"@bundlekit/shared-utils";import j from"http";import w from"https";import b from"os";import{exec as S}from"child_process";const C={".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"},E="<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 ${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,n)=>{this.server=j.createServer(async(s,n)=>{const i=s.url??"/";if(i.startsWith("/__bundlekit_sse"))return n.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"}),n.write(":ok\n\n"),this.sseClients.add(n),void s.on("close",()=>this.sseClients.delete(n));if(await this.handleProxy(s,n))return;const l=this.resolveFilePath(i);if(!l)return n.writeHead(404,{"Content-Type":"text/plain"}),void n.end(`Cannot GET ${i}`);const a=e.extname(l).toLowerCase(),c=C[a]??"application/octet-stream";try{if(".html"===a){let e=t(l,"utf-8");e=e.includes("</body>")?e.replace("</body>",`${E}\n</body>`):e+E,n.writeHead(200,{"Content-Type":c}),n.end(e)}else{const e=r(l).size;n.writeHead(200,{"Content-Type":c,"Content-Length":e}),o(l).pipe(n)}}catch(e){this.logger.error(`[bundlekit] 读取文件失败: ${e.message}`),n.writeHead(500),n.end("Internal Server Error")}}),this.server.on("error",n),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,n=[e.join(s,o),e.join(s,o,"index.html"),e.join(s,"index.html")];for(const e of n)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,n]of Object.entries(r)){if(!o.startsWith(s))continue;const r="string"==typeof n?{target:n}:n;let i;try{i=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:"===i.protocol,c=a?w:j,p=a?443:80;return new Promise(o=>{const s=c.request({hostname:i.hostname,port:Number(i.port)||p,path:l,method:e.method,headers:{...e.headers,...!1!==r.changeOrigin?{host:i.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(b.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}"`;S(t,e=>{e&&this.logger.warn(`[bundlekit] 打开浏览器失败: ${e.message}`)})}}const k={es:".mjs",esm:".mjs",cjs:".cjs",commonjs:".cjs",umd:".umd.js",iife:".iife.js"},O=e=>({commonjs:"cjs",esm:"es",es:"es",cjs:"cjs",umd:"umd",iife:"iife"}[e]??"es");const D=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 R(e){return Object.fromEntries(Object.entries(e).filter(([e])=>D.has(e)))}class A{constructor(e,t){this.logger=new f,this.devServerConfig=null,this.name="@bundlekit/bundler-rollup",this.mode=t,this.context=e.context||process.cwd(),this.fse=new g(this.context)}transformConfig(r){const o=[".js",".jsx",".ts",".tsx"],n=r.config?.[this.mode]||r.config?.development||{},i="node"===n.target,f=n.entry?"string"==typeof n.entry?n.entry:Object.values(n.entry)[0]:e.resolve(this.context,"src/index.ts"),g=(n.output&&!Array.isArray(n.output)?n.output.dir:void 0)||(Array.isArray(n.output)?n.output[0]?.dir:void 0)||"dist",v=e.resolve(this.context,g),y=n.css||{},x=!0===n.library,j=n.libraryName,w=n.output?.formats,b=Array.isArray(w)?w:[w||"es"],S=n.output?.filename||"index.js",C=/\[.+?\]/.test(S)?"index.js":S,E=S.replace(/\[.+?\]/g,"").replace(/\.[^.]+$/,"")||"index",$="production"===this.mode?"production":"development",D=[m({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})}}),l({extensions:o,browser:!0,preferBuiltins:!1}),a(),d(),u(),h({extract:y.extract||!1,modules:y.modules||!1,sourceMap:y.sourcemap||!1,use:[...y.loaders?.includes("less")?["less"]:[],...y.loaders?.includes("sass")||y.loaders?.includes("scss")?["sass"]:[]]}),c({tsconfig:e.resolve(this.context,"tsconfig.json"),outDir:v,declaration:x,noEmit:!1,sourceMap:n.js?.sourcemap??!1}),p({babelHelpers:"bundled",extensions:o,exclude:["node_modules/**"],presets:[["@babel/preset-env",{modules:!1}],"@babel/preset-typescript"]})];if(!x&&!i){const r=n.pages,o=r?.[0];D.push((R={context:this.context,template:o?.template,filename:o?.filename||"index.html",inject:o?.inject||"body"},{name:"bundlekit-html",generateBundle(r,o){const n=Object.keys(o).filter(e=>"chunk"===o[e].type).map(t=>e.basename(t)),i=Object.keys(o).filter(e=>"asset"===o[e].type&&e.endsWith(".css")).map(t=>e.basename(t)).map(e=>` <link rel="stylesheet" href="${e}">`).join("\n"),l=n.map(e=>` <script src="${e}"><\/script>`).join("\n");let a;const c=R.template?e.resolve(R.context,R.template):null;if(c&&s(c)){a=t(c,"utf-8"),i&&(a=a.includes("</head>")?a.replace("</head>",`${i}\n</head>`):i+"\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>",...i?[i]:[],..."head"===R.inject?[l]:[],"</head>","<body>",' <div id="root"></div>',..."head"!==R.inject?[l]:[],"</body>","</html>"].join("\n");this.emitFile({type:"asset",fileName:R.filename,source:a})}}))}var R;const A=i?this.resolveServerExternals(n):n.externals||[];let P;if(i){const t=n.ssr,r="esm"===t?.output?.formats?"es":"cjs";P={file:e.resolve(v,t?.output?.filename||"server.cjs"),format:r,sourcemap:n.js?.sourcemap||!1,exports:"named",inlineDynamicImports:!0}}else if(x&&b.length>1)P=b.map(t=>{const r=O(t),o=k[t]??".js";return{file:e.resolve(v,`${E}${o}`),format:r,sourcemap:n.js?.sourcemap||!1,name:["umd","iife"].includes(r)?j||e.basename(String(f),e.extname(String(f))):void 0,inlineDynamicImports:["umd","iife"].includes(r),exports:"named"}});else{const t=b[0]??"es",r=O(t);P={file:e.resolve(v,x?`${E}${k[t]??".js"}`:C),format:r,sourcemap:n.js?.sourcemap||!1,name:["umd","iife"].includes(r)?j||e.basename(String(f),e.extname(String(f))):void 0,inlineDynamicImports:["umd","iife"].includes(r)}}return this.devServerConfig={host:n.devServer?.host??"0.0.0.0",port:n.devServer?.port??3e3,open:n.devServer?.open??!1,proxy:n.devServer?.proxy??{},outDir:v,library:x},{input:e.resolve(this.context,String(f)),output:P,plugins:D,external:A}}validateConfig(e,t){return!t||v(t,this.mode).valid}resolveServerExternals(r){const o=r.ssr?.externals;if(Array.isArray(o))return o;const n=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=>n.add(e)),Object.keys(e.peerDependencies||{}).forEach(e=>n.add(e))}}catch{}return t=>{if(t.startsWith("node:"))return!0;if(t.startsWith(".")||e.isAbsolute(t))return!1;if(n.has(t))return!0;for(const e of n)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=R(t),i=n({...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 l=new $({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=>{"START"===r.code&&this.logger.log("rollup 开始重新构建...","rollup"),"END"===r.code&&(this.logger.done("rollup 构建完成","rollup"),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=R(e),r=await i(t),o=Array.isArray(t.output)?t.output:[t.output];for(const e of o)await r.write(e);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=y(t,this.mode),l=R(this.transformConfig(i)),a=e.resolve(this.context,s.output.dir),c=s.output.filename||"server.cjs",p=e.resolve(a,c);let u=!1,d=[];n({...l,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[x({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{A 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 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};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bundlekit/bundler-rollup",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
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.3"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@rollup/plugin-terser": "^0.4.4",
|
|
@@ -44,7 +44,13 @@
|
|
|
44
44
|
"bundlekit"
|
|
45
45
|
],
|
|
46
46
|
"author": "harhao@163.com",
|
|
47
|
-
"license": "
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"website": "https://bundlekit.harhao.workers.dev",
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "https://github.com/Harhao/bundlekit.git",
|
|
52
|
+
"directory": "packages/bundlekit-bundler-rollup"
|
|
53
|
+
},
|
|
48
54
|
"publishConfig": {
|
|
49
55
|
"registry": "https://registry.npmjs.org/",
|
|
50
56
|
"access": "public"
|