Automatic import/export/reference path maintenance system that reduces the burden of relative path management during code refactoring. When file locations change, grunt-ts regenerates the relevant import/export/reference statements automatically.
The transform system processes special comments in TypeScript files to generate and maintain import/export/reference statements.
/**
* Processes transforms in TypeScript files
* @param changedFiles - Files that have changed (for incremental processing)
* @param targetFiles - All target files in the compilation context
* @param options - grunt-ts options containing transform settings
*/
function transformFiles(
changedFiles: string[],
targetFiles: string[],
options: IGruntTSOptions
): void;
// Transform markers in TypeScript files
interface TransformMarkers {
/** Import transform marker */
importTransform: "///ts:import=<fileOrDirectoryName>[,<variableName>]";
/** Export transform marker */
exportTransform: "///ts:export=<fileOrDirectoryName>[,<variableName>]";
/** Reference transform marker */
referenceTransform: "///ts:ref=<fileName>";
}Automatically generates import statements with correct relative paths based on file locations.
// Transform syntax:
// ///ts:import=<fileOrDirectoryName>[,<variableName>]
interface ImportTransformBehavior {
/** Searches for files by base name (with or without .ts/.d.ts extension) */
fileMatching: "basename-match";
/** Searches for directories by name */
directoryMatching: "dirname-match";
/** For directories with index.ts, imports index.ts instead of all files */
indexFilePreference: boolean;
/** Generates relative import paths from current file location */
pathGeneration: "relative-paths";
}File Import Examples:
// In src/components/user.ts
///ts:import=api-client
// Generates: import apiClient = require('../services/api-client'); ///ts:import:generated
///ts:import=UserModel,User
// Generates: import User = require('../models/UserModel'); ///ts:import:generatedDirectory Import Examples:
// Directory without index.ts - imports all TypeScript files
///ts:import=utils
// Generates:
// import stringUtils = require('../utils/string-utils'); ///ts:import:generated
// import mathUtils = require('../utils/math-utils'); ///ts:import:generated
// import dateUtils = require('../utils/date-utils'); ///ts:import:generated
// Directory with index.ts - imports only index.ts
///ts:import=services
// Generates: import services = require('../services/index'); ///ts:import:generatedAutomatically generates export import statements for creating module indexes and re-exports.
// Transform syntax:
// ///ts:export=<fileOrDirectoryName>[,<variableName>]
interface ExportTransformBehavior {
/** Generates export import statements for external module re-exports */
statementType: "export-import";
/** Useful for creating index files that re-export entire directories */
indexGeneration: boolean;
/** Same file/directory matching rules as import transforms */
matching: "same-as-import";
}File Export Examples:
// In src/index.ts (creating a module index)
///ts:export=UserService
// Generates: export import UserService = require('./services/UserService'); ///ts:export:generated
///ts:export=ApiClient,Client
// Generates: export import Client = require('./api/ApiClient'); ///ts:export:generatedDirectory Export Examples:
// Export entire directory
///ts:export=models
// Generates:
// export import User = require('./models/User'); ///ts:export:generated
// export import Product = require('./models/Product'); ///ts:export:generated
// export import Order = require('./models/Order'); ///ts:export:generated
// Export directory with index.ts
///ts:export=services
// Generates: export import services = require('./services/index'); ///ts:export:generatedAutomatically generates triple-slash reference comments for internal module dependencies.
// Transform syntax:
// ///ts:ref=<fileName>
interface ReferenceTransformBehavior {
/** Generates triple-slash reference comments */
statementType: "triple-slash-reference";
/** Searches only in files included in src/files glob patterns */
searchScope: "compilation-context-only";
/** Generates relative paths from current file location */
pathGeneration: "relative-paths";
}Reference Examples:
// In src/app.ts
///ts:ref=BaseClass
// Generates: /// <reference path='./core/BaseClass.ts'/> ///ts:ref:generated
///ts:ref=interfaces
// Generates: /// <reference path='./types/interfaces.ts'/> ///ts:ref:generatedUnderstanding how transforms are processed and integrated with compilation.
interface TransformProcessing {
/** Transforms are processed before TypeScript compilation */
processingOrder: "before-compilation";
/** Only files in the compilation context are searched for matches */
searchScope: "src-and-files-globs-only";
/** Generated lines are marked with special comments for identification */
generatedMarkers: "///ts:import:generated" | "///ts:export:generated" | "///ts:ref:generated";
/** Existing generated lines are replaced on each run */
regeneration: "replace-existing";
}Configure transform behavior through grunt-ts options.
interface TransformOptions {
/** End-of-line character used in generated statements */
newLine?: string; // From options.newLine or system default
/** Base directory for calculating relative paths */
baseDir?: string;
/** Whether compilation is enabled (transforms can run without compilation) */
compile?: boolean;
}Transforms-Only Configuration:
ts: {
transformsOnly: {
src: ["src/**/*.ts"],
options: {
compile: false, // Only run transforms, don't compile
newLine: "LF" // Use Unix line endings
}
}
}Understanding how transforms locate target files and directories.
interface FileMatchingRules {
/** Files matched by basename with or without TypeScript extensions */
fileMatching: {
patterns: ["basename", "basename.ts", "basename.d.ts"];
caseSensitive: boolean;
};
/** Directories matched by basename */
directoryMatching: {
pattern: "dirname";
recursiveSearch: boolean;
};
/** Index file behavior for directory imports/exports */
indexFileBehavior: {
condition: "index.ts exists in directory";
action: "import/export index.ts only";
fallback: "import/export all .ts files in directory";
};
}Important limitations and requirements for using transforms.
interface TransformLimitations {
/** Target files must be included in src or files globs */
searchScope: "grunt-resolved-files-only";
/** Transforms don't search the entire filesystem */
fileSystemSearch: false;
/** Generated content is replaced on each grunt-ts run */
persistence: "regenerated-each-run";
/** Self-references are avoided (file doesn't import itself) */
selfReferenceProtection: boolean;
}Transforms work together with reference file management for comprehensive dependency handling.
interface ReferenceIntegration {
/** Transforms process individual files, reference files manage global references */
complementaryFunctionality: boolean;
/** Processing order: transforms first, then reference file updates */
processingOrder: "transforms-then-references";
/** Transform-generated files are included in reference file management */
inclusionInReferences: boolean;
}Combined Usage Example:
ts: {
fullProject: {
src: ["src/**/*.ts"],
reference: "src/references.ts",
options: {
compile: true,
fast: "watch"
}
}
}With this configuration:
Transform error handling and troubleshooting.
interface TransformErrorHandling {
/** Errors when target files/directories are not found */
missingTargets: "generates-comment-indicating-not-found";
/** Warnings for ambiguous matches (multiple files with same name) */
ambiguousMatches: "uses-first-match-found";
/** Circular reference detection for import/export chains */
circularReferences: "avoided-automatically";
}Example Error Output:
///ts:import=nonexistent-file
// File not found: nonexistent-file ///ts:import:generated
///ts:export=missing-directory
// Directory not found: missing-directory ///ts:export:generated