128 lines
4.2 KiB
JavaScript
128 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.0.0",
|
|
"svelte-preprocess": "^4.0.0",
|
|
"@rollup/plugin-typescript": "^6.0.0",
|
|
"typescript": "^3.9.3",
|
|
"tslib": "^2.0.0",
|
|
"@tsconfig/svelte": "^1.0.0"
|
|
})
|
|
|
|
// 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*}/gmi)
|
|
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({\n\t\t\tsourceMap: !production,\n\t\t\tinlineSources: !production\n\t\t}),'
|
|
);
|
|
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.")
|
|
}
|