diff --git a/src/commands/build.ts b/src/commands/build.ts index 520c04b..1905b6c 100644 --- a/src/commands/build.ts +++ b/src/commands/build.ts @@ -22,10 +22,6 @@ type BuildOptions = { * default = esm */ format?: 'cjs' | 'esm'; - /** - * extra esbuild plugins to build with sern. - */ - esbuildPlugins?: esbuild.Plugin[]; /** * https://esbuild.github.io/api/#drop-labels **/ @@ -46,32 +42,23 @@ type BuildOptions = { */ env?: string; }; -const CommandHandlerPlugin = (commandPaths: Array<{name: string}>, eventsPaths: Array<{name: string}>) => { +const CommandHandlerPlugin = (buildConfig: Partial, ambientFilePath: string, sernTsConfigPath: string) => { return { name: "commandhandler", setup(build) { - build.onEnd(async result => { - if(result.errors.length) return; - const commandsImports = commandPaths.map((fname, i) => - `import cm${i} from "./commands/${fname.name}"`); - const eventImports = eventsPaths.map((fname, i) => - `import em${i} from "./events/${fname.name}"`); - const commandMapTemplate = - 'export const __commands = new Map();\n ' + - commandPaths.map((_, i) => `__commands.set(cm${i}.meta.id, cm${i});`).join("\n"); - const eventsMapTemplate = - 'export const __events = new Map();\n' + - eventsPaths.map((_, i) => `__events.set(em${i}.meta.id, em${i});`).join("\n"); - const presence = await glob("./src/presence.{ts,js}"); - const startFile = - commandsImports.join('\n') + '\n' + - eventImports.join('\n') + '\n' + - (presence.length ? `import p0 from './presence.js'` : '') + "\n" + - commandMapTemplate + "\n"+ - eventsMapTemplate + "\n"; - await writeFile("./dist/handler.js", startFile); - }) + const options = build.initialOptions + + const defVersion = () => JSON.stringify(require(p.resolve('package.json')).version); + options.define = { + ...buildConfig.define ?? {}, + __DEV__: `${buildConfig.mode === 'development'}`, + __PROD__: `${buildConfig.mode === 'production'}`, + __VERSION__: `${buildConfig.defineVersion ? `${defVersion()}` : 'undefined'}` + } ?? {} + Preprocessor.writeTsConfig(buildConfig.format!, sernTsConfigPath, writeFile); + Preprocessor.writeAmbientFile(ambientFilePath, options.define!, writeFile); + } } as esbuild.Plugin } @@ -105,20 +92,12 @@ export async function build(options: Record) { buildConfig = defaultBuildConfig; console.log('No build config found, defaulting'); } - let env = {} as Record; - configDotenv({ path: buildConfig.env, processEnv: env }); - const modeButNotNodeEnvExists = env.MODE && !env.NODE_ENV; - if (modeButNotNodeEnvExists) { - console.warn('Use NODE_ENV instead of MODE \n\ - MODE has no effect. \n\ - https://nodejs.org/en/learn/getting-started/nodejs-the-difference-between-development-and-production'); - } - - if (env.NODE_ENV) { - buildConfig.mode = env.NODE_ENV as 'production' | 'development'; + configDotenv({ path: buildConfig.env }); + + if (process.env.NODE_ENV) { + buildConfig.mode = process.env.NODE_ENV as 'production' | 'development'; console.log(magentaBright('NODE_ENV:'), 'Found NODE_ENV variable, setting `mode` to this.'); } - assert(buildConfig.mode === 'development' || buildConfig.mode === 'production', 'Mode is not `production` or `development`'); try { let config = require(buildConfig.tsconfig!); @@ -128,7 +107,7 @@ export async function build(options: Record) { console.error(`Please create a ${sernConfig.language === 'javascript' ? 'jsconfig.json' : 'tsconfig.json' }`); console.error('It should have at least extend the generated one sern makes.\n \ { "extends": "./.sern/tsconfig.json" }'); - throw e; + throw e; } console.log(bold('Building with:')); @@ -139,10 +118,8 @@ export async function build(options: Record) { console.log(' ', magentaBright('env'), buildConfig.env); const sernDir = p.resolve('.sern'), - genDir = p.resolve(sernDir, 'generated'), - ambientFilePath = p.resolve(sernDir, 'ambient.d.ts'), - sernTsConfigPath = p.resolve(sernDir, 'tsconfig.json'), - packageJson = () => require(p.resolve('package.json')); + [ambientFilePath, sernTsConfigPath, genDir] = + ['ambient.d.ts', 'tsconfig.json', 'generated'].map(f => p.resolve(sernDir, f)); if (!(await pathExists(genDir))) { console.log('Making .sern/generated dir, does not exist'); @@ -150,36 +127,23 @@ export async function build(options: Record) { } const entryPoints = await glob(`./src/**/*{${validExtensions.join(',')}}`); - const [commandsPaths, eventsPaths] = await Promise.all([ - glob(`**/*`, { - withFileTypes: true, - ignore: { ignored: p => p.isDirectory() }, - cwd: "./src/commands/" - }), - glob(`**/*`, { - withFileTypes: true, - ignore: { ignored: p => p.isDirectory() }, - cwd: "./src/events/" - }) - ]) - - const defVersion = () => JSON.stringify(packageJson().version); - const define = { - ...(buildConfig.define ?? {}), - __DEV__: `${buildConfig.mode === 'development'}`, - __PROD__: `${buildConfig.mode === 'production'}`, - __VERSION__: `${buildConfig.defineVersion ? `${defVersion()}` : 'undefined'}` - } satisfies Record; +// const [commandsPaths, eventsPaths] = await Promise.all([ +// glob(`**/*`, { withFileTypes: true, ignore: { ignored: p => p.isDirectory() }, cwd: "./src/commands/" }), +// glob(`**/*`, { withFileTypes: true, ignore: { ignored: p => p.isDirectory() }, cwd: "./src/events/" }) +// ]) - await Preprocessor.writeTsConfig(buildConfig.format!, sernTsConfigPath, writeFile); - await Preprocessor.writeAmbientFile(ambientFilePath, define, writeFile); + //https://esbuild.github.io/content-types/#tsconfig-json - await esbuild.build({ + const ctx = await esbuild.context({ entryPoints, - plugins: [CommandHandlerPlugin(commandsPaths, eventsPaths)], + plugins: [CommandHandlerPlugin(buildConfig, ambientFilePath, sernTsConfigPath)], ...defaultEsbuild(buildConfig.format!, buildConfig.tsconfig), - define, dropLabels: [buildConfig.mode === 'production' ? '__DEV__' : '__PROD__', ...buildConfig.dropLabels!], }); + if(options.watch) { + } else { + ctx.rebuild() + ctx.dispose() + } } diff --git a/src/utilities/getConfig.ts b/src/utilities/getConfig.ts index 68ddfbf..aa3bba8 100644 --- a/src/utilities/getConfig.ts +++ b/src/utilities/getConfig.ts @@ -17,18 +17,17 @@ export async function getLang(): Promise<'typescript' | 'javascript'> { return output.language; } -export async function getConfig(): Promise { +export async function getConfig(): Promise { const sernLocation = await findUp('sern.config.json'); assert(sernLocation, "Can't find sern.config.json"); - const output = JSON.parse(await readFile(sernLocation, 'utf8')) as sernConfig; + const output = JSON.parse(await readFile(sernLocation, 'utf8')) as SernConfig; assert(output, "Can't read your sern.config.json."); return output; } -export interface sernConfig { - type?: "serverless" | "websocket" +export interface SernConfig { language: 'typescript' | 'javascript'; defaultPrefix?: string; paths: { @@ -36,4 +35,7 @@ export interface sernConfig { commands: string; events?: string; }; + build?: { + + } } diff --git a/src/utilities/preprocessor.ts b/src/utilities/preprocessor.ts index 284e1a1..b91360b 100644 --- a/src/utilities/preprocessor.ts +++ b/src/utilities/preprocessor.ts @@ -37,7 +37,6 @@ const writeAmbientFile = async (path: string, define: Record, wr const writeTsConfig = async (format: 'cjs' | 'esm', configPath: string, fw: FileWriter) => { //maybe better way to do this - const target = format === 'esm' ? { target: 'esnext' } : {}; const sernTsConfig = { compilerOptions: { //module determines top level await. CJS doesn't have that abliity afaik @@ -45,7 +44,7 @@ const writeTsConfig = async (format: 'cjs' | 'esm', configPath: string, fw: File moduleResolution: 'node16', strict: true, skipLibCheck: true, - ...target, + target: 'esnext', rootDirs: ['./generated', '../src'], }, include: ['./ambient.d.ts', '../src'],