diff --git a/src/buildCloudflareWorker.ts b/src/buildCloudflareWorker.ts new file mode 100644 index 00000000000..548bd64f05e --- /dev/null +++ b/src/buildCloudflareWorker.ts @@ -0,0 +1,90 @@ +import { writeFile as writeFile_cb } from 'fs' +import { green, gray, cyan } from 'kolorist' +import * as rollup from 'rollup' +import esbuild from 'rollup-plugin-esbuild' +import resolve from '@rollup/plugin-node-resolve' +import commonjs from '@rollup/plugin-commonjs' +import json from '@rollup/plugin-json' +import nodePolyfills from 'rollup-plugin-polyfill-node' +import { assert } from './utils' +import { join, sep, relative } from 'path' + +export { buildCloudflareWorker } + +async function buildCloudflareWorker({ worker, root = process.cwd() }: { worker: string; root?: string }) { + console.log( + `${cyan(`vite-plugin-ssr ${require('../package.json').version}`)} ${green('building Cloudflare Worker...')}` + ) + + await buildImporter(root) + + const inputOptions: rollup.InputOptions = { + input: worker, + plugins: [ + esbuild({ + sourceMap: false, + minify: false + }), + resolve(), + commonjs(), + json(), + nodePolyfills({ sourceMap: false }) as rollup.Plugin + ], + onwarn(warning, warn) { + if (warning.code === 'CIRCULAR_DEPENDENCY') { + // Circular dependency warning doesn't seem to break build; https://github.com/snowpackjs/snowpack/pull/289#issuecomment-622167990 + return + } + warn(warning) + } + } + const bundle = await rollup.rollup(inputOptions) + const dir = join('dist', 'server') + sep + const fileName = 'worker.js' + const file = join(relative(__dirname, root), dir, fileName) + const outputOptions: rollup.OutputOptions = { + format: 'iife', + exports: 'none', + file, + sourcemap: false + } + const { output } = await bundle.generate(outputOptions) + assert(output.length === 1) + assert(output[0].fileName === fileName) + console.log(`${gray(dir)}${cyan(fileName)}`) + console.log(`${green(`✓`)} Worker built.`) + + // or write the bundle to disk + await bundle.write(outputOptions) + + // closes the bundle + await bundle.close() +} + +async function buildImporter(root: string): Promise { + const importerCode = getImporterCode() + await writeFile(join(root, 'dist', 'server', 'importer.js'), importerCode) +} + +function getImporterCode(): string { + return `// Import/require this file if you need to bundle your entire server code into a single file. For example for Cloudflare Workers. +// (The path of following dependencies are normally determined at run-time; this file makes them statically-analysable instead so that bundlers can determine the entire dependency tree at build-time.) +require("./infra.node.vite-entry.js"); +const clientManifest = require("../client/manifest.json"); +const serverManifest = require("../server/manifest.json"); +const { __private_setViteManifest } = require("vite-plugin-ssr"); +__private_setViteManifest({ clientManifest, serverManifest }); +` +} + +function writeFile(path: string, fileContent: string): Promise { + return new Promise((resolve, reject) => { + writeFile_cb(path, fileContent, 'utf8', (err) => { + if (err) { + reject(err) + } else { + resolve() + } + }) + }) +} diff --git a/src/cli/bin.node.ts b/src/cli/bin.node.ts index 71cc2f9ef2b..c6aa34dfd4d 100644 --- a/src/cli/bin.node.ts +++ b/src/cli/bin.node.ts @@ -1,4 +1,5 @@ import { cac } from 'cac' +import { buildCloudflareWorker } from '../buildCloudflareWorker' import { prerender } from '../prerender' const cli = cac('vite-plugin-ssr') @@ -17,6 +18,10 @@ cli await prerender({ partial, clientRouter, base, root }) }) +cli.command('build-cloudflare-worker ').action(async (worker: string) => { + await buildCloudflareWorker({ worker }) +}) + // Listen to unknown commands cli.on('command:*', () => { console.error('Invalid command: %s', cli.args.join(' ')) diff --git a/src/cli/index.ts b/src/cli/index.ts index 590ff8838a9..1fa04092aba 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -1 +1,2 @@ export { prerender } from '../prerender' +export { buildCloudflareWorker } from '../buildCloudflareWorker' diff --git a/src/package.json b/src/package.json index 3f730c7c3b8..e4188981614 100644 --- a/src/package.json +++ b/src/package.json @@ -6,10 +6,17 @@ "@brillout/libassert": "^0.3.0", "@brillout/path-to-regexp": "^0.1.2", "@brillout/vite-fix-2390": "^0.3.0", + "@rollup/plugin-commonjs": "^18.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^11.2.1", "cac": "^6.7.2", "devalue": "^2.0.1", + "esbuild": "^0.11.6", "fast-glob": "^3.2.5", - "kolorist": "^1.3.2" + "kolorist": "^1.3.2", + "rollup": "^2.44.0", + "rollup-plugin-esbuild": "^3.0.2", + "rollup-plugin-polyfill-node": "^0.6.2" }, "devDependencies": { "@types/node": "^14.14.37",