UNPKG

3.53 kBJavaScriptView Raw
1/* eslint-disable no-console */
2import commander from "commander";
3import {exists, mkdir, readdir, readFile, stat, writeFile} from "mz/fs";
4import {join} from "path";
5
6import { transform} from "./index";
7
8
9
10
11
12
13
14
15export default function run() {
16 commander
17 .description(`Sucrase: super-fast Babel alternative.`)
18 .usage("[options] <srcDir>")
19 .option(
20 "-d, --out-dir <out>",
21 "Compile an input directory of modules into an output directory.",
22 )
23 .option("--out-extension <extension>", "File extension to use for all output files.", "js")
24 .option("--exclude-dirs <paths>", "Names of directories that should not be traversed.")
25 .option("-t, --transforms <transforms>", "Comma-separated list of transforms to run.")
26 .option("-q, --quiet", "Don't print the names of converted files.")
27 .option(
28 "--enable-legacy-typescript-module-interop",
29 "Use default TypeScript ESM/CJS interop strategy.",
30 )
31 .option("--enable-legacy-babel5-module-interop", "Use Babel 5 ESM/CJS interop strategy.")
32 .option("--jsx-pragma <string>", "Element creation function, defaults to `React.createElement`")
33 .option("--jsx-fragment-pragma <string>", "Fragment component, defaults to `React.Fragment`")
34 .parse(process.argv);
35
36 if (!commander.outDir) {
37 console.error("Out directory is required");
38 process.exit(1);
39 }
40
41 if (!commander.transforms) {
42 console.error("Transforms option is required.");
43 process.exit(1);
44 }
45
46 if (!commander.args[0]) {
47 console.error("Source directory is required.");
48 process.exit(1);
49 }
50
51 const outDir = commander.outDir;
52 const srcDir = commander.args[0];
53
54 const options = {
55 outExtension: commander.outExtension,
56 excludeDirs: commander.excludeDirs ? commander.excludeDirs.split(",") : [],
57 quiet: commander.quiet,
58 sucraseOptions: {
59 transforms: commander.transforms.split(","),
60 enableLegacyTypeScriptModuleInterop: commander.enableLegacyTypescriptModuleInterop,
61 enableLegacyBabel5ModuleInterop: commander.enableLegacyBabel5ModuleInterop,
62 jsxPragma: commander.jsxPragma || "React.createElement",
63 jsxFragmentPragma: commander.jsxFragmentPragma || "React.Fragment",
64 },
65 };
66
67 buildDirectory(srcDir, outDir, options).catch((e) => {
68 process.exitCode = 1;
69 console.error(e);
70 });
71}
72
73async function buildDirectory(
74 srcDirPath,
75 outDirPath,
76 options,
77) {
78 const extension = options.sucraseOptions.transforms.includes("typescript") ? ".ts" : ".js";
79 if (!(await exists(outDirPath))) {
80 await mkdir(outDirPath);
81 }
82 for (const child of await readdir(srcDirPath)) {
83 if (["node_modules", ".git"].includes(child) || options.excludeDirs.includes(child)) {
84 continue;
85 }
86 const srcChildPath = join(srcDirPath, child);
87 const outChildPath = join(outDirPath, child);
88 if ((await stat(srcChildPath)).isDirectory()) {
89 await buildDirectory(srcChildPath, outChildPath, options);
90 } else if (srcChildPath.endsWith(extension)) {
91 const outPath = `${outChildPath.substr(0, outChildPath.length - extension.length)}.${
92 options.outExtension
93 }`;
94 await buildFile(srcChildPath, outPath, options);
95 }
96 }
97}
98
99async function buildFile(srcPath, outPath, options) {
100 if (!options.quiet) {
101 console.log(`${srcPath} -> ${outPath}`);
102 }
103 const code = (await readFile(srcPath)).toString();
104 const transformedCode = transform(code, {...options.sucraseOptions, filePath: srcPath}).code;
105 await writeFile(outPath, transformedCode);
106}