-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fffe2e1
commit aac81f4
Showing
10 changed files
with
445 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@rnm/tscx": minor | ||
--- | ||
|
||
feat: init |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,50 @@ | ||
# tscx(WIP) | ||
# TSCX | ||
|
||
[![](https://img.shields.io/npm/l/@rnm/tscx.svg)](https://github.com/rnmjs/tscx/blob/main/LICENSE) | ||
[![](https://img.shields.io/npm/v/@rnm/tscx.svg)](https://www.npmjs.com/package/@rnm/tscx) | ||
[![](https://img.shields.io/npm/dm/@rnm/tscx.svg)](https://www.npmjs.com/package/@rnm/tscx) | ||
[![](https://img.shields.io/librariesio/release/npm/@rnm/tscx)](https://www.npmjs.com/package/@rnm/tscx) | ||
[![](https://packagephobia.com/badge?p=@rnm/tscx)](https://packagephobia.com/result?p=@rnm/tscx) | ||
|
||
A tsc wrapper with many convenient features. | ||
|
||
## Highlight | ||
|
||
- Same usages as `tsc` with few additional options. | ||
- Remove output folder before before every compilation. | ||
- Copy non-ts files to output folder after every compilation. | ||
- Execute js file after compilation success. | ||
- Respect `tsconfig.json`. | ||
- ESM. | ||
|
||
## Install | ||
|
||
```sh | ||
npm install typescript @nrm/tscx | ||
``` | ||
|
||
## Usages | ||
|
||
```sh | ||
# Equivalent to `npx tsc` | ||
$ npx tscx | ||
|
||
# Equivalent to `npx tsc --project tsconfig.build.json --watch` | ||
$ npx tscx --project tsconfig.build.json --watch | ||
|
||
# Remove output folder before before compilation and then compile ts code. | ||
$ npx tscx --remove | ||
|
||
# Compile ts code and then copy non-ts files to output folder after compilation. | ||
$ npx tscx --copyfiles | ||
|
||
# Compile ts code in watch mode and execute bootstrap.js after every compilation success. | ||
$ npx tscx --project tsconfig.build.json --watch --exec ./bootstrap.js | ||
|
||
# Remove => Compile => Copy => Execute => Edit any file to repeat it | ||
$ npx tscx --project tsconfig.build.json --watch --remove --copyfiles --exec ./bootstrap.js | ||
``` | ||
|
||
## License | ||
|
||
MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import path from "node:path"; | ||
import process from "node:process"; | ||
import chokidar, { type FSWatcher } from "chokidar"; | ||
import { Compiler, type CompilerOptions } from "./compiler.js"; | ||
|
||
interface TscxOptions extends CompilerOptions { | ||
watch: boolean; | ||
} | ||
|
||
export class Action { | ||
private readonly compiler; | ||
private watcher?: FSWatcher; | ||
constructor(private readonly options: TscxOptions) { | ||
this.compiler = new Compiler(options); | ||
} | ||
|
||
private setupWatcher() { | ||
const include = this.compiler.getInclude() ?? []; | ||
const watchFiles = | ||
include.length <= 0 | ||
? [process.cwd()] | ||
: include | ||
.map((i) => path.resolve(process.cwd(), i)) | ||
.concat(path.resolve(process.cwd(), this.options.project)); | ||
|
||
this.watcher = chokidar.watch(watchFiles, { | ||
ignored: ["**/node_modules/**", "**/.git/**", this.compiler.getOutDir()], | ||
ignoreInitial: true, | ||
}); | ||
this.watcher | ||
.on("add", (filepath) => this.cb(filepath)) | ||
.on("unlink", (filepath) => this.cb(filepath)) | ||
.on("change", (filepath) => this.cb(filepath)) | ||
.on("ready", () => this.cb()); | ||
} | ||
|
||
private cb(filepath?: string) { | ||
console.log("Recompile for the file updated", filepath); | ||
if ( | ||
!filepath || | ||
path.resolve(process.cwd(), filepath) !== | ||
path.resolve(process.cwd(), this.options.project) | ||
) { | ||
return this.compiler.exec(); | ||
} | ||
|
||
this.compiler.refreshTsConfig(); | ||
this.watcher | ||
?.close() | ||
.then(() => { | ||
this.setupWatcher(); | ||
}) | ||
.catch((e) => { | ||
console.error("Close watcher fail!", e); | ||
process.exit(1); | ||
}); | ||
} | ||
|
||
start() { | ||
if (!this.options.watch) { | ||
this.compiler.exec(); | ||
return; | ||
} | ||
|
||
this.setupWatcher(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import fs from "node:fs/promises"; | ||
import path from "node:path"; | ||
import { fileURLToPath } from "node:url"; | ||
import { Command } from "commander"; | ||
import { Action } from "../action.js"; | ||
|
||
const version: string = JSON.parse( | ||
await fs.readFile( | ||
path.resolve( | ||
path.dirname(fileURLToPath(import.meta.url)), | ||
"..", | ||
"..", | ||
"package.json", | ||
), | ||
"utf8", | ||
), | ||
).version; | ||
|
||
new Command() | ||
.name("tscx") | ||
.version(version) | ||
.description("The TypeScript Compiler. Run `tsc` under the hood.") | ||
.option( | ||
"-p, --project <path>", | ||
"Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.", | ||
"tsconfig.json", | ||
) | ||
.option("-w, --watch", "Watch input files.", false) | ||
.option( | ||
"-r, --remove", | ||
"Remove output folder before before every compilation.", | ||
false, | ||
) | ||
.option( | ||
"-c, --copyfiles", | ||
"Copy non-ts files to output folder after every compilation.", | ||
false, | ||
) | ||
.option( | ||
"-e, --exec <path>", | ||
"Execute the specified js file after compilation success", | ||
) | ||
.action((options) => { | ||
new Action(options).start(); | ||
}) | ||
.parse(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import fs from "node:fs/promises"; | ||
import path from "node:path"; | ||
import process from "node:process"; | ||
|
||
/** | ||
* Copy non-ts/non-js files to outDir | ||
* @param rootDir absolute path | ||
* @param outDir absolute path | ||
*/ | ||
async function copyfiles(rootDir: string, outDir: string) { | ||
rootDir = path.resolve(rootDir); | ||
outDir = path.resolve(outDir); | ||
async function walkDir(dir: string, cb: (filepath: string) => Promise<void>) { | ||
await Promise.all( | ||
(await fs.readdir(dir)) | ||
.map((filepath) => path.resolve(dir, filepath)) | ||
.map(async (filepath) => { | ||
if ((await fs.stat(filepath)).isDirectory()) { | ||
if ( | ||
filepath !== outDir && | ||
!filepath.endsWith(`${path.sep}node_modules`) | ||
) { | ||
await walkDir(filepath, cb); | ||
} | ||
} else { | ||
if (!/\.(js|cjs|mjs|jsx|ts|cts|mts|tsx)$/.test(filepath)) { | ||
await cb(filepath); | ||
} | ||
} | ||
}), | ||
); | ||
} | ||
await walkDir(rootDir, async (filepath) => { | ||
const dest = filepath.replace(rootDir, outDir); | ||
console.log("Copy", filepath, "=>", dest); | ||
await fs.copyFile(filepath, dest); | ||
}); | ||
} | ||
|
||
const rootDir = process.argv[2]; | ||
const outDir = process.argv[3]; | ||
if (!rootDir || !outDir) { | ||
throw new Error("`rootDir` and `outDir` are required"); | ||
} | ||
|
||
await copyfiles(rootDir, outDir); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { spawn } from "node:child_process"; | ||
import path from "node:path"; | ||
import process from "node:process"; | ||
import { fileURLToPath } from "node:url"; | ||
|
||
const __dirname = path.dirname(fileURLToPath(import.meta.url)); | ||
const REMOVE_PATH = path.resolve(__dirname, "remove.mjs"); | ||
const COPYFILES_PATH = path.resolve(__dirname, "copyfiles.mjs"); | ||
const TSC_PATH = path.resolve( | ||
process.cwd(), | ||
"node_modules", | ||
"typescript", | ||
"bin", | ||
"tsc", | ||
); | ||
|
||
export function remove(filepath: string) { | ||
console.log("Remove", filepath); | ||
return spawn("node", [REMOVE_PATH, filepath], { stdio: "inherit" }); | ||
} | ||
|
||
export function tsc(options: { project: string }) { | ||
console.log("Tsc", options); | ||
return spawn("node", [TSC_PATH, "--project", options.project], { | ||
stdio: "inherit", | ||
}); | ||
} | ||
|
||
export function copyfiles(rootDir: string, outDir: string) { | ||
console.log("Copyfiles", rootDir, "=>", outDir); | ||
return spawn("node", [COPYFILES_PATH, rootDir, outDir], { stdio: "inherit" }); | ||
} | ||
|
||
export function exec(filepath: string) { | ||
console.log("Execute", filepath); | ||
return spawn("node", [filepath], { stdio: "inherit" }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import fs from "node:fs"; | ||
import process from "node:process"; | ||
|
||
/** | ||
* @param filepath absolute filepath | ||
*/ | ||
async function remove(filepath: string) { | ||
await new Promise<void>((resolve, reject) => { | ||
fs.stat(filepath, (err) => { | ||
if (err) { | ||
return err.code === "ENOENT" ? resolve() : reject(err); // do nothing if file not found | ||
} | ||
fs.rm(filepath, { recursive: true }, (e) => (e ? reject(e) : resolve())); | ||
}); | ||
}); | ||
console.log(`Removed ${filepath}`); | ||
} | ||
|
||
const filepath = process.argv[2]; | ||
if (!filepath) { | ||
throw new Error("File path is required"); | ||
} | ||
|
||
await remove(filepath); |
Oops, something went wrong.