@wrdagency/react-islands 2.0.2 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/index.js +1 -410
  2. package/package.json +17 -15
package/bin/index.js CHANGED
@@ -1,411 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import fs, { readFileSync } from 'fs';
3
- import yoctoSpinner from 'yocto-spinner';
4
- import commonjsPlugin from '@rollup/plugin-commonjs';
5
- import resolvePlugin from '@rollup/plugin-node-resolve';
6
- import replacePlugin from '@rollup/plugin-replace';
7
- import terserPlugin from '@rollup/plugin-terser';
8
- import typescriptPlugin from '@rollup/plugin-typescript';
9
- import path from 'path';
10
- import { rollup } from 'rollup';
11
- import { typescriptPaths } from 'rollup-plugin-typescript-paths';
12
- import { exec } from 'child_process';
13
- import { promisify } from 'util';
14
- import commandLineArgs from 'command-line-args';
15
- import commandLineUsage from 'command-line-usage';
16
-
17
- function createGlobalObject(namespace) {
18
- return namespace
19
- .split(".")
20
- .filter(Boolean)
21
- .map((_, index, levels) => {
22
- const path = "window." + levels.slice(0, index + 1).join(".");
23
- return `${path} = ${path} || {}`;
24
- })
25
- .join(";\n");
26
- }
27
- function importPackage(packageName) {
28
- return `import * as ${packageNameToProperty(packageName)} from "${packageName}";\n`;
29
- }
30
- function importAndGlobalisePackage(packageName, globalName) {
31
- let str = "";
32
- str += importPackage(packageName);
33
- str += `${globalName} = ${packageNameToProperty(packageName)};\n`;
34
- return str;
35
- }
36
- function packageNameToProperty(packageName) {
37
- return packageName
38
- .replace(/^@/, "")
39
- .replace(/\//g, "_")
40
- .replace(/[-_](.)/g, (_, c) => c.toUpperCase())
41
- .replace(/^[a-z]/, (c) => c.toUpperCase());
42
- }
43
- function renderComponentToFile(filename, component) {
44
- return `var server = require('react-dom/server');
45
- var fs = require('node:fs/promises');
46
- var path = require('node:path');
47
- const html = server.renderToString( module.exports.component( {} ) );
48
- const file = path.resolve(__dirname, '${filename}');
49
- fs.writeFile(file, html, { flag: "w+" });`;
50
- }
51
-
52
- const normalizeOptions = (options) => {
53
- return {
54
- name: options.name,
55
- input: options.input,
56
- output: options.output || "./dist/",
57
- minify: normalizeBoolean(options.minify, true),
58
- ssg: normalizeBoolean(options.ssg, true),
59
- jsx: options.jsx || "react-jsx",
60
- typescript: normalizeBoolean(options.ssg, false),
61
- common: normalizeCommonOption(options.common || [
62
- "react",
63
- "react-dom/client",
64
- "@wrdagency/react-islands",
65
- ]),
66
- };
67
- };
68
- const normalizeBoolean = (value, fallback) => {
69
- if (value === false) {
70
- return false;
71
- }
72
- else if (value === true) {
73
- return true;
74
- }
75
- else {
76
- return fallback;
77
- }
78
- };
79
- const normalizeCommonOption = (share = [""]) => {
80
- if (Array.isArray(share)) {
81
- return share.reduce((record, packageName) => ({
82
- ...record,
83
- [packageName]: "Islands._Common." + packageNameToProperty(packageName),
84
- }), {});
85
- }
86
- else {
87
- return share;
88
- }
89
- };
90
-
91
- const execPromise = promisify(exec);
92
- const consoleExecute = async (command) => {
93
- try {
94
- const { stdout, stderr } = await execPromise(command);
95
- if (stdout) {
96
- console.log(stdout);
97
- }
98
- if (stderr) {
99
- console.error(stderr);
100
- }
101
- return stdout;
102
- }
103
- catch (e) {
104
- console.error(e);
105
- throw e;
106
- }
107
- };
108
-
109
- function runScriptAfterBuildPlugin(opts) {
110
- const { deleteAfterRunning = false } = opts;
111
- return {
112
- name: "rollup-plugin-run-script-after-builder",
113
- writeBundle(outputOptions, bundle) {
114
- const outputDir = outputOptions.dir
115
- ? outputOptions.dir
116
- : path.dirname(outputOptions.file || "");
117
- for (const [fileName, chunkInfo] of Object.entries(bundle)) {
118
- const filePath = path.resolve(outputDir, fileName);
119
- if (chunkInfo.type !== "chunk" || !chunkInfo.isEntry) {
120
- return;
121
- }
122
- if (!filePath && !filePath.endsWith("js")) {
123
- return;
124
- }
125
- if (!fs.existsSync(filePath)) {
126
- return;
127
- }
128
- consoleExecute(`node ${filePath}`).then(() => {
129
- if (deleteAfterRunning) {
130
- fs.unlinkSync(filePath);
131
- }
132
- });
133
- }
134
- },
135
- };
136
- }
137
-
138
- function virtualizeDependencyPlugin(opts) {
139
- const { dependencies, namespace = "" } = opts;
140
- const VIRTUAL_MODULE_ID = "\0virtual-entry";
141
- return {
142
- name: "rollup-plugin-virtualize-dependency",
143
- resolveId(source) {
144
- if (source === "virtual-entry")
145
- return VIRTUAL_MODULE_ID;
146
- return null;
147
- },
148
- load(id) {
149
- if (id !== VIRTUAL_MODULE_ID) {
150
- return null;
151
- }
152
- let str = createGlobalObject(namespace) + ";\n";
153
- for (const [dependency, name] of Object.entries(dependencies)) {
154
- str += importAndGlobalisePackage(dependency, name);
155
- }
156
- return str;
157
- },
158
- };
159
- }
160
-
161
- function createRollupConfigs(options) {
162
- const normalized = normalizeOptions(options);
163
- const { name, input, output, minify, ssg, jsx, typescript, common } = normalized;
164
- const configs = [];
165
- const createRollupConfig = (opts) => {
166
- const { active = true, name: mainName = `Islands.${name}`, subName, format, globals = {}, prefix, suffix, plugins = [], } = opts;
167
- if (!active) {
168
- return null;
169
- }
170
- return {
171
- input,
172
- external: Object.keys(globals),
173
- jsx,
174
- output: {
175
- name: mainName,
176
- globals,
177
- format,
178
- entryFileNames: `[name]/${subName}`,
179
- dir: output,
180
- banner: prefix && ((chunk) => prefix(chunk.name)),
181
- footer: suffix && ((chunk) => suffix(chunk.name)),
182
- },
183
- plugins: [
184
- resolvePlugin({
185
- extensions: [
186
- ".cjs",
187
- ".mjs",
188
- ".js",
189
- ".json",
190
- ".node",
191
- ".jsx",
192
- ".ts",
193
- ".tsx",
194
- ],
195
- }),
196
- commonjsPlugin(),
197
- replacePlugin({
198
- preventAssignment: true,
199
- "process.env.NODE_ENV": JSON.stringify("production"),
200
- }),
201
- minify && terserPlugin(),
202
- typescript &&
203
- typescriptPlugin({
204
- jsx,
205
- }),
206
- typescript && typescriptPaths(),
207
- ...plugins,
208
- ],
209
- };
210
- };
211
- configs.push(createRollupConfig({
212
- active: true,
213
- subName: "client.js",
214
- format: "iife",
215
- globals: common,
216
- suffix: (name) => `\nwindow.Islands['${name}']?.render('${name}')`,
217
- }));
218
- configs.push(createRollupConfig({
219
- active: ssg,
220
- subName: "server.cjs",
221
- format: "cjs",
222
- suffix: () => renderComponentToFile("ssg.html"),
223
- plugins: [
224
- runScriptAfterBuildPlugin({
225
- deleteAfterRunning: true,
226
- }),
227
- ],
228
- }));
229
- return configs.filter(isRollupOptions);
230
- }
231
- function createCommonConfig(options) {
232
- const normalized = normalizeOptions(options);
233
- const { output, minify, jsx, common } = normalized;
234
- return {
235
- input: "virtual-entry",
236
- jsx,
237
- output: {
238
- name: "Islands._Common",
239
- file: path.resolve(output, "common.js"),
240
- format: "iife",
241
- },
242
- plugins: [
243
- replacePlugin({
244
- preventAssignment: true,
245
- "process.env.NODE_ENV": JSON.stringify("production"),
246
- }),
247
- virtualizeDependencyPlugin({
248
- dependencies: common,
249
- namespace: "Islands._Common",
250
- }),
251
- resolvePlugin(),
252
- commonjsPlugin(),
253
- minify && terserPlugin(),
254
- ],
255
- };
256
- }
257
- function isRollupOptions(config) {
258
- return config !== null;
259
- }
260
- async function runRollup(inputOptions, outputOptions) {
261
- let bundle;
262
- let buildFailed = false;
263
- try {
264
- bundle = await rollup(inputOptions);
265
- await bundle.write(outputOptions);
266
- }
267
- catch (error) {
268
- buildFailed = true;
269
- console.error(error);
270
- }
271
- if (bundle) {
272
- await bundle.close();
273
- }
274
- return !buildFailed;
275
- }
276
-
277
- class Command {
278
- args;
279
- callback;
280
- description;
281
- constructor(options) {
282
- let { args, callback, description } = options;
283
- args.push({
284
- name: "help",
285
- alias: "h",
286
- type: Boolean,
287
- // @ts-ignore
288
- description: "Display this usage guide.",
289
- });
290
- this.args = args;
291
- this.callback = callback;
292
- this.description = description;
293
- }
294
- run(argv) {
295
- const { help, ...args } = commandLineArgs(this.args, { argv });
296
- if (help) {
297
- console.log(commandLineUsage([
298
- {
299
- header: "Options",
300
- optionList: this.args,
301
- },
302
- ]));
303
- return;
304
- }
305
- return this.callback(args);
306
- }
307
- }
308
- async function commandset(commands) {
309
- const { command, help = false, _unknown: argv = [], } = commandLineArgs([
310
- {
311
- name: "command",
312
- type: String,
313
- defaultOption: true,
314
- },
315
- {
316
- name: "help",
317
- alias: "h",
318
- type: Boolean,
319
- // @ts-ignore
320
- description: "Display this usage guide.",
321
- },
322
- ], {
323
- stopAtFirstUnknown: true,
324
- });
325
- if (!command || !(command in commands)) {
326
- if (help) {
327
- const commandsSummary = Object.keys(commands).map((key) => ({
328
- name: key,
329
- summary: commands[key].description,
330
- }));
331
- const usage = commandLineUsage([
332
- {
333
- header: "Synopsis",
334
- content: "npx react-islands <command> <options>",
335
- },
336
- {
337
- header: "Command List",
338
- content: commandsSummary,
339
- },
340
- ]);
341
- console.log(usage);
342
- }
343
- else {
344
- console.error(`Command '${command}' not recognized by React Islands.`);
345
- }
346
- return;
347
- }
348
- return commands[command].run([...argv, help && "--help"].filter(Boolean));
349
- }
350
-
351
- var build = new Command({
352
- description: "Build and statically render the islands.",
353
- args: [
354
- {
355
- name: "config",
356
- type: String,
357
- alias: "c",
358
- // @ts-ignore
359
- description: "The config file to use.",
360
- defaultValue: "islands.config.json",
361
- },
362
- ],
363
- callback: async (args) => {
364
- const { config } = args;
365
- const configJson = JSON.parse(readFileSync(config, "utf8"));
366
- const { islands, ...restConfig } = configJson;
367
- if (restConfig.common !== false) {
368
- const spinner = yoctoSpinner({
369
- text: `Creating common dependencies file...`,
370
- }).start();
371
- const commonRollupConfig = createCommonConfig(restConfig);
372
- const { output, ...input } = commonRollupConfig;
373
- const success = await runRollup(input, output);
374
- if (success) {
375
- spinner.success(`Succeeded: common dependencies file`);
376
- }
377
- else {
378
- spinner.warning(`Failed: common dependencies file`);
379
- }
380
- }
381
- for (const [name, input] of Object.entries(islands)) {
382
- const spinner = yoctoSpinner({
383
- text: `Creating island ${name}...`,
384
- }).start();
385
- const rollupConfigs = createRollupConfigs({
386
- input,
387
- name,
388
- ...restConfig,
389
- });
390
- let hadFailure = false;
391
- for (const rollupConfig of rollupConfigs) {
392
- const { output, ...input } = rollupConfig;
393
- const success = await runRollup(input, output);
394
- if (!success) {
395
- hadFailure = true;
396
- }
397
- }
398
- rollupConfigs.map(async (options) => { });
399
- if (hadFailure) {
400
- spinner.warning(`Failed island: ${name}`);
401
- }
402
- else {
403
- spinner.success(`Succeeded island: ${name}`);
404
- }
405
- }
406
- },
407
- });
408
-
409
- commandset({
410
- build,
411
- });
2
+ import e,{readFileSync as n}from"fs";import t from"yocto-spinner";import r from"@rollup/plugin-commonjs";import o from"@rollup/plugin-node-resolve";import s from"@rollup/plugin-replace";import i from"@rollup/plugin-terser";import a from"@rollup/plugin-typescript";import c from"path";import{rollup as l}from"rollup";import{typescriptPaths as p}from"rollup-plugin-typescript-paths";import{exec as u}from"child_process";import{promisify as m}from"util";import d from"command-line-args";import f from"command-line-usage";function g(e,n){let t="";return t+=function(e){return`import * as ${y(e)} from "${e}";\n`}(e),t+=`${n} = ${y(e)};\n`,t}function y(e){return e.replace(/^@/,"").replace(/\//g,"_").replace(/[-_](.)/g,(e,n)=>n.toUpperCase()).replace(/^[a-z]/,e=>e.toUpperCase())}const h=e=>({name:e.name,input:e.input,output:e.output||"./dist/",minify:j(e.minify,!0),ssg:j(e.ssg,!0),jsx:e.jsx||"react-jsx",typescript:j(e.ssg,!1),common:v(e.common||["react","react-dom/client","@wrdagency/react-islands"])}),j=(e,n)=>!1!==e&&(!0===e||n),v=(e=[""])=>Array.isArray(e)?e.reduce((e,n)=>({...e,[n]:"Islands._Common."+y(n)}),{}):e,w=m(u),x=async e=>{try{const{stdout:n,stderr:t}=await w(e);return n&&console.log(n),t&&console.error(t),n}catch(e){throw console.error(e),e}};function b(n){const{deleteAfterRunning:t=!1}=n;return{name:"rollup-plugin-run-script-after-builder",writeBundle(n,r){const o=n.dir?n.dir:c.dirname(n.file||"");for(const[n,s]of Object.entries(r)){const r=c.resolve(o,n);if("chunk"!==s.type||!s.isEntry)return;if(!r&&!r.endsWith("js"))return;if(!e.existsSync(r))return;x(`node ${r}`).then(()=>{t&&e.unlinkSync(r)})}}}}function $(e){const{dependencies:n,namespace:t=""}=e,r="\0virtual-entry";return{name:"rollup-plugin-virtualize-dependency",resolveId:e=>"virtual-entry"===e?r:null,load(e){if(e!==r)return null;let o=function(e){return e.split(".").filter(Boolean).map((e,n,t)=>{const r="window."+t.slice(0,n+1).join(".");return`${r} = ${r} || {}`}).join(";\n")}(t)+";\n";for(const[e,t]of Object.entries(n))o+=g(e,t);return o}}}function O(e){const n=h(e),{name:t,input:c,output:l,minify:u,ssg:m,jsx:d,typescript:f,common:g}=n,y=[],j=e=>{const{active:n=!0,name:m=`Islands.${t}`,subName:g,format:y,globals:h={},prefix:j,suffix:v,plugins:w=[]}=e;return n?{input:c,external:Object.keys(h),jsx:d,output:{name:m,globals:h,format:y,entryFileNames:`[name]/${g}`,dir:l,banner:j&&(e=>j(e.name)),footer:v&&(e=>v(e.name))},plugins:[o({extensions:[".cjs",".mjs",".js",".json",".node",".jsx",".ts",".tsx"]}),r(),s({preventAssignment:!0,"process.env.NODE_ENV":JSON.stringify("production")}),u&&i(),f&&a({jsx:d}),f&&p(),...w]}:null};return y.push(j({active:!0,subName:"client.js",format:"iife",globals:g,suffix:e=>`\nwindow.Islands['${e}']?.render('${e}')`})),y.push(j({active:m,subName:"server.cjs",format:"cjs",suffix:()=>`var server = require('react-dom/server');\n\tvar fs = require('node:fs/promises');\n\tvar path = require('node:path');\nconst html = server.renderToString( module.exports.component( {} ) );\nconst file = path.resolve(__dirname, '${"ssg.html"}');\nfs.writeFile(file, html, { flag: "w+" });`,plugins:[b({deleteAfterRunning:!0})]})),y.filter(k)}function k(e){return null!==e}async function N(e,n){let t,r=!1;try{t=await l(e),await t.write(n)}catch(e){r=!0,console.error(e)}return t&&await t.close(),!r}!async function(e){const{command:n,help:t=!1,_unknown:r=[]}=d([{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([...r,t&&"--help"].filter(Boolean));if(t){const n=Object.keys(e).map(n=>({name:n,summary:e[n].description})),t=f([{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 class{args;callback;description;constructor(e){let{args:n,callback:t,description:r}=e;n.push({name:"help",alias:"h",type:Boolean,description:"Display this usage guide."}),this.args=n,this.callback=t,this.description=r}run(e){const{help:n,...t}=d(this.args,{argv:e});if(!n)return this.callback(t);console.log(f([{header:"Options",optionList:this.args}]))}}({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:a}=e,l=JSON.parse(n(a,"utf8")),{islands:p,...u}=l;if(!1!==u.common){const e=t({text:"Creating common dependencies file..."}).start(),n=function(e){const n=h(e),{output:t,minify:a,jsx:l,common:p}=n;return{input:"virtual-entry",jsx:l,output:{name:"Islands._Common",file:c.resolve(t,"common.js"),format:"iife"},plugins:[s({preventAssignment:!0,"process.env.NODE_ENV":JSON.stringify("production")}),$({dependencies:p,namespace:"Islands._Common"}),o(),r(),a&&i()]}}(u),{output:a,...l}=n;await N(l,a)?e.success("Succeeded: common dependencies file"):e.warning("Failed: common dependencies file")}for(const[e,n]of Object.entries(p)){const r=t({text:`Creating island ${e}...`}).start(),o=O({input:n,name:e,...u});let s=!1;for(const e of o){const{output:n,...t}=e;await N(t,n)||(s=!0)}o.map(async e=>{}),s?r.warning(`Failed island: ${e}`):r.success(`Succeeded island: ${e}`)}}})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@wrdagency/react-islands",
4
- "version": "2.0.2",
4
+ "version": "2.0.4",
5
5
  "description": "",
6
6
  "main": "./dist/index.js",
7
7
  "files": [
@@ -10,7 +10,7 @@
10
10
  "bin"
11
11
  ],
12
12
  "bin": {
13
- "react-islands": "./bin/index.js"
13
+ "react-islands": "./bin/index.cjs"
14
14
  },
15
15
  "exports": {
16
16
  ".": {
@@ -28,24 +28,12 @@
28
28
  "author": "Kyle Thomas Cooper @ WRD",
29
29
  "license": "MIT",
30
30
  "devDependencies": {
31
- "@rollup/plugin-commonjs": "^28.0.6",
32
- "@rollup/plugin-json": "^6.1.0",
33
- "@rollup/plugin-node-resolve": "^16.0.1",
34
- "@rollup/plugin-replace": "^6.0.2",
35
- "@rollup/plugin-terser": "^0.4.4",
36
- "@rollup/plugin-typescript": "^12.1.4",
37
31
  "@types/command-line-args": "^5.2.3",
38
32
  "@types/command-line-usage": "^5.0.4",
39
33
  "@types/react": "^19.1.8",
40
34
  "@types/react-dom": "^19.1.6",
41
- "command-line-args": "^6.0.1",
42
- "command-line-usage": "^7.0.3",
43
- "rollup": "^4.45.1",
44
- "rollup-plugin-dts": "^6.2.1",
45
- "rollup-plugin-typescript-paths": "^1.5.0",
46
35
  "tslib": "^2.8.1",
47
- "typescript": "^5.4.3",
48
- "yocto-spinner": "^1.0.0"
36
+ "typescript": "^5.4.3"
49
37
  },
50
38
  "repository": {
51
39
  "type": "git",
@@ -53,5 +41,19 @@
53
41
  },
54
42
  "peerDependencies": {
55
43
  "react-dom": "^19.1.0"
44
+ },
45
+ "dependencies": {
46
+ "@rollup/plugin-commonjs": "^28.0.6",
47
+ "@rollup/plugin-json": "^6.1.0",
48
+ "@rollup/plugin-node-resolve": "^16.0.1",
49
+ "@rollup/plugin-replace": "^6.0.2",
50
+ "@rollup/plugin-terser": "^0.4.4",
51
+ "@rollup/plugin-typescript": "^12.1.4",
52
+ "command-line-args": "^6.0.1",
53
+ "command-line-usage": "^7.0.3",
54
+ "rollup": "^4.45.1",
55
+ "rollup-plugin-dts": "^6.2.1",
56
+ "rollup-plugin-typescript-paths": "^1.5.0",
57
+ "yocto-spinner": "^1.0.0"
56
58
  }
57
59
  }