diff --git a/src/swc/__tests__/options.test.ts b/src/swc/__tests__/options.test.ts index 534a96a..a352db9 100644 --- a/src/swc/__tests__/options.test.ts +++ b/src/swc/__tests__/options.test.ts @@ -33,6 +33,7 @@ const createDefaultResult = (): ParserArgsReturn => ({ outDir: undefined, // @ts-expect-error outFile: undefined, + outFileExtension: "js", quiet: false, sourceMapTarget: undefined, stripLeadingPaths: false, @@ -63,6 +64,29 @@ describe("parserArgs", () => { expect(result).toEqual(defaultResult); }); + describe("--out-file-extension", () => { + it("provides the extension in the parsed args", () => { + const args = [ + "node", + "/path/to/node_modules/swc-cli/bin/swc.js", + "src", + "--out-file-extension", + "magic_custom_extension", + ]; + const result = parserArgs(args); + const expectedOptions = deepmerge(defaultResult, { + cliOptions: { outFileExtension: "magic_custom_extension" }, + }); + expect(result).toEqual(expectedOptions); + }); + + it("provides the a sensible default", () => { + const args = ["node", "/path/to/node_modules/swc-cli/bin/swc.js", "src"]; + const result = parserArgs(args); + expect(result.cliOptions.outFileExtension).toEqual("js"); + }); + }); + describe("errors", () => { let mockExit: jest.SpyInstance; let mockConsoleError: jest.SpyInstance; diff --git a/src/swc/dir.ts b/src/swc/dir.ts index f4cefd0..26949cb 100644 --- a/src/swc/dir.ts +++ b/src/swc/dir.ts @@ -60,6 +60,7 @@ async function initialCompilation(cliOptions: CliOptions, swcOptions: Options) { copyFiles, extensions, outDir, + outFileExtension, stripLeadingPaths, sync, quiet, @@ -92,6 +93,7 @@ async function initialCompilation(cliOptions: CliOptions, swcOptions: Options) { sync, cliOptions, swcOptions, + outFileExtension, }); results.set(filename, result); } catch (err: any) { @@ -119,7 +121,14 @@ async function initialCompilation(cliOptions: CliOptions, swcOptions: Options) { Promise.allSettled( compilable.map(filename => workers - .run({ filename, outDir, sync, cliOptions, swcOptions }) + .run({ + filename, + outDir, + sync, + cliOptions, + swcOptions, + outFileExtension, + }) .catch(err => { console.error(err.message); throw err; @@ -208,6 +217,7 @@ async function watchCompilation(cliOptions: CliOptions, swcOptions: Options) { extensions, outDir, stripLeadingPaths, + outFileExtension, quiet, sync, } = cliOptions; @@ -252,6 +262,7 @@ async function watchCompilation(cliOptions: CliOptions, swcOptions: Options) { sync, cliOptions, swcOptions, + outFileExtension, }); if (!quiet && result === CompileStatus.Compiled) { const end = process.hrtime(start); diff --git a/src/swc/dirWorker.ts b/src/swc/dirWorker.ts index 102cb33..9ecdbf5 100644 --- a/src/swc/dirWorker.ts +++ b/src/swc/dirWorker.ts @@ -13,12 +13,13 @@ export default async function handleCompile(opts: { sync: boolean; cliOptions: CliOptions; swcOptions: Options; + outFileExtension: string; }) { const dest = getDest( opts.filename, opts.outDir, opts.cliOptions.stripLeadingPaths, - ".js" + `.${opts.outFileExtension}` ); const sourceFileName = slash(relative(dirname(dest), opts.filename)); diff --git a/src/swc/options.ts b/src/swc/options.ts index b64675a..ba57f00 100644 --- a/src/swc/options.ts +++ b/src/swc/options.ts @@ -81,6 +81,11 @@ export const initProgram = () => { "Compile an input directory of modules into an output directory" ); + program.option( + "--out-file-extension [string]", + "Use a specific extension for the output files [default: js]" + ); + program.option( "-D, --copy-files", "When compiling a directory copy over non-compilable files" @@ -176,6 +181,7 @@ export interface CliOptions { readonly extensions: string[]; readonly watch: boolean; readonly copyFiles: boolean; + readonly outFileExtension: string; readonly includeDotfiles: boolean; readonly deleteDirOnStart: boolean; readonly quiet: boolean; @@ -294,6 +300,7 @@ export default function parserArgs(args: string[]) { extensions: opts.extensions || DEFAULT_EXTENSIONS, watch: !!opts.watch, copyFiles: !!opts.copyFiles, + outFileExtension: opts.outFileExtension || "js", includeDotfiles: !!opts.includeDotfiles, deleteDirOnStart: Boolean(opts.deleteDirOnStart), quiet: !!opts.quiet,