Skip to content

Commit

Permalink
Merge pull request #192 from CloudCannon/fix/astro-fixes
Browse files Browse the repository at this point in the history
Astro fixes
  • Loading branch information
bglw authored May 16, 2024
2 parents 5dee388 + 12491f7 commit dce9464
Show file tree
Hide file tree
Showing 9 changed files with 335 additions and 82 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@

## Unreleased

* Adds component error boundaries to the Astro engine.
* Adds support for client rendered components inside Bookshop components.
* Astro Bookshop will now attempt to load build plugins from your integrations.
* Fixes an issue where the asset URLs generated by Astro Bookshop during live editing were wrong.
* Fixes an issue where Astro Dynamic tags would break live editing.
* Fixes some inconsistencies in content collections between Bookshop and Astro.
* Fixes some inconsistencies in the `Image` component between Bookshop and Astro.
* Fixes an issue where component names containing dashes would break MDX auto-imports.
* Fixes an issue where React TSX components would fail to parse.
* Fixes an issue where scripts in Astro components would be run multiple times when live editing.
* Fixes an issue where the Astro engine was too lenient when checking bookshop names.

## v3.9.0 (December 22, 2023)

* Adds support for the `astro:content` and `astro:assets` modules inside Bookshop components.
Expand Down
149 changes: 134 additions & 15 deletions javascript-modules/engines/astro-engine/lib/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { sassPlugin, postcssModules } from "esbuild-sass-plugin";

export const extensions = [".astro", ".jsx", ".tsx"];

const { transform: bookshopTransform } = AstroPluginVite();
const { transform: bookshopTransform } = AstroPluginVite({
__includeErrorBoundaries: true,
__removeClientDirectives: true,
});

export const buildPlugins = [
sassPlugin({
Expand All @@ -35,10 +38,49 @@ export const buildPlugins = [
: "attribute";
astroConfig = (await import(join(process.cwd(), "astro.config.mjs")))
.default;
astroConfig.output = astroConfig.output ?? "static";

const root = `${astroConfig.root ?? process.cwd()}/`.replace(
/\/+/g,
"/"
);
astroConfig.root = new URL(`file://${root}`);
} catch (err) {
astroConfig = {};
}

if (Array.isArray(astroConfig.integrations)) {
await Promise.allSettled(
astroConfig.integrations?.map((integration) => {
return integration?.hooks?.["astro:config:setup"]?.({
config: astroConfig,
logger: {
info: console.log,
warn: console.log,
error: console.log,
debug: console.log,
},
command: "build",
isRestart: true,
updateConfig: (config) => {
if (config?.vite?.plugins) {
astroConfig.vite = astroConfig.vite ?? {};
astroConfig.vite.plugins = astroConfig.vite.plugins ?? [];
astroConfig.vite.plugins.push(...config.vite.plugins);
}
},
addRenderer: () => {},
addClientDirective: () => {},
addMiddleware: () => {},
addDevToolbarApp: () => {},
addWatchFile: () => {},
injectScript: () => {},
injectRoute: () => {},
});
})
);
}

build.onResolve({ filter: /^astro:.*$/ }, async (args) => {
const type = args.path.replace("astro:", "");
if (type !== "content" && type !== "assets") {
Expand All @@ -59,6 +101,23 @@ export const buildPlugins = [
};
});

build.onResolve({ filter: /.*/ }, async (args) => {
try {
if (astroConfig.vite?.plugins) {
for (const plugin of astroConfig.vite.plugins) {
if (plugin.resolveId) {
const result = await plugin.resolveId(args.path);
if (result) {
return { path: result, namespace: "virtual" };
}
}
}
}
} catch (err) {
// Intentionally ignored
}
});

build.onLoad({ filter: /\.astro$/, namespace: "style" }, async (args) => {
let text = await fs.promises.readFile(args.path, "utf8");
let transformed = await transform(text, {
Expand All @@ -73,13 +132,25 @@ export const buildPlugins = [
};
});
build.onLoad({ filter: /\.astro$/ }, async (args) => {
let text = await fs.promises.readFile(args.path, "utf8");
let tsResult = await transform(text, {
const astroOptions = {
internalURL: "astro/runtime/server/index.js",
filename: args.path.replace(process.cwd(), ""),
scopedStyleStrategy:
astroConfig.scopedStyleStrategy ?? defaultScopedStyleStrategy,
});
};
let text = await fs.promises.readFile(args.path, "utf8");
let tsResult;
try {
tsResult = await transform(
text.replace(/<script(.|\n)*?>(.|\n)*?<\/script>/g, ""),
astroOptions
);
} catch (err) {}

if (!tsResult) {
tsResult = await transform(text, astroOptions);
}

let jsResult = await esbuild.transform(tsResult.code, {
loader: "ts",
target: "esnext",
Expand Down Expand Up @@ -159,50 +230,98 @@ export const buildPlugins = [
return { path: args.importer, namespace: "style" };
}
);

build.onLoad({ filter: /.*/, namespace: "virtual" }, async (args) => {
if (astroConfig.vite?.plugins) {
for (const plugin of astroConfig.vite.plugins) {
try {
if (!plugin.load) {
continue;
}

const result = await plugin.load(args.path);
if (!result) {
continue;
}

if (typeof result !== "string" && !result.code) {
continue;
}

return {
contents: typeof result === "string" ? result : result.code,
loader: "js",
};
} catch (err) {
// Intentionally ignored
}
}
}
});

build.onLoad({ filter: /.*/ }, async (args) => {
try{
if (astroConfig.vite?.plugins) {
const text = await fs.promises.readFile(args.path, "utf8");
for (const plugin of astroConfig.vite.plugins) {
if (
args.path.endsWith(".png") ||
args.path.endsWith(".svg") ||
args.path.endsWith(".jpg") ||
args.path.endsWith(".jpeg") ||
args.path.endsWith(".webp") ||
args.path.endsWith(".json") ||
args.path.endsWith(".ts")
) {
return;
}
if (astroConfig.vite?.plugins) {
let text;
try {
text = await fs.promises.readFile(args.path, "utf8");
} catch (err) {
return;
}

for (const plugin of astroConfig.vite.plugins) {
try {
if (!plugin.transform) {
continue;
}

const result = await plugin.transform(
text,
args.path.replace(process.cwd(), "")
);

if (!result) {
continue;
}

if (typeof result !== "string" && !result.code) {
return;
continue;
}

return {
contents: typeof result === "string" ? result : result.code,
loader: "js",
};
} catch (err) {
// Intentionally ignored
}
}
} catch(err){
// Intentionally ignored
}
});
},
},
];

export const esbuildConfigFn = (esbuildOptions, options) => {
esbuildOptions.publicPath = "/_cloudcannon/";
esbuildOptions.loader = esbuildOptions.loader ?? {};
esbuildOptions.loader = {
".png": "file",
".svg": "file",
".jpg": "file",
".jpeg": "file",
".webp": "file",
".ts": "ts",
...esbuildOptions.loader,
};
};
Loading

0 comments on commit dce9464

Please sign in to comment.