Skip to content

Instantly share code, notes, and snippets.

@mcansh
Last active April 13, 2022 14:26
Show Gist options
  • Save mcansh/d78f7d657244d9a50531556057be6380 to your computer and use it in GitHub Desktop.
Save mcansh/d78f7d657244d9a50531556057be6380 to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const { convertTemplateToJavaScript } = require("./index");
let args = process.argv.slice(2);
let projectDir = path.resolve(args[0]);
convertTemplateToJavaScript(projectDir)
.then(() => {
process.exit(0);
})
.catch((error) => {
console.error(error);
process.exit(1);
});
const path = require("path");
const fse = require("fs-extra");
const glob = require("fast-glob");
const babel = require("@babel/core");
const babelPluginSyntaxJSX = require("@babel/plugin-syntax-jsx");
const babelPresetTypeScript = require("@babel/preset-typescript");
const prettier = require("prettier");
function convertToJavaScript(
filename,
source,
projectDir
) {
let result = babel.transformSync(source, {
filename,
presets: [[babelPresetTypeScript, { jsx: "preserve" }]],
plugins: [babelPluginSyntaxJSX],
compact: false,
retainLines: true,
cwd: projectDir,
});
if (!result || !result.code) {
throw new Error("Could not parse typescript");
}
/*
Babel's `compact` and `retainLines` options are both bad at formatting code.
Use Prettier for nicer formatting.
*/
return prettier.format(result.code, { parser: "babel" });
}
async function convertTemplateToJavaScript(projectDir) {
// 1. Convert all .ts files in the template to .js
let entries = glob.sync("**/*.+(ts|tsx)", {
cwd: projectDir,
absolute: true,
ignore: ["**/node_modules/**"],
});
for (let entry of entries) {
if (entry.endsWith(".d.ts")) {
fse.removeSync(entry);
continue;
}
let contents = fse.readFileSync(entry, "utf8");
let filename = path.basename(entry);
let javascript = convertToJavaScript(filename, contents, projectDir);
fse.writeFileSync(entry, javascript, "utf8");
if (entry.endsWith(".tsx")) {
fse.renameSync(entry, entry.replace(/\.tsx?$/, ".jsx"));
} else {
fse.renameSync(entry, entry.replace(/\.ts?$/, ".js"));
}
}
// 2. Rename the tsconfig.json to jsconfig.json
if (fse.existsSync(path.join(projectDir, "tsconfig.json"))) {
fse.renameSync(
path.join(projectDir, "tsconfig.json"),
path.join(projectDir, "jsconfig.json")
);
}
// 3. Remove @types/* and typescript from package.json
let packageJsonPath = path.join(projectDir, "package.json");
if (!fse.existsSync(packageJsonPath)) {
throw new Error("Could not find package.json");
}
let pkg = JSON.parse(fse.readFileSync(packageJsonPath, "utf8"));
let devDeps = pkg.devDependencies || {};
devDeps = Object.fromEntries(
Object.entries(devDeps).filter(([name]) => {
return !name.startsWith("@types/") && name !== "typescript";
})
);
pkg.devDependencies = devDeps;
fse.writeJSONSync(packageJsonPath, pkg, {
spaces: 2,
});
}
{
"name": "@mcansh/untype",
"version": "1.0.0",
"bin": "./cli.js",
"license": "MIT",
"dependencies": {
"@babel/core": "7.17.8",
"@babel/plugin-syntax-jsx": "7.16.7",
"@babel/preset-typescript": "7.16.7",
"fast-glob": "3.2.11",
"fs-extra": "10.0.1",
"prettier": "2.6.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment