Skip to content

Commit

Permalink
Merge pull request #210 from QwikDev/node-primary
Browse files Browse the repository at this point in the history
Improve manifest handling
  • Loading branch information
thejackshelton authored Jan 4, 2025
2 parents cf03f24 + 87f657e commit f8a20ce
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 37 deletions.
5 changes: 5 additions & 0 deletions .changeset/nine-jobs-sip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@qwikdev/astro": patch
---

fix: improved manifest handling for deployment providers using older node versions
1 change: 1 addition & 0 deletions libs/qwikdev-astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
},
"bugs": "https://github.com/thejackshelton/@qwikdev/astro/issues",
"dependencies": {
"@inox-tools/inline-mod": "^2.0.2",
"astro-integration-kit": "^0.18.0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion libs/qwikdev-astro/q-astro-manifest.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"manifestHash":"dxopp8","symbols":{"s_Jkq4JnSu3vc":{"origin":"components/qwik/counter.tsx","displayName":"counter.tsx_s","canonicalFilename":"counter.tsx_s_Jkq4JnSu3vc","hash":"Jkq4JnSu3vc","ctxKind":"function","ctxName":"component$","captures":false,"loc":[929,942]},"s_o0dE1oWgGK4":{"origin":"../../../libs/qwikdev-astro/src/root.tsx","displayName":"root.tsx_root_component","canonicalFilename":"root.tsx_root_component_o0dE1oWgGK4","hash":"o0dE1oWgGK4","ctxKind":"function","ctxName":"component$","captures":false,"loc":[81,136]},"s_WTj7Z5OCKjk":{"origin":"components/qwik/counter.tsx","displayName":"counter.tsx_s","canonicalFilename":"counter.tsx_s_WTj7Z5OCKjk","hash":"WTj7Z5OCKjk","ctxKind":"function","ctxName":"_jsxQ","captures":true,"loc":[626,639]}},"mapping":{"s_Jkq4JnSu3vc":"q-CbgFd24z.js","s_o0dE1oWgGK4":"q-BVmDhJRY.js","s_WTj7Z5OCKjk":"q-BUgo_UOC.js"},"bundles":{"q-BUgo_UOC.js":{"size":93,"imports":["q-BVmDhJRY.js","q-CbgFd24z.js"],"origins":["src/components/qwik/counter.tsx_s_WTj7Z5OCKjk.js"],"symbols":["s_WTj7Z5OCKjk"]},"q-BVmDhJRY.js":{"size":61649,"origins":["../../libs/qwikdev-astro/src/root.tsx_root_component_o0dE1oWgGK4.js","../../node_modules/.pnpm/@[email protected][email protected]_@[email protected][email protected][email protected]_/node_modules/@builder.io/qwik/dist/core.prod.mjs","@builder.io/qwik/build"],"symbols":["s_o0dE1oWgGK4"]},"q-BZLo5_WJ.js":{"size":146,"imports":["q-BVmDhJRY.js","q-CbgFd24z.js"]},"q-C3ZwI676.js":{"size":184,"imports":["q-BVmDhJRY.js","q-CbgFd24z.js"],"dynamicImports":["q-BVmDhJRY.js"],"origins":["../../libs/qwikdev-astro/src/root.tsx"]},"q-CbgFd24z.js":{"size":1694,"imports":["q-BVmDhJRY.js"],"dynamicImports":["q-BUgo_UOC.js"],"origins":["src/components/qwik/counter.tsx","src/components/qwik/counter.tsx_s_Jkq4JnSu3vc.js"],"symbols":["s_Jkq4JnSu3vc"]}},"injections":[],"version":"1","options":{"target":"client","buildMode":"production","entryStrategy":{"type":"smart"}},"platform":{"qwik":"1.12.0","vite":"","rollup":"4.29.1","env":"node","os":"darwin","node":"22.12.0"}}
{"manifestHash":"ksjrps","symbols":{"s_0DHRa0FqCj4":{"origin":"../../../libs/qwikdev-astro/src/root.tsx","displayName":"root.tsx_root_component","canonicalFilename":"root.tsx_root_component_0DHRa0FqCj4","hash":"0DHRa0FqCj4","ctxKind":"function","ctxName":"component$","captures":false,"loc":[81,136]},"s_qY02pQHKSts":{"origin":"components/qwik/counter.tsx","displayName":"counter.tsx_Counter_component","canonicalFilename":"counter.tsx_Counter_component_qY02pQHKSts","hash":"qY02pQHKSts","ctxKind":"function","ctxName":"component$","captures":false,"loc":[121,322]},"s_WDqUvWziK5k":{"origin":"components/qwik/counter.tsx","displayName":"counter.tsx_Counter_component_Fragment_button_onClick","canonicalFilename":"counter.tsx_Counter_component_Fragment_button_onClick_WDqUvWziK5k","hash":"WDqUvWziK5k","ctxKind":"eventHandler","ctxName":"onClick$","captures":true,"parent":"s_qY02pQHKSts","loc":[235,256]}},"mapping":{"s_0DHRa0FqCj4":"q-CXpka_yH.js","s_qY02pQHKSts":"q-4LT-psvh.js","s_WDqUvWziK5k":"q-Cf-M9i3S.js"},"bundles":{"q-4LT-psvh.js":{"size":88,"imports":["q-Cf-M9i3S.js","q-CXpka_yH.js"],"symbols":["s_qY02pQHKSts"]},"q-Cf-M9i3S.js":{"size":1635,"imports":["q-CXpka_yH.js"],"origins":["src/components/qwik/counter.tsx_Counter_component_Fragment_button_onClick_WDqUvWziK5k.js","src/components/qwik/counter.tsx_Counter_component_qY02pQHKSts.js"],"symbols":["s_WDqUvWziK5k"]},"q-CXpka_yH.js":{"size":61657,"origins":["../../libs/qwikdev-astro/src/root.tsx_root_component_0DHRa0FqCj4.js","../../node_modules/.pnpm/@[email protected][email protected]_@[email protected][email protected][email protected]_/node_modules/@builder.io/qwik/dist/core.prod.mjs","@builder.io/qwik/build"],"symbols":["s_0DHRa0FqCj4"]},"q-FfniopH8.js":{"size":184,"imports":["q-Cf-M9i3S.js","q-CXpka_yH.js"],"dynamicImports":["q-CXpka_yH.js"],"origins":["../../libs/qwikdev-astro/src/root.tsx"]},"q-fzuY5JUw.js":{"size":171,"imports":["q-Cf-M9i3S.js","q-CXpka_yH.js"],"dynamicImports":["q-4LT-psvh.js"],"origins":["src/components/qwik/counter.tsx"]}},"injections":[],"version":"1","options":{"target":"client","buildMode":"production","entryStrategy":{"type":"smart"}},"platform":{"qwik":"1.12.0","vite":"","rollup":"4.29.1","env":"node","os":"darwin","node":"22.12.0"}}
48 changes: 31 additions & 17 deletions libs/qwikdev-astro/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { SSRResult } from "astro";

import { isNode, qAstroManifestPath } from "inox:inline-mod:mod_0";
import { type JSXNode, jsx } from "@builder.io/qwik";
import { isDev } from "@builder.io/qwik/build";
import type { QwikManifest } from "@builder.io/qwik/optimizer";
Expand All @@ -8,6 +7,7 @@ import {
getQwikLoaderScript,
renderToStream
} from "@builder.io/qwik/server";
import type { SSRResult } from "astro";

const isQwikLoaderAddedMap = new WeakMap<SSRResult, boolean>();
const modulePreloadScript = `window.addEventListener("load",()=>{(async()=>{window.requestIdleCallback||(window.requestIdleCallback=(e,t)=>{const n=t||{},o=1,i=n.timeout||o,a=performance.now();return setTimeout(()=>{e({get didTimeout(){return!n.timeout&&performance.now()-a-o>i},timeRemaining:()=>Math.max(0,o+(performance.now()-a))})},o)});const e=async()=>{const e=new Set,t=document.querySelectorAll('script[q\\\\:type="prefetch-bundles"]');t.forEach(t=>{if(!t.textContent)return;const n=t.textContent,o=n.match(/\\["prefetch","[/]build[/]","(.*?)"\\]/);o&&o[1]&&o[1].split('","').forEach(t=>{t.startsWith("q-")&&e.add(t)})}),document.querySelectorAll('script[type="qwik/json"]').forEach(t=>{if(!t.textContent)return;const n=t.textContent.match(/q-[A-Za-z0-9_-]+\\.js/g);n&&n.forEach(t=>e.add(t))}),e.forEach(e=>{const t=document.createElement("link");t.rel="modulepreload",t.href="/build/"+e,t.fetchPriority="low",document.head.appendChild(t)})};await requestIdleCallback(await e)})()});`;
Expand Down Expand Up @@ -63,25 +63,37 @@ export async function renderToStaticMarkup(

let html = "";

// Get the manifest from the integration directory
const qwikRenderer = this.result.renderers.find(
(r) => r.name === "@qwikdev/astro"
) as any;

const manifestPath = qwikRenderer?.serverEntrypoint?.replace(
"server.ts",
"q-astro-manifest.json"
);

let integrationManifest = null;
if (manifestPath) {

/**
* fallback to dynamic import if node is false. Node is preferred because most deployment providers still use older versions of node by default, so dynamic json imports will fail.
*
* Until this improves, we'll use node's readFileSync, with dynamic json imports for those not using node.
*/
if (isNode) {
try {
const { readFileSync } = await import("node:fs");
const manifestContent = readFileSync(qAstroManifestPath, "utf-8");
integrationManifest = JSON.parse(manifestContent);
} catch (error) {
throw new Error(
`@qwikdev/astro: Failed to read the q-astro-manifest.json file. This file is required for the @qwikdev/astro integration to work.
It seems like you're using node. If this is not the case, please set the isNode option to false in the integration options in astro.config.mjs.
Also make sure this is the case with both your local and deployed environment.`
);
}
} else {
try {
integrationManifest = await import(/* @vite-ignore */ manifestPath, {
integrationManifest = await import(/* @vite-ignore */ qAstroManifestPath, {
with: { type: "json" }
});
} catch (error) {
throw new Error(
`@qwikdev/astro: This integration requires Node version 22 or higher. If this is local, check your node version with node -v. If this is a deployment, check your deployment provider's environment variables.`
`@qwikdev/astro: Failed to read the q-astro-manifest.json file. This file is required for the @qwikdev/astro integration to work.
Because isNode is set to false, the integration will use dynamic json imports to read the q-astro-manifest.json file. Check to make sure this environment supports dynamic json imports.`
);
}
}
Expand All @@ -95,7 +107,8 @@ export async function renderToStaticMarkup(
symbolMapper: globalThis.symbolMapperFn
}
: {
manifest: globalThis.qManifest || integrationManifest?.default
manifest:
globalThis.qManifest || integrationManifest?.default || integrationManifest
}),
serverData: props,
qwikPrefetchServiceWorker: {
Expand Down Expand Up @@ -158,7 +171,7 @@ export async function renderToStaticMarkup(
dangerouslySetInnerHTML: String(value),
style: "display: contents",
...namedSlot,
"q:key": globalThis.hash
"q:key": Math.random().toString(26).split(".").pop()
});

if (key === "default") {
Expand Down Expand Up @@ -213,5 +226,6 @@ export async function renderToStaticMarkup(
export default {
renderToStaticMarkup,
supportsAstroStaticSlot: true,
testing123: true,
check
};
39 changes: 25 additions & 14 deletions libs/qwikdev-astro/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { writeFileSync } from "node:fs";
import path from "node:path";
import { qwikVite, symbolMapper } from "@builder.io/qwik/optimizer";
import type {
QwikManifest,
QwikVitePluginOptions,
SymbolMapperFn
} from "@builder.io/qwik/optimizer";
import { inlineModule } from "@inox-tools/inline-mod/vite";
import inlineMod from "@inox-tools/inline-mod/vite";
import type { AstroConfig, AstroIntegration } from "astro";
import { createResolver, defineIntegration, watchDirectory } from "astro-integration-kit";
import { z } from "astro/zod";
Expand All @@ -14,7 +15,6 @@ import type { InlineConfig } from "vite";

declare global {
var symbolMapperFn: SymbolMapperFn;
var hash: string | undefined;
var relativeClientPath: string;
var qManifest: QwikManifest;
}
Expand Down Expand Up @@ -48,7 +48,12 @@ export default defineIntegration({
/**
* Enable debug mode with the qwikVite plugin.
*/
debug: z.boolean().optional()
debug: z.boolean().optional(),

/**
* Use node's readFileSync to read the manifest. Common for deployment providers that don't support dynamic json imports. When false, please ensure your deployment provider supports dynamic json imports, through environment variables or other means.
*/
isNode: z.boolean().optional().default(true)
})
.optional(),

Expand All @@ -70,19 +75,24 @@ export default defineIntegration({
let astroConfig: AstroConfig | null = null;
const { resolve: resolver } = createResolver(import.meta.url);
const filter = createFilter(options?.include, options?.exclude);
const qAstroManifestPath = resolver("../q-astro-manifest.json");

const lifecycleHooks: AstroIntegration["hooks"] = {
"astro:config:setup": async (setupProps) => {
const { addRenderer, updateConfig, config, command } = setupProps;
astroConfig = config;

// passes config values to other runtimes with a virtual module
inlineModule({
constExports: {
isNode: options?.isNode ?? true,
qAstroManifestPath
}
});

/* q-astro-manifest.json doesn't error in dev */
if (command === "dev") {
writeFileSync(
path.join(resolver("../"), "q-astro-manifest.json"),
"{}",
"utf-8"
);
writeFileSync(qAstroManifestPath, "{}", "utf-8");
}

// integration HMR support
Expand Down Expand Up @@ -225,7 +235,12 @@ export default defineIntegration({
}
}
},
plugins: [astroQwikPlugin, qwikVite(qwikSetupConfig), overrideEsbuildPlugin]
plugins: [
inlineMod(),
astroQwikPlugin,
qwikVite(qwikSetupConfig),
overrideEsbuildPlugin
]
}
});
},
Expand Down Expand Up @@ -254,11 +269,7 @@ export default defineIntegration({
outDir: finalDir,
manifestOutput: (manifest) => {
globalThis.qManifest = manifest;
writeFileSync(
path.join(resolver("../"), "q-astro-manifest.json"),
JSON.stringify(manifest),
"utf-8"
);
writeFileSync(qAstroManifestPath, JSON.stringify(manifest), "utf-8");
}
},
debug: options?.debug ?? false
Expand Down
5 changes: 0 additions & 5 deletions libs/qwikdev-astro/src/utils.ts

This file was deleted.

4 changes: 4 additions & 0 deletions libs/qwikdev-astro/src/virtual.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module "inox:inline-mod:mod_0" {
export const isNode: boolean;
export const qAstroManifestPath: string;
}
21 changes: 21 additions & 0 deletions pnpm-lock.yaml

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

0 comments on commit f8a20ce

Please sign in to comment.