This repository has been archived on 2023-05-03. You can view files and clone it, but cannot push or open issues or pull requests.
ocp-wg-frontend/scripts/setupTypeScript.js
2022-11-18 19:41:03 +07:00

144 lines
4.2 KiB
JavaScript

// @ts-check
/** This script modifies the project to support TS code in .svelte files like:
<script lang="ts">
export let name: string;
</script>
As well as validating the code for CI.
*/
/** To work on this script:
rm -rf test-template template && git clone sveltejs/template test-template && node scripts/setupTypeScript.js test-template
*/
const fs = require("fs");
const path = require("path");
const { argv } = require("process");
const projectRoot = argv[2] || path.join(__dirname, "..");
// Add deps to pkg.json
const packageJSON = JSON.parse(
fs.readFileSync(path.join(projectRoot, "package.json"), "utf8")
);
packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, {
"svelte-check": "^1.2.5",
"svelte-preprocess": "^4.6.9",
"@rollup/plugin-typescript": "^8.2.0",
typescript: "^4.2.3",
tslib: "^2.1.0",
"@tsconfig/svelte": "^1.0.10",
});
// Add script for checking
packageJSON.scripts = Object.assign(packageJSON.scripts, {
validate: "svelte-check",
});
// Write the package JSON
fs.writeFileSync(
path.join(projectRoot, "package.json"),
JSON.stringify(packageJSON, null, " ")
);
// mv src/main.js to main.ts - note, we need to edit rollup.config.js for this too
const beforeMainJSPath = path.join(projectRoot, "src", "main.js");
const afterMainTSPath = path.join(projectRoot, "src", "main.ts");
fs.renameSync(beforeMainJSPath, afterMainTSPath);
// Switch the app.svelte file to use TS
const appSveltePath = path.join(projectRoot, "src", "App.svelte");
let appFile = fs.readFileSync(appSveltePath, "utf8");
appFile = appFile.replace("<script>", '<script lang="ts">');
appFile = appFile.replace("export let name;", "export let name: string;");
fs.writeFileSync(appSveltePath, appFile);
// Edit rollup config
const rollupConfigPath = path.join(projectRoot, "rollup.config.js");
let rollupConfig = fs.readFileSync(rollupConfigPath, "utf8");
// Edit imports
rollupConfig = rollupConfig.replace(
`'rollup-plugin-terser';`,
`'rollup-plugin-terser';
import sveltePreprocess from 'svelte-preprocess';
import typescript from '@rollup/plugin-typescript';`
);
// Replace name of entry point
rollupConfig = rollupConfig.replace(`'src/main.js'`, `'src/main.ts'`);
// Add preprocess to the svelte config, this is tricky because there's no easy signifier.
// Instead we look for `css:` then the next `}` and add the preprocessor to that
let foundCSS = false;
let match;
// https://regex101.com/r/OtNjwo/1
const configEditor = new RegExp(/css:.|\n*}/gim);
while ((match = configEditor.exec(rollupConfig)) != null) {
if (foundCSS) {
const endOfCSSIndex = match.index + 1;
rollupConfig =
rollupConfig.slice(0, endOfCSSIndex) +
",\n preprocess: sveltePreprocess()," +
rollupConfig.slice(endOfCSSIndex);
break;
}
if (match[0].includes("css:")) foundCSS = true;
}
// Add TypeScript
rollupConfig = rollupConfig.replace(
"commonjs(),",
"commonjs(),\n\t\ttypescript({ sourceMap: !production }),"
);
fs.writeFileSync(rollupConfigPath, rollupConfig);
// Add TSConfig
const tsconfig = `{
"extends": "@tsconfig/svelte/tsconfig.json",
"include": ["src/**/*"],
"exclude": ["node_modules/*", "__sapper__/*", "public/*"],
}`;
const tsconfigPath = path.join(projectRoot, "tsconfig.json");
fs.writeFileSync(tsconfigPath, tsconfig);
// Delete this script, but not during testing
if (!argv[2]) {
// Remove the script
fs.unlinkSync(path.join(__filename));
// Check for Mac's DS_store file, and if it's the only one left remove it
const remainingFiles = fs.readdirSync(path.join(__dirname));
if (remainingFiles.length === 1 && remainingFiles[0] === ".DS_store") {
fs.unlinkSync(path.join(__dirname, ".DS_store"));
}
// Check if the scripts folder is empty
if (fs.readdirSync(path.join(__dirname)).length === 0) {
// Remove the scripts folder
fs.rmdirSync(path.join(__dirname));
}
}
// Adds the extension recommendation
fs.mkdirSync(path.join(projectRoot, ".vscode"));
fs.writeFileSync(
path.join(projectRoot, ".vscode", "extensions.json"),
`{
"recommendations": ["svelte.svelte-vscode"]
}
`
);
console.log("Converted to TypeScript.");
if (fs.existsSync(path.join(projectRoot, "node_modules"))) {
console.log(
"\nYou will need to re-run your dependency manager to get started."
);
}