Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*DS_Store
*.log
.vscode/
node_modules/
public/
.greenwood/
63 changes: 63 additions & 0 deletions greenwood-plugins/monaco-editor-esm-shim-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { generate } from "astring";
// @ts-expect-error
import { ACORN_OPTIONS } from "@greenwood/cli/src/lib/parsing-utils.js";
import * as acorn from "acorn";
import * as walk from "acorn-walk";
import type { ResourcePlugin } from "@greenwood/cli";

// https://github.com/microsoft/monaco-editor/issues/886
// have to strip out CSS `import` statements from the ESM build of Monaco Editor,
// otherwise the browser will attempt to load them as ESM and fail
class StripCssImportsResource {
extensions: string[];
contentType: string;

constructor() {
this.extensions = ["js"];
this.contentType = "application/javascript";
}

async shouldIntercept(url: URL) {
return url.pathname.includes("node_modules/monaco-editor") && url.pathname.endsWith(".js");
}

async intercept(url: URL, request: Request, response: Response) {
// console.log("Intercepting Monaco Editor ESM resource:", url.pathname);
const contents = await response.text();
// TODO: acorn my be too heavy for this. could maybe just do a naive string replace
const tree = acorn.parse(contents, ACORN_OPTIONS);

walk.simple(tree, {
ImportDeclaration(node) {
// @ts-expect-error for us value will (probably) always be a string
if (node?.source?.value?.endsWith(".css")) {
// console.log("Stripping CSS import:", node.source.value);

tree.body.forEach((element) => {
if (
element.type === "ImportDeclaration" &&
element.source.value === node.source.value
) {
// Remove the element from the body
tree.body = tree.body.filter((child) => child !== element);
}
});
}
},
});

return new Response(generate(tree), {
headers: {
"Content-Type": this.contentType,
},
});
}
}

export function monacoEditorEsmShimPlugin(): ResourcePlugin {
return {
type: "resource",
name: "monaco-editor-esm-shim-plugin:resource",
provider: () => new StripCssImportsResource(),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ class ReplBundlerResource {
format: "esm",
});

// Create a buffer from the code string to avoid body consumption issues
// const codeBuffer = Buffer.from(output[0].code, 'utf-8');

return new Response(output[0].code, {
headers: {
"Content-Type": "text/javascript",
Expand Down
4 changes: 3 additions & 1 deletion greenwood.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { greenwoodPluginImportRaw } from "@greenwood/plugin-import-raw";
import { greenwoodPluginCssModules } from "@greenwood/plugin-css-modules";
import { greenwoodPluginImportJsx } from "@greenwood/plugin-import-jsx";
import { replBundlerResourcePlugin } from "./repl-bundler-plugin.ts";
import { replBundlerResourcePlugin } from "./greenwood-plugins/repl-bundler-plugin.ts";
import { monacoEditorEsmShimPlugin } from "./greenwood-plugins/monaco-editor-esm-shim-plugin.ts";
import type { Config } from "@greenwood/cli";

const config: Config = {
Expand All @@ -11,6 +12,7 @@ const config: Config = {
greenwoodPluginImportRaw(),
greenwoodPluginImportJsx(),
replBundlerResourcePlugin(),
monacoEditorEsmShimPlugin(),
],
};

Expand Down
68 changes: 55 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@
"lint": "oxlint",
"format": "oxfmt",
"format:check": "oxfmt --check",
"check": "tsgo",
"check": "tsgo --ignoreConfig --noEmit",
"prepare": "husky",
"postinstall": "patch-package"
},
"dependencies": {
"geist": "^1.2.0",
"monaco-editor": "^0.55.1",
"open-props": "^1.7.23"
},
"devDependencies": {
Expand All @@ -35,11 +36,17 @@
"@greenwood/plugin-import-jsx": "^0.34.0-alpha.4",
"@greenwood/plugin-import-raw": "^0.34.0-alpha.4",
"@typescript/native-preview": "^7.0.0-dev.20260209.1",
"acorn": "^8.16.0",
"acorn-walk": "^8.3.5",
"astring": "^1.9.0",
"husky": "^9.1.7",
"lint-staged": "^16.2.7",
"oxfmt": "^0.28.0",
"oxlint": "^1.43.0",
"patch-package": "^8.0.1",
"typescript": "^5.9.2"
"typescript": "^6.0.2"
},
"overrides": {
"wc-compiler": "~0.20.0"
}
}
13 changes: 0 additions & 13 deletions patches/@greenwood+cli+0.34.0-alpha.2.patch

This file was deleted.

69 changes: 69 additions & 0 deletions patches/@greenwood+cli+0.34.0-alpha.4.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
diff --git a/node_modules/@greenwood/cli/src/lifecycles/serve.js b/node_modules/@greenwood/cli/src/lifecycles/serve.js
index beff516..d4c24ce 100644
--- a/node_modules/@greenwood/cli/src/lifecycles/serve.js
+++ b/node_modules/@greenwood/cli/src/lifecycles/serve.js
@@ -70,9 +70,9 @@ async function getDevServer(compilation) {
(await plugin.shouldServe(url, request))
) {
const current = await plugin.serve(url, request);
- const merged = mergeResponse(response.clone(), current.clone());
+ const merged = mergeResponse(response, current);

- response = merged.clone();
+ response = merged;
}
}

@@ -106,16 +106,18 @@ async function getDevServer(compilation) {
// when looping through and sharing responses between plugins
const response = await resourcePlugins.reduce(async (responsePromise, plugin) => {
const intermediateResponse = await responsePromise;
+ // Create a single snapshot to avoid multiple clone() calls failing on exhausted bodies
+ const responseSnapshot = intermediateResponse.clone();
if (
plugin.shouldPreIntercept &&
- (await plugin.shouldPreIntercept(url, request, intermediateResponse.clone()))
+ (await plugin.shouldPreIntercept(url, request, responseSnapshot.clone()))
) {
const current = await plugin.preIntercept(
url,
request,
- await intermediateResponse.clone(),
+ await responseSnapshot.clone(),
);
- const merged = mergeResponse(intermediateResponse.clone(), current);
+ const merged = mergeResponse(responseSnapshot, current);

return Promise.resolve(merged);
} else {
@@ -152,12 +154,14 @@ async function getDevServer(compilation) {
// when looping through and sharing responses between plugins
const response = await resourcePlugins.reduce(async (responsePromise, plugin) => {
const intermediateResponse = await responsePromise;
+ // Create a single snapshot to avoid multiple clone() calls failing on exhausted bodies
+ const responseSnapshot = intermediateResponse.clone();
if (
plugin.shouldIntercept &&
- (await plugin.shouldIntercept(url, request, intermediateResponse.clone()))
+ (await plugin.shouldIntercept(url, request, responseSnapshot.clone()))
) {
- const current = await plugin.intercept(url, request, await intermediateResponse.clone());
- const merged = mergeResponse(intermediateResponse.clone(), current);
+ const current = await plugin.intercept(url, request, await responseSnapshot.clone());
+ const merged = mergeResponse(responseSnapshot, current);

return Promise.resolve(merged);
} else {
diff --git a/node_modules/@greenwood/cli/src/plugins/resource/plugin-standard-javascript.js b/node_modules/@greenwood/cli/src/plugins/resource/plugin-standard-javascript.js
index 0f54727..dbf1ea8 100644
--- a/node_modules/@greenwood/cli/src/plugins/resource/plugin-standard-javascript.js
+++ b/node_modules/@greenwood/cli/src/plugins/resource/plugin-standard-javascript.js
@@ -78,7 +78,7 @@ const greenwoodPluginStandardJavascript = [
type: "rollup",
name: "plugin-standard-javascript:rollup",
provider: (compilation) => {
- return compilation.config.optimization !== "none" ? [terser()] : [];
+ return compilation.config.optimization !== "none" ? [] : [];
},
},
];
13 changes: 13 additions & 0 deletions patches/@greenwood+plugin-import-jsx+0.34.0-alpha.4.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/node_modules/@greenwood/plugin-import-jsx/src/index.js b/node_modules/@greenwood/plugin-import-jsx/src/index.js
index 5fe6e11..15fdad2 100644
--- a/node_modules/@greenwood/plugin-import-jsx/src/index.js
+++ b/node_modules/@greenwood/plugin-import-jsx/src/index.js
@@ -4,7 +4,7 @@
*
*/
import { generate } from "astring";
-import { parseJsx } from "wc-compiler/src/jsx-loader.js";
+import { parseJsx } from "wc-compiler/jsx-loader";

class ImportJsxResource {
constructor(compilation, options) {
14 changes: 0 additions & 14 deletions patches/wc-compiler+0.18.1.patch

This file was deleted.

Loading