@wrdagency/react-islands
Version:
Created by Kyle Cooper at [WRD.agency](https://webresultsdirect.com)
3 lines (2 loc) • 6.74 kB
JavaScript
import e from"@rollup/plugin-commonjs";import n from"@rollup/plugin-node-resolve";import t from"@rollup/plugin-replace";import o from"@rollup/plugin-terser";import r from"path";import{rollup as s,watch as i}from"rollup";import a from"@rollup/plugin-typescript";import{typescriptPaths as c}from"rollup-plugin-typescript-paths";import l,{readFileSync as u}from"fs";import{exec as p}from"child_process";import{promisify as m}from"util";import d from"yocto-spinner";import f from"command-line-args";import g from"command-line-usage";class h{lines=[];import(e,n){return n||(n=h.packageNameToProperty(e)),this.add(`import * as ${n} from "${e}"`)}createGlobalObject(e){return this.add(e.split(".").map(e=>e.trim()).filter(Boolean).map((e,n,t)=>{const o="window."+t.slice(0,n+1).join(".");return`${o} = ${o} || {}`}))}setGlobalObjectProperty(e,n,t){return this.add(`window.${e}['${n}'] = ${t}`)}static packageNameToProperty(e){return e.replace(/^@/,"").replace(/\//g,"_").replace(/[-_](.)/g,(e,n)=>n.toUpperCase()).replace(/^[a-z]/,e=>e.toUpperCase())}static renderReactComponentToFile(e,n){return`var server = require('react-dom/server');\nvar fs = require('node:fs/promises');\nvar path = require('node:path');\nconst html = server.renderToString( ${n}( {} ) );\nconst file = path.resolve(__dirname, '${e}');\nfs.writeFile(file, html, { flag: "w+" });`}add(e){return Array.isArray(e)?this.lines.push(...e):this.lines.push(e),this}out(){return this.lines.join(";\n")}}function y(e){const{dependencies:n,namespace:t=""}=e,o="\0virtual-entry";return{name:"rollup-plugin-virtualize-dependency",resolveId:e=>"virtual-entry"===e?o:null,load(e){if(e!==o)return null;const r=new h;r.createGlobalObject(t);for(const e of n){const n=h.packageNameToProperty(e);r.import(e,n),r.setGlobalObjectProperty(t,n,n)}return r.out()}}}async function w(e){const{output:n,...t}=e;let o,r=!1;try{o=await s(t),await o.write(n)}catch(e){r=!0,console.error(e)}return o&&await o.close(),!r}function b(e){const{output:n,...t}=e,o=i({...t,output:n,watch:{clearScreen:!1}});return o.on("event",e=>{"BUNDLE_END"===e.code&&e.result&&e.result.close()}),o}function j(s){const{output:i,minify:a,jsx:c,common:l}=s;return{input:"virtual-entry",jsx:c,output:{name:"Islands._Common",file:r.resolve(i,"common.js"),format:"iife"},plugins:[t({preventAssignment:!0,"process.env.NODE_ENV":JSON.stringify("production")}),y({dependencies:l,namespace:"Islands._Common"}),n(),e(),a&&o()]}}const v=m(p);class ${line(e){console.log(e)}async spinner(e,n){const t=d({text:`${e}...`}).start();await n()?t.success(`Succeeded: ${e}`):t.warning(`Failed: ${e}`)}watcher(e,n){const t=d({text:`Rebuilding ${e}...`});let o=0;n.on("event",n=>{if("START"===n.code)t.clear(),t.start(),o=Date.now();else if("END"===n.code){const n=Date.now()-o;t.success(`Rebuilt: ${e} in ${n}ms.`)}else"ERROR"===n.code&&(t.warning(`Failed: ${e}`),console.error(n.error))})}async command(e){try{const{stdout:n,stderr:t}=await v(e);return n&&console.log(n),t&&console.error(t),n}catch(e){throw console.error(e),e}}}function x(e){const{deleteAfterRunning:n=!1}=e;return{name:"rollup-plugin-run-script-after-builder",writeBundle(e,t){const o=e.dir?e.dir:r.dirname(e.file||"");for(const[e,s]of Object.entries(t)){const t=r.resolve(o,e);if("chunk"!==s.type||!s.isEntry)return;if(!t&&!t.endsWith("js"))return;if(!l.existsSync(t))return;(new $).command(`node ${t}`).then(()=>{n&&l.unlinkSync(t)})}}}}function N(r,s){const{name:i,input:l,output:u,minify:p,ssg:m,jsx:d,typescript:f,common:g,define:h}=r,{subName:y,format:w,globals:b={},prefix:j,suffix:v,plugins:$=[]}=s;return{input:l,external:Object.keys(b),jsx:d,output:{name:`Islands.${i}`,globals:b,format:w,entryFileNames:`${i}/${y}`,dir:u,banner:j&&(e=>j(e.name)),footer:v&&(e=>v(e.name))},plugins:[n({extensions:[".cjs",".mjs",".js",".json",".node",".jsx",".ts",".tsx"]}),e(),f&&a({outputToFilesystem:!1,noForceEmit:!0,compilerOptions:{outDir:u,jsx:d}}),f&&c(),t({preventAssignment:!0,values:{...h,"process.env.NODE_ENV":JSON.stringify("production")}}),p&&o(),...$]}}function O(e){return N(e,{subName:"client.js",format:"iife",globals:e.common.reduce((e,n)=>({...e,[n]:`Islands._Common["${h.packageNameToProperty(n)}"]`}),{}),suffix:()=>`\nwindow.Islands['${e.name}']?.render('${e.name}')`})}function k(e){const n=[O(e)];return e.ssg&&n.push(function(e){return N(e,{subName:"server.cjs",format:"cjs",suffix:()=>h.renderReactComponentToFile("ssg.html","module.exports.component"),plugins:[x({deleteAfterRunning:!0})]})}(e)),n}function S(e){return async function(e){let n=!0;for(const t of e)await w(t)||(n=!1);return n}(k(e))}function C(e){return b(O(e))}class T{args;callback;description;constructor(e){let{args:n,callback:t,description:o}=e;n.push({name:"help",alias:"h",type:Boolean,description:"Display this usage guide."}),this.args=n,this.callback=t,this.description=o}run(e){const{help:n,...t}=f(this.args,{argv:e});if(!n)return this.callback(t);console.log(g([{header:"Options",optionList:this.args}]))}}function _(e){const n=u(e,"utf8");return function(e){const n=(e,n)=>"boolean"==typeof e?e:n;return{islands:e.islands,output:e.output||"./dist/",minify:n(e.minify,!0),ssg:n(e.ssg,!0),jsx:e.jsx||"react-jsx",typescript:n(e.typescript,!0),common:e.common||["react","react/jsx-runtime","react-dom/client","@wrdagency/react-islands"],define:e.define||{}}}(JSON.parse(n))}!async function(e){const{command:n,help:t=!1,_unknown:o=[]}=f([{name:"command",type:String,defaultOption:!0},{name:"help",alias:"h",type:Boolean,description:"Display this usage guide."}],{stopAtFirstUnknown:!0});if(n&&n in e)return e[n].run([...o,t&&"--help"].filter(Boolean));if(t){const n=Object.keys(e).map(n=>({name:n,summary:e[n].description})),t=g([{header:"Synopsis",content:"npx react-islands <command> <options>"},{header:"Command List",content:n}]);console.log(t)}else console.error(`Command '${n}' not recognized by React Islands.`)}({build:new T({description:"Build and statically render the islands.",args:[{name:"config",type:String,alias:"c",description:"The config file to use.",defaultValue:"islands.config.json"}],callback:async e=>{const{config:n}=e,t=new $,o=_(n);o.common&&await t.spinner("Creating common dependencies file",async()=>w(j(o)));for(const[e,n]of Object.entries(o.islands))await t.spinner(`Creating island ${e}`,()=>S({name:e,input:n,...o}))}}),watch:new T({description:"Watch & build the islands for development",args:[{name:"config",type:String,alias:"c",description:"The config file to use.",defaultValue:"islands.config.json"}],callback:async e=>{const{config:n}=e,t=new $,o=_(n);if(o.common){const e=b(j(o));t.watcher("Common Dependencies",e)}for(const[e,n]of Object.entries(o.islands)){const r=C({name:e,input:n,...o});t.watcher(e,r)}}})});