UNPKG

rajt

Version:

A serverless bundler layer, fully typed for AWS Lambda (Node.js and LLRT) and Cloudflare Workers.

124 lines (109 loc) 3.58 kB
import esbuild from 'esbuild' import { basename, dirname, join, relative } from 'node:path' import { fileURLToPath } from 'node:url' import { mkdirSync, existsSync, readdirSync, rmSync, copyFileSync } from 'node:fs' import { readFile, stat, writeFile } from 'node:fs/promises' const fail = (e) => { console.error('❌ Build failed' + (e ? ':' : ''), e || '') process.exit(1) } const args = process.argv.slice(2) const platform = args[0] || '' const platforms = ['aws', 'cf'] if (!platform || !platforms.includes(platform)) fail() const __dirname = dirname(fileURLToPath(import.meta.url)) const formatSize = (bytes) => { if (bytes < 1024) return `${bytes}b` if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)}kb` return `${(bytes / (1024 * 1024)).toFixed(2)}mb` } const formatTime = (ms) => { if (ms < 1000) return `${ms}ms` return `${(ms / 1000).toFixed(2)}s` } const isCF = platform == 'cf' const buildOptions = { entryPoints: [join(__dirname, `prod-${platform}.ts`)], bundle: true, minify: true, outfile: join(__dirname, '../../../dist/index.js'), platform: isCF ? 'browser' : 'node20', target: isCF ? 'es2022' : 'node20', conditions: isCF ? ['worker', 'browser'] : [], format: 'esm', treeShaking: true, legalComments: 'none', external: [ '@aws-sdk', '@smithy', ...(isCF ? [ 'cloudflare:workers', 'node:crypto', 'crypto', ] : []), ], metafile: true, write: false, plugins: [ { name: 'preserve-class-names', setup(build) { build.onLoad( { filter: /(actions|features)\/.*\.ts$/ }, async (args) => { const contents = await readFile(args.path, 'utf8') const result = await esbuild.transform(contents, { loader: 'ts', minify: true, keepNames: true }) return { contents: result.code, loader: 'ts' } } ) }, }, { name: 'remove-use-strict', setup(build) { build.onEnd(async (result) => { if (!result.outputFiles) return const files = result.outputFiles.filter(file => file.path.endsWith('.js')) await Promise.all(files.map(async file => { if (!file.path.endsWith('.js')) return await writeFile( file.path, new TextDecoder() .decode(file.contents) .replace(/(["'`])\s*use strict\s*\1;?|`use strict`;?/g, '') ) })) }) } } ] } const startTime = Date.now() const cwd = join(__dirname, '../../..') const distDir = join(cwd, 'dist') existsSync(distDir) ? readdirSync(distDir).forEach(file => rmSync(join(distDir, file), { recursive: true, force: true })) : mkdirSync(distDir, { recursive: true }) for (const file of await readdirSync(distDir)) await rmSync(join(distDir, file)) for (let file of [ 'wrangler.toml', ]) { file = join(cwd, file) if (existsSync(file)) copyFileSync(file, join(cwd, 'dist', basename(file))) } esbuild.build(buildOptions) .then(async result => { const outputFile = buildOptions.outfile const stats = await stat(outputFile) const size = formatSize(stats.size) console.log(`\n⚡️ Done in ${formatTime(Date.now() - startTime)}`) console.log(` ${relative(join(cwd, 'node_modules/rajt/src'), buildOptions.entryPoints[0])}${relative(cwd, outputFile)}`) console.log(` Size: ${size}`) console.log(` Files: ${Object.keys(result.metafile.outputs).length}`) }).catch(fail)