Compare commits
No commits in common. "master" and "v2.2.3" have entirely different histories.
43
changelog.md
43
changelog.md
@ -1,48 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 2025-03-20 - 2.3.2 - fix(compileGlobStringObject)
|
|
||||||
Fix duplicate file outputs in glob pattern processing
|
|
||||||
|
|
||||||
- Removed duplicate concatenation of compiled files in compileGlobStringObject
|
|
||||||
- Ensured unique file paths are used during TypeScript compilation
|
|
||||||
|
|
||||||
## 2025-03-20 - 2.3.1 - fix(compiler)
|
|
||||||
Refactor compiler implementation with consolidated TsBuild class and improved diagnostics handling
|
|
||||||
|
|
||||||
- Removed legacy tsbuild.classes.compiler.ts and introduced tsbuild.classes.tsbuild.ts
|
|
||||||
- Unified compiler options merging, reading tsconfig.json, and diagnostics reporting within the TsBuild class
|
|
||||||
- Updated exports to reference the new compiler class implementation for backward compatibility
|
|
||||||
|
|
||||||
## 2025-03-20 - 2.3.0 - feat(cli)
|
|
||||||
Add emitcheck command to validate TS file emission without generating output
|
|
||||||
|
|
||||||
- Implemented the emitcheck CLI command to allow checking if TypeScript files can be emitted without producing files
|
|
||||||
- Updated tsbuild.classes.compiler.ts to include the emitCheck function
|
|
||||||
- Enhanced documentation in readme.md to describe the new emitcheck usage with examples
|
|
||||||
|
|
||||||
## 2025-03-17 - 2.2.7 - fix(compiler)
|
|
||||||
Improve diagnostic checking and error handling in the TypeScript compiler integration
|
|
||||||
|
|
||||||
- Added pre-emit diagnostics check to log errors before emitting
|
|
||||||
- Process exits on encountering pre-emit errors to ensure build correctness
|
|
||||||
- Enhanced logging for emit diagnostics to aid debugging
|
|
||||||
|
|
||||||
## 2025-03-04 - 2.2.6 - fix(package)
|
|
||||||
Fix repository URL in package.json
|
|
||||||
|
|
||||||
- Updated repository URL in package.json to point to the correct Git repository.
|
|
||||||
|
|
||||||
## 2025-03-04 - 2.2.5 - fix(package.json)
|
|
||||||
Update repository URLs in package metadata.
|
|
||||||
|
|
||||||
- Corrected the 'bugs.url' and 'homepage' fields with the accurate URLs.
|
|
||||||
|
|
||||||
## 2025-03-04 - 2.2.4 - fix(core)
|
|
||||||
Fix compiler logic to remove duplicate compiled files and improve glob pattern handling.
|
|
||||||
|
|
||||||
- Resolved an issue causing duplicate file compilations when using compileGlobStringObject.
|
|
||||||
- Improved handling of glob patterns to ensure accurate compilation paths.
|
|
||||||
|
|
||||||
## 2025-03-04 - 2.2.3 - fix(exports)
|
## 2025-03-04 - 2.2.3 - fix(exports)
|
||||||
Fixed duplicate file compilation in compileGlobStringObject
|
Fixed duplicate file compilation in compileGlobStringObject
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@git.zone/tsbuild",
|
"name": "@git.zone/tsbuild",
|
||||||
"version": "2.3.2",
|
"version": "2.2.3",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.",
|
"description": "A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
@ -16,7 +16,7 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://code.foss.global/git.zone/tsbuild.git"
|
"url": "git+ssh://git@gitlab.com/pushrocks/tsn.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"TypeScript",
|
"TypeScript",
|
||||||
@ -32,9 +32,9 @@
|
|||||||
"author": "Lossless GmbH",
|
"author": "Lossless GmbH",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://code.foss.global/git.zone/tsbuild/issues"
|
"url": "https://gitlab.com/pushrocks/tsn/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://code.foss.global/git.zone/tsbuild#README",
|
"homepage": "https://gitlab.com/pushrocks/tsn#README",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@git.zone/tspublish": "^1.9.1",
|
"@git.zone/tspublish": "^1.9.1",
|
||||||
"@push.rocks/early": "^4.0.4",
|
"@push.rocks/early": "^4.0.4",
|
||||||
|
25
readme.md
25
readme.md
@ -121,31 +121,6 @@ compiling in this order:
|
|||||||
[ 'ts_interfaces', 'ts_shared', 'ts_core', 'ts_utils', 'ts_modules' ]
|
[ 'ts_interfaces', 'ts_shared', 'ts_core', 'ts_utils', 'ts_modules' ]
|
||||||
```
|
```
|
||||||
|
|
||||||
### EmitCheck Command
|
|
||||||
|
|
||||||
Checks if TypeScript files can be emitted without actually emitting them:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx tsbuild emitcheck <file_or_glob_pattern> [additional_patterns ...]
|
|
||||||
```
|
|
||||||
|
|
||||||
This command:
|
|
||||||
1. Performs type checking on the specified TypeScript file(s)
|
|
||||||
2. Supports both direct file paths and glob patterns
|
|
||||||
3. Reports any errors that would prevent successful compilation
|
|
||||||
4. Exits with code 0 if all files can be emitted, or 1 if any cannot
|
|
||||||
5. Doesn't produce any output files
|
|
||||||
|
|
||||||
Example usage with specific files:
|
|
||||||
```bash
|
|
||||||
npx tsbuild emitcheck src/main.ts src/utils.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Example usage with glob patterns:
|
|
||||||
```bash
|
|
||||||
npx tsbuild emitcheck "src/**/*.ts" "test/**/*.ts"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Compiler Options
|
## Compiler Options
|
||||||
|
|
||||||
Additional flags can be passed to any command to modify the compilation behavior:
|
Additional flags can be passed to any command to modify the compilation behavior:
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@git.zone/tsbuild',
|
name: '@git.zone/tsbuild',
|
||||||
version: '2.3.2',
|
version: '2.2.3',
|
||||||
description: 'A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.'
|
description: 'A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.'
|
||||||
}
|
}
|
||||||
|
128
ts/tsbuild.classes.compiler.ts
Normal file
128
ts/tsbuild.classes.compiler.ts
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
// import all the stuff we need
|
||||||
|
import * as plugins from './plugins.js';
|
||||||
|
import * as paths from './paths.js';
|
||||||
|
import type { CompilerOptions, ScriptTarget, ModuleKind } from './tsbuild.exports.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the default typescript compilerOptions
|
||||||
|
*/
|
||||||
|
export const compilerOptionsDefault: CompilerOptions = {
|
||||||
|
declaration: true,
|
||||||
|
emitDecoratorMetadata: true,
|
||||||
|
experimentalDecorators: true,
|
||||||
|
inlineSourceMap: true,
|
||||||
|
noEmitOnError: true,
|
||||||
|
outDir: 'dist_ts/',
|
||||||
|
module: plugins.typescript.ModuleKind.NodeNext,
|
||||||
|
target: plugins.typescript.ScriptTarget.ESNext,
|
||||||
|
moduleResolution: plugins.typescript.ModuleResolutionKind.NodeNext,
|
||||||
|
lib: ['lib.dom.d.ts', 'lib.es2022.d.ts'],
|
||||||
|
noImplicitAny: true,
|
||||||
|
esModuleInterop: true,
|
||||||
|
useDefineForClassFields: false,
|
||||||
|
verbatimModuleSyntax: true,
|
||||||
|
baseUrl: './',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* merges compilerOptions with the default compiler options
|
||||||
|
*/
|
||||||
|
export const mergeCompilerOptions = (
|
||||||
|
customTsOptions: CompilerOptions,
|
||||||
|
argvArg?: any
|
||||||
|
): CompilerOptions => {
|
||||||
|
// create merged options
|
||||||
|
const mergedOptions: CompilerOptions = {
|
||||||
|
...compilerOptionsDefault,
|
||||||
|
...customTsOptions,
|
||||||
|
...(argvArg && argvArg.skiplibcheck
|
||||||
|
? {
|
||||||
|
skipLibCheck: true,
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
...(argvArg && argvArg.allowimplicitany
|
||||||
|
? {
|
||||||
|
noImplicitAny: false,
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
...(argvArg && argvArg.commonjs
|
||||||
|
? {
|
||||||
|
module: plugins.typescript.ModuleKind.CommonJS,
|
||||||
|
moduleResolution: plugins.typescript.ModuleResolutionKind.NodeJs,
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
...(() => {
|
||||||
|
const returnObject: CompilerOptions = {};
|
||||||
|
console.log(`looking at tsconfig.json at ${paths.cwd}`);
|
||||||
|
const tsconfig = plugins.smartfile.fs.toObjectSync(plugins.path.join(paths.cwd, 'tsconfig.json'));
|
||||||
|
if (tsconfig && tsconfig.compilerOptions && tsconfig.compilerOptions.baseUrl) {
|
||||||
|
console.log('baseUrl found in tsconfig.json');
|
||||||
|
returnObject.baseUrl = tsconfig.compilerOptions.baseUrl;
|
||||||
|
}
|
||||||
|
if (tsconfig && tsconfig.compilerOptions && tsconfig.compilerOptions.paths) {
|
||||||
|
console.log('paths found in tsconfig.json');
|
||||||
|
returnObject.paths = tsconfig.compilerOptions.paths;
|
||||||
|
for (const path of Object.keys(tsconfig.compilerOptions.paths)) {
|
||||||
|
returnObject.paths[path][0] = returnObject.paths[path][0].replace('./ts_', './dist_ts_');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnObject;
|
||||||
|
})(),
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(mergedOptions);
|
||||||
|
|
||||||
|
return mergedOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the internal main compiler function that compiles the files
|
||||||
|
*/
|
||||||
|
export const compiler = async (
|
||||||
|
fileNames: string[],
|
||||||
|
options: plugins.typescript.CompilerOptions,
|
||||||
|
argvArg?: any
|
||||||
|
): Promise<any[]> => {
|
||||||
|
if (options.skipLibCheck) {
|
||||||
|
console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?');
|
||||||
|
console.log('You are skipping libcheck... Is that really wanted?');
|
||||||
|
console.log('continuing in 5 seconds...');
|
||||||
|
console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?');
|
||||||
|
await plugins.smartdelay.delayFor(5000);
|
||||||
|
}
|
||||||
|
console.log(`Compiling ${fileNames.length} files...`);
|
||||||
|
const done = plugins.smartpromise.defer<any[]>();
|
||||||
|
const program = plugins.typescript.createProgram(fileNames, options);
|
||||||
|
const emitResult = program.emit();
|
||||||
|
|
||||||
|
// implement check only
|
||||||
|
/*let emitResult = program.emit(undefined,(args) => {
|
||||||
|
console.log(args)
|
||||||
|
});*/
|
||||||
|
|
||||||
|
const allDiagnostics = plugins.typescript
|
||||||
|
.getPreEmitDiagnostics(program)
|
||||||
|
.concat(emitResult.diagnostics);
|
||||||
|
allDiagnostics.forEach((diagnostic) => {
|
||||||
|
if (diagnostic.file) {
|
||||||
|
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
|
||||||
|
const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
||||||
|
console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
`${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const exitCode = emitResult.emitSkipped ? 1 : 0;
|
||||||
|
if (exitCode === 0) {
|
||||||
|
console.log('TypeScript emit succeeded!');
|
||||||
|
done.resolve(emitResult.emittedFiles);
|
||||||
|
} else {
|
||||||
|
console.error('TypeScript emit failed. Please investigate!');
|
||||||
|
process.exit(exitCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return done.promise;
|
||||||
|
};
|
@ -1,271 +0,0 @@
|
|||||||
// import all the stuff we need
|
|
||||||
import * as plugins from './plugins.js';
|
|
||||||
import * as paths from './paths.js';
|
|
||||||
import type { CompilerOptions, ScriptTarget, ModuleKind } from './tsbuild.exports.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default compiler options for TypeScript compilation
|
|
||||||
*/
|
|
||||||
export const compilerOptionsDefault: CompilerOptions = {
|
|
||||||
declaration: true,
|
|
||||||
emitDecoratorMetadata: true,
|
|
||||||
experimentalDecorators: true,
|
|
||||||
inlineSourceMap: true,
|
|
||||||
noEmitOnError: true,
|
|
||||||
outDir: 'dist_ts/',
|
|
||||||
module: plugins.typescript.ModuleKind.NodeNext,
|
|
||||||
target: plugins.typescript.ScriptTarget.ESNext,
|
|
||||||
moduleResolution: plugins.typescript.ModuleResolutionKind.NodeNext,
|
|
||||||
lib: ['lib.dom.d.ts', 'lib.es2022.d.ts'],
|
|
||||||
noImplicitAny: true,
|
|
||||||
esModuleInterop: true,
|
|
||||||
useDefineForClassFields: false,
|
|
||||||
verbatimModuleSyntax: true,
|
|
||||||
baseUrl: './',
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TsBuild class for handling TypeScript compilation
|
|
||||||
*/
|
|
||||||
export class TsBuild {
|
|
||||||
private fileNames: string[] = [];
|
|
||||||
private options: plugins.typescript.CompilerOptions;
|
|
||||||
private argvArg?: any;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new TsBuild instance
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
fileNames: string[] = [],
|
|
||||||
customOptions: CompilerOptions = {},
|
|
||||||
argvArg?: any
|
|
||||||
) {
|
|
||||||
this.fileNames = fileNames;
|
|
||||||
this.argvArg = argvArg;
|
|
||||||
this.options = this.mergeCompilerOptions(customOptions, argvArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to read and process tsconfig.json
|
|
||||||
*/
|
|
||||||
private getTsConfigOptions(): CompilerOptions {
|
|
||||||
console.log(`looking at tsconfig.json at ${paths.cwd}`);
|
|
||||||
const tsconfig = plugins.smartfile.fs.toObjectSync(plugins.path.join(paths.cwd, 'tsconfig.json'));
|
|
||||||
const returnObject: CompilerOptions = {};
|
|
||||||
|
|
||||||
if (!tsconfig || !tsconfig.compilerOptions) {
|
|
||||||
return returnObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tsconfig.compilerOptions.baseUrl) {
|
|
||||||
console.log('baseUrl found in tsconfig.json');
|
|
||||||
returnObject.baseUrl = tsconfig.compilerOptions.baseUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tsconfig.compilerOptions.paths) {
|
|
||||||
console.log('paths found in tsconfig.json');
|
|
||||||
returnObject.paths = tsconfig.compilerOptions.paths;
|
|
||||||
for (const path of Object.keys(tsconfig.compilerOptions.paths)) {
|
|
||||||
returnObject.paths[path][0] = returnObject.paths[path][0].replace('./ts_', './dist_ts_');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process command line arguments and return applicable compiler options
|
|
||||||
*/
|
|
||||||
private getCommandLineOptions(argvArg?: any): CompilerOptions {
|
|
||||||
if (!argvArg) return {};
|
|
||||||
|
|
||||||
const options: CompilerOptions = {};
|
|
||||||
|
|
||||||
if (argvArg.skiplibcheck) {
|
|
||||||
options.skipLibCheck = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argvArg.allowimplicitany) {
|
|
||||||
options.noImplicitAny = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argvArg.commonjs) {
|
|
||||||
options.module = plugins.typescript.ModuleKind.CommonJS;
|
|
||||||
options.moduleResolution = plugins.typescript.ModuleResolutionKind.NodeJs;
|
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merges compilerOptions with the default compiler options
|
|
||||||
*/
|
|
||||||
public mergeCompilerOptions(
|
|
||||||
customTsOptions: CompilerOptions = {},
|
|
||||||
argvArg?: any
|
|
||||||
): CompilerOptions {
|
|
||||||
// create merged options
|
|
||||||
const mergedOptions: CompilerOptions = {
|
|
||||||
...compilerOptionsDefault,
|
|
||||||
...customTsOptions,
|
|
||||||
...this.getCommandLineOptions(argvArg),
|
|
||||||
...this.getTsConfigOptions(),
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log(mergedOptions);
|
|
||||||
return mergedOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to handle and log TypeScript diagnostics
|
|
||||||
*/
|
|
||||||
private handleDiagnostics(diagnostics: readonly plugins.typescript.Diagnostic[]): boolean {
|
|
||||||
let hasErrors = false;
|
|
||||||
|
|
||||||
diagnostics.forEach((diagnostic) => {
|
|
||||||
hasErrors = true;
|
|
||||||
if (diagnostic.file) {
|
|
||||||
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
|
|
||||||
const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
|
||||||
console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
|
||||||
} else {
|
|
||||||
console.log(
|
|
||||||
`${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return hasErrors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a TypeScript program from file names and options
|
|
||||||
*/
|
|
||||||
private createProgram(
|
|
||||||
options: plugins.typescript.CompilerOptions = this.options
|
|
||||||
): plugins.typescript.Program {
|
|
||||||
return plugins.typescript.createProgram(this.fileNames, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set file names to be compiled
|
|
||||||
*/
|
|
||||||
public setFileNames(fileNames: string[]): void {
|
|
||||||
this.fileNames = fileNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set compiler options
|
|
||||||
*/
|
|
||||||
public setOptions(options: CompilerOptions): void {
|
|
||||||
this.options = { ...this.options, ...options };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The main compiler function that compiles the files
|
|
||||||
*/
|
|
||||||
public async compile(): Promise<any[]> {
|
|
||||||
if (this.options.skipLibCheck) {
|
|
||||||
console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?');
|
|
||||||
console.log('You are skipping libcheck... Is that really wanted?');
|
|
||||||
console.log('continuing in 5 seconds...');
|
|
||||||
console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?');
|
|
||||||
await plugins.smartdelay.delayFor(5000);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Compiling ${this.fileNames.length} files...`);
|
|
||||||
const done = plugins.smartpromise.defer<any[]>();
|
|
||||||
const program = this.createProgram();
|
|
||||||
|
|
||||||
// Check for pre-emit diagnostics first
|
|
||||||
const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program);
|
|
||||||
const hasPreEmitErrors = this.handleDiagnostics(preEmitDiagnostics);
|
|
||||||
|
|
||||||
// Only continue to emit phase if no pre-emit errors
|
|
||||||
if (hasPreEmitErrors) {
|
|
||||||
console.error('TypeScript pre-emit checks failed. Please fix the issues above.');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no pre-emit errors, proceed with emit
|
|
||||||
const emitResult = program.emit();
|
|
||||||
const hasEmitErrors = this.handleDiagnostics(emitResult.diagnostics);
|
|
||||||
|
|
||||||
const exitCode = emitResult.emitSkipped ? 1 : 0;
|
|
||||||
if (exitCode === 0) {
|
|
||||||
console.log('TypeScript emit succeeded!');
|
|
||||||
done.resolve(emitResult.emittedFiles);
|
|
||||||
} else {
|
|
||||||
console.error('TypeScript emit failed. Please investigate!');
|
|
||||||
process.exit(exitCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return done.promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to check if files can be emitted without actually emitting them
|
|
||||||
*/
|
|
||||||
public async checkEmit(): Promise<boolean> {
|
|
||||||
console.log(`Checking if ${this.fileNames.length} files can be emitted...`);
|
|
||||||
|
|
||||||
// Create a program with noEmit option
|
|
||||||
const program = this.createProgram({
|
|
||||||
...this.options,
|
|
||||||
noEmit: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check for pre-emit diagnostics
|
|
||||||
const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program);
|
|
||||||
const hasPreEmitErrors = this.handleDiagnostics(preEmitDiagnostics);
|
|
||||||
|
|
||||||
// Run the emit phase but with noEmit: true to check for emit errors without producing files
|
|
||||||
const emitResult = program.emit(undefined, undefined, undefined, true);
|
|
||||||
const hasEmitErrors = this.handleDiagnostics(emitResult.diagnostics);
|
|
||||||
|
|
||||||
const success = !hasPreEmitErrors && !hasEmitErrors && !emitResult.emitSkipped;
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
console.log('TypeScript emit check passed! File can be emitted successfully.');
|
|
||||||
} else {
|
|
||||||
console.error('TypeScript emit check failed. Please fix the issues above.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merges compilerOptions with the default compiler options (backward compatibility)
|
|
||||||
*/
|
|
||||||
export const mergeCompilerOptions = (
|
|
||||||
customTsOptions: CompilerOptions,
|
|
||||||
argvArg?: any
|
|
||||||
): CompilerOptions => {
|
|
||||||
const tsBuild = new TsBuild();
|
|
||||||
return tsBuild.mergeCompilerOptions(customTsOptions, argvArg);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The internal main compiler function that compiles the files (backward compatibility)
|
|
||||||
*/
|
|
||||||
export const compiler = async (
|
|
||||||
fileNames: string[],
|
|
||||||
options: plugins.typescript.CompilerOptions,
|
|
||||||
argvArg?: any
|
|
||||||
): Promise<any[]> => {
|
|
||||||
const tsBuild = new TsBuild(fileNames, options, argvArg);
|
|
||||||
return tsBuild.compile();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to check if a TypeScript file can be emitted without actually emitting it (backward compatibility)
|
|
||||||
*/
|
|
||||||
export const emitCheck = async (
|
|
||||||
fileNames: string[],
|
|
||||||
options: plugins.typescript.CompilerOptions = {},
|
|
||||||
argvArg?: any
|
|
||||||
): Promise<boolean> => {
|
|
||||||
const tsBuild = new TsBuild(fileNames, options, argvArg);
|
|
||||||
return tsBuild.checkEmit();
|
|
||||||
};
|
|
@ -32,87 +32,6 @@ export const runCli = async () => {
|
|||||||
await tsbuild.compileGlobStringObject(compilationCommandObject, {}, process.cwd(), argvArg);
|
await tsbuild.compileGlobStringObject(compilationCommandObject, {}, process.cwd(), argvArg);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* the emitcheck command checks if a TypeScript file can be emitted without actually emitting it
|
|
||||||
*/
|
|
||||||
tsbuildCli.addCommand('emitcheck').subscribe(async (argvArg) => {
|
|
||||||
const patterns = argvArg._.slice(1); // Remove the first element which is 'emitcheck'
|
|
||||||
|
|
||||||
if (patterns.length === 0) {
|
|
||||||
console.error('Error: Please provide at least one TypeScript file path or glob pattern');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const cwd = process.cwd();
|
|
||||||
let allFiles: string[] = [];
|
|
||||||
|
|
||||||
// Process each pattern - could be a direct file path or a glob pattern
|
|
||||||
for (const pattern of patterns) {
|
|
||||||
// Check if the pattern looks like a glob pattern
|
|
||||||
if (pattern.includes('*') || pattern.includes('{') || pattern.includes('?')) {
|
|
||||||
// Handle as glob pattern
|
|
||||||
console.log(`Processing glob pattern: ${pattern}`);
|
|
||||||
try {
|
|
||||||
const matchedFiles = await plugins.smartfile.fs.listFileTree(cwd, pattern);
|
|
||||||
|
|
||||||
// Ensure matchedFiles contains only strings
|
|
||||||
const stringMatchedFiles = Array.isArray(matchedFiles)
|
|
||||||
? matchedFiles.filter((item): item is string => typeof item === 'string')
|
|
||||||
: [];
|
|
||||||
|
|
||||||
if (stringMatchedFiles.length === 0) {
|
|
||||||
console.warn(`Warning: No files matched the pattern '${pattern}'`);
|
|
||||||
} else {
|
|
||||||
console.log(`Found ${stringMatchedFiles.length} files matching pattern '${pattern}'`);
|
|
||||||
|
|
||||||
// Transform to absolute paths
|
|
||||||
const absoluteMatchedFiles = plugins.smartpath.transform.toAbsolute(
|
|
||||||
stringMatchedFiles,
|
|
||||||
cwd
|
|
||||||
) as string[];
|
|
||||||
|
|
||||||
// Add to the list of all files to check
|
|
||||||
allFiles = allFiles.concat(absoluteMatchedFiles);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Error processing glob pattern '${pattern}': ${err}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Handle as direct file path
|
|
||||||
const filePath = plugins.path.isAbsolute(pattern)
|
|
||||||
? pattern
|
|
||||||
: plugins.path.join(cwd, pattern);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await plugins.smartfile.fs.fileExists(filePath);
|
|
||||||
allFiles.push(filePath);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Error: File not found: ${filePath}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter to only TypeScript files
|
|
||||||
allFiles = allFiles.filter(file => file.endsWith('.ts') || file.endsWith('.tsx'));
|
|
||||||
|
|
||||||
if (allFiles.length === 0) {
|
|
||||||
console.error('Error: No TypeScript files found to check');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Found ${allFiles.length} TypeScript files to check`);
|
|
||||||
|
|
||||||
// Process compiler options
|
|
||||||
const compilerOptions = tsbuild.mergeCompilerOptions({}, argvArg);
|
|
||||||
|
|
||||||
// Run emit check
|
|
||||||
const success = await tsbuild.emitCheck(allFiles, compilerOptions, argvArg);
|
|
||||||
|
|
||||||
// Exit with appropriate code
|
|
||||||
process.exit(success ? 0 : 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the custom command compiles any customDir to dist_customDir
|
* the custom command compiles any customDir to dist_customDir
|
||||||
*/
|
*/
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import * as plugins from './plugins.js';
|
import * as plugins from './plugins.js';
|
||||||
import type { CompilerOptions, ScriptTarget, ModuleKind } from 'typescript';
|
import type { CompilerOptions, ScriptTarget, ModuleKind } from 'typescript';
|
||||||
import { compiler, mergeCompilerOptions, emitCheck } from './tsbuild.classes.tsbuild.js';
|
import { compiler, mergeCompilerOptions } from './tsbuild.classes.compiler.js';
|
||||||
|
|
||||||
export type { CompilerOptions, ScriptTarget, ModuleKind };
|
export type { CompilerOptions, ScriptTarget, ModuleKind };
|
||||||
|
|
||||||
export * from './tsbuild.classes.tsbuild.js';
|
export * from './tsbuild.classes.compiler.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* compile am array of absolute file paths
|
* compile am array of absolute file paths
|
||||||
|
Loading…
x
Reference in New Issue
Block a user