@platform/react.ssr
Version:
A lightweight SSR (server-side-rendering) system for react apps bundled with ParcelJS and hosted on S3.
115 lines (98 loc) • 2.99 kB
text/typescript
import { bundler } from '../bundler';
import { Config } from '../config';
import { t, fs, log } from './common';
import * as status from './cmd.status';
type PayloadType = 'MANIFEST' | 'BUNDLE';
/**
* Push a bundle or manifest to S3.
*/
export async function run(args: { cli: t.ICmdApp; type?: PayloadType; silent?: boolean }) {
const { cli, silent } = args;
const config = await Config.create();
let type = args.type;
if (type === undefined) {
type = await cli.prompt.list<PayloadType>({
message: 'type',
items: [
{ name: 'bundle', value: 'BUNDLE' },
{ name: 'manifest', value: 'MANIFEST' },
],
});
}
if (type === 'MANIFEST') {
await manifest({ cli, config, silent });
}
if (type === 'BUNDLE') {
await bundle({ cli, config, silent, prompt: true });
}
// Finish up.
if (!args.silent) {
log.info();
}
}
/**
* Push bundle to S3.
*/
export async function bundle(args: {
cli: t.ICmdApp;
config?: Config;
version?: string;
prompt?: boolean;
silent?: boolean;
}) {
const { cli, silent } = args;
const config = args.config || (await Config.create());
const bundlesDir = config.builder.bundles;
const promptForVersion = async () => {
const paths = await bundler.dir(bundlesDir).semver();
const versions = paths.map((path) => fs.basename(path)).reverse();
const items = [...versions, '---'];
const res = await cli.prompt.list<string>({ message: 'bundle version', items });
return res;
};
// Derive the bundle-version to push.
const version = args.prompt
? await promptForVersion()
: args.version || fs.basename(await bundler.dir(bundlesDir).latest());
// S3 config.
const { endpoint, accessKey, secret, bucket } = config.s3;
const s3 = { endpoint, accessKey, secret };
const bucketKey = fs.join(config.s3.path.base, config.s3.path.bundles, version);
// Ensure the bundle exists.
const bundleDir = fs.resolve(fs.join(bundlesDir, version));
if (!(await fs.pathExists(bundleDir))) {
log.error(`\nBundle does not exist.`);
log.info.gray(bundleDir);
cli.exit(1);
}
// Push.
await bundler.push({ ...s3, cli }).bundle({
bundleDir,
bucket,
bucketKey,
silent,
});
// Finish up.
if (!args.silent) {
log.info();
}
return { version, bundleDir };
}
/**
* Push manifest to S3.
*/
export async function manifest(args: { cli: t.ICmdApp; config?: Config; silent?: boolean }) {
const { cli, silent } = args;
const config = args.config || (await Config.create());
const s3 = config.s3;
// Push change to S3.
const bucket = s3.bucket;
const source = config.manifest.local.path;
const target = fs.join(s3.path.base, s3.path.manifest);
await bundler.push({ ...s3.config, cli }).manifest({ bucket, source, target, silent });
// Finish up.
if (!silent) {
const manifest = await config.manifest.s3.pull({ loadBundleManifest: true });
await status.print({ config, manifest });
}
}