Skip to content

Commit

Permalink
removes esbuild step
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderniebuhr committed Mar 22, 2024
1 parent 87ca54c commit 2487bcb
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 159 deletions.
103 changes: 13 additions & 90 deletions packages/cloudflare/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@ import type { AstroConfig, AstroIntegration, RouteData } from 'astro';

import * as fs from 'node:fs';
import * as os from 'node:os';
import { relative } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { fileURLToPath } from 'node:url';
import { createRedirectsFromAstroRoutes } from '@astrojs/underscore-redirects';
import { AstroError } from 'astro/errors';
import esbuild from 'esbuild';
import glob from 'tiny-glob';
import { getAdapter } from './getAdapter.js';
import { deduplicatePatterns } from './utils/deduplicatePatterns.js';
import { prepareImageConfig } from './utils/image-config.js';
import { prependForwardSlash } from './utils/prependForwardSlash.js';
import { rewriteWasmImportPath } from './utils/rewriteWasmImportPath.js';
import { patchSharpBundle } from './utils/sharpBundlePatch.js';
import { wasmModuleLoader } from './utils/wasm-module-loader.js';
import { getPlatformProxy } from 'wrangler';

Expand Down Expand Up @@ -62,25 +58,22 @@ export default function createIntegration(args?: Options): AstroIntegration {
let _config: AstroConfig;
let _buildConfig: BuildConfig;

const SERVER_BUILD_FOLDER = '/$server_build/';

return {
name: '@astrojs/cloudflare',
hooks: {
'astro:config:setup': ({ command, config, updateConfig, logger }) => {
updateConfig({
build: {
client: new URL(`.${config.base}`, config.outDir),
server: new URL(`.${SERVER_BUILD_FOLDER}`, config.outDir),
serverEntry: '_worker.mjs',
server: new URL('./_worker.js/', config.outDir),
serverEntry: 'index.js',
redirects: false,
},
vite: {
// load .wasm files as WebAssembly modules
plugins: [
wasmModuleLoader({
disabled: !args?.wasmModuleImports,
assetsDirectory: config.build.assets,
}),
],
},
Expand All @@ -97,12 +90,6 @@ export default function createIntegration(args?: Options): AstroIntegration {
'[@astrojs/cloudflare] `output: "server"` or `output: "hybrid"` is required to use this adapter. Otherwise, this adapter is not necessary to deploy a static site to Cloudflare.'
);
}

if (_config.base === SERVER_BUILD_FOLDER) {
throw new AstroError(
'[@astrojs/cloudflare] `base: "${SERVER_BUILD_FOLDER}"` is not allowed. Please change your `base` config to something else.'
);
}
},
'astro:server:setup': async ({ server, logger }) => {
if (args?.platformProxy?.enabled === true) {
Expand Down Expand Up @@ -146,86 +133,22 @@ export default function createIntegration(args?: Options): AstroIntegration {
(vite.resolve.alias as Record<string, string>)[alias.find] = alias.replacement;
}
}

vite.ssr ||= {};
vite.ssr.target = 'webworker';
vite.ssr.noExternal = true;
vite.ssr.external = _config.vite?.ssr?.external ?? [];

// Cloudflare env is only available per request. This isn't feasible for code that access env vars
// in a global way, so we shim their access as `process.env.*`. We will populate `process.env` later
// in its fetch handler.
vite.define = {
'process.env': 'process.env',
...vite.define,
};
vite.build ||= {};
vite.build.rollupOptions ||= {};
vite.build.rollupOptions.output ||= {};
// @ts-ignore
vite.build.rollupOptions.output.banner ||= 'globalThis.process ??= {};';

vite.build.rollupOptions.external = _config.vite?.build?.rollupOptions?.external ?? [];
}
},
'astro:build:done': async ({ pages, routes, dir }) => {
const assetsUrl = new URL(_buildConfig.assets, _buildConfig.client);

const entryPath = fileURLToPath(new URL(_buildConfig.serverEntry, _buildConfig.server));
const entryUrl = new URL(_buildConfig.serverEntry, _config.outDir);
const buildPath = fileURLToPath(entryUrl);
// A URL for the final build path after renaming
const finalBuildUrl = pathToFileURL(buildPath.replace(/\.mjs$/, '.js'));

const esbuildPlugins = [];
if (args?.imageService === 'compile') {
esbuildPlugins.push(patchSharpBundle());
}

if (args?.wasmModuleImports) {
esbuildPlugins.push(
rewriteWasmImportPath({
relativePathToAssets: relative(
fileURLToPath(_buildConfig.client),
fileURLToPath(assetsUrl)
),
})
);
}

await esbuild.build({
target: 'es2022',
platform: 'browser',
conditions: ['workerd', 'worker', 'browser'],
external: [
'node:assert',
'node:async_hooks',
'node:buffer',
'node:crypto',
'node:diagnostics_channel',
'node:events',
'node:path',
'node:process',
'node:stream',
'node:string_decoder',
'node:util',
'cloudflare:*',
],
entryPoints: [entryPath],
outfile: buildPath,
allowOverwrite: true,
format: 'esm',
bundle: true,
minify: _config.vite?.build?.minify !== false,
banner: {
js: `globalThis.process = {
argv: [],
env: {},
};`,
},
logOverride: {
'ignored-bare-import': 'silent',
},
plugins: esbuildPlugins,
});

// Rename to worker.js
await fs.promises.rename(buildPath, finalBuildUrl);

// throw the server folder in the bin
const serverUrl = new URL(_buildConfig.server);
await fs.promises.rm(serverUrl, { recursive: true, force: true });

// move cloudflare specific files to the root
const cloudflareSpecialFiles = ['_headers', '_redirects', '_routes.json'];

Expand Down
29 changes: 0 additions & 29 deletions packages/cloudflare/src/utils/rewriteWasmImportPath.ts

This file was deleted.

20 changes: 0 additions & 20 deletions packages/cloudflare/src/utils/sharpBundlePatch.ts

This file was deleted.

57 changes: 37 additions & 20 deletions packages/cloudflare/src/utils/wasm-module-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ import type { AstroConfig } from 'astro';
*/
export function wasmModuleLoader({
disabled,
assetsDirectory,
}: {
disabled: boolean;
assetsDirectory: string;
}): NonNullable<AstroConfig['vite']['plugins']>[number] {
const postfix = '.wasm?module';
let isDev = false;
Expand All @@ -31,7 +29,11 @@ export function wasmModuleLoader({
// let vite know that file format and the magic import string is intentional, and will be handled in this plugin
return {
assetsInclude: ['**/*.wasm?module'],
build: { rollupOptions: { external: /^__WASM_ASSET__.+\.wasm\.mjs$/i } },
build: {
rollupOptions: {
external: [/^__WASM_ASSET__.+\.wasm$/i, /^__WASM_ASSET__.+\.wasm.mjs$/i],
},
},
};
},

Expand All @@ -50,10 +52,8 @@ export function wasmModuleLoader({
const data = fs.readFileSync(filePath);
const base64 = data.toString('base64');

const base64Module = `
const wasmModule = new WebAssembly.Module(Uint8Array.from(atob("${base64}"), c => c.charCodeAt(0)));
export default wasmModule
`;
const base64Module = `const wasmModule = new WebAssembly.Module(Uint8Array.from(atob("${base64}"), c => c.charCodeAt(0)));export default wasmModule;`;

if (isDev) {
// no need to wire up the assets in dev mode, just rewrite
return base64Module;
Expand All @@ -68,8 +68,8 @@ export default wasmModule
// put it explicitly in the _astro assets directory with `fileName` rather than `name` so that
// vite doesn't give it a random id in its name. We need to be able to easily rewrite from
// the .mjs loader and the actual wasm asset later in the ESbuild for the worker
fileName: path.join(assetsDirectory, assetName),
source: fs.readFileSync(filePath),
fileName: assetName,
source: data,
});

// however, by default, the SSG generator cannot import the .wasm as a module, so embed as a base64 string
Expand All @@ -79,10 +79,7 @@ export default wasmModule
code: base64Module,
});

return `
import wasmModule from "__WASM_ASSET__${chunkId}.wasm.mjs";
export default wasmModule;
`;
return `import wasmModule from "__WASM_ASSET__${chunkId}.wasm.mjs";export default wasmModule;`;
},

// output original wasm file relative to the chunk
Expand All @@ -91,13 +88,33 @@ export default wasmModule;

if (!/__WASM_ASSET__/g.test(code)) return;

const final = code.replaceAll(/__WASM_ASSET__([A-Za-z\d]+).wasm.mjs/g, (s, assetId) => {
const fileName = this.getFileName(assetId);
const relativePath = path
.relative(path.dirname(chunk.fileName), fileName)
.replaceAll('\\', '/'); // fix windows paths for import
return `./${relativePath}`;
});
const isPrerendered = Object.keys(chunk.modules).some(
(moduleId) => this.getModuleInfo(moduleId)?.meta?.astro?.pageOptions?.prerender === true
);

let final = code;

// SSR
if (!isPrerendered) {
final = code.replaceAll(/__WASM_ASSET__([A-Za-z\d]+).wasm.mjs/g, (s, assetId) => {
const fileName = this.getFileName(assetId).replace(/\.mjs$/, '');
const relativePath = path
.relative(path.dirname(chunk.fileName), fileName)
.replaceAll('\\', '/'); // fix windows paths for import
return `./${relativePath}`;
});
}

// SSG
if (isPrerendered) {
final = code.replaceAll(/__WASM_ASSET__([A-Za-z\d]+).wasm.mjs/g, (s, assetId) => {
const fileName = this.getFileName(assetId);
const relativePath = path
.relative(path.dirname(chunk.fileName), fileName)
.replaceAll('\\', '/'); // fix windows paths for import
return `./${relativePath}`;
});
}

return { code: final };
},
Expand Down

0 comments on commit 2487bcb

Please sign in to comment.