I use this patch to allow Bun to run vue-tsc. This creates a copy of TSC instead of monkey patching the FS methods. I feel monkey patching the FS library isn't the right idea anyway.
diff --git a/lib/quickstart/runTsc.js b/lib/quickstart/runTsc.js
index 9de27714a40531e5b1ade7e0686c937a327a8d38..a36c9ab1f2ae373f36f274738df7753c3da4beea 100644
--- a/lib/quickstart/runTsc.js
+++ b/lib/quickstart/runTsc.js
@@ -20,33 +20,55 @@ function runTsc(tscPath, options, _getLanguagePlugins, typescriptObject) {
extraExtensionsToRemove = options.extraExtensionsToRemove;
}
const proxyApiPath = require.resolve('../node/proxyCreateProgram');
- const readFileSync = fs.readFileSync;
- fs.readFileSync = (...args) => {
- if (args[0] === tscPath) {
- let tsc = readFileSync(...args);
- try {
- return transformTscContent(tsc, proxyApiPath, extraSupportedExtensions, extraExtensionsToRemove, __filename, typescriptObject);
+
+ // Alternative approach: Write transformed content to temp file in same directory
+ // This preserves TypeScript's library resolution while working in both Node.js and Bun
+ const crypto = require('crypto');
+
+ try {
+ // Read the original tsc file
+ let tscContent = fs.readFileSync(tscPath, 'utf8');
+ let actualTscPath = tscPath;
+
+ // Handle tsc shim (TypeScript 5.7+)
+ try {
+ const transformed = transformTscContent(tscContent, proxyApiPath, extraSupportedExtensions, extraExtensionsToRemove, __filename, typescriptObject);
+ tscContent = transformed;
+ }
+ catch {
+ // Support the tsc shim used in Typescript v5.7 and up
+ const requireRegex = /module\.exports\s*=\s*require\((?:"|')(?<path>\.\/\w+\.js)(?:"|')\)/;
+ const requirePath = requireRegex.exec(tscContent)?.groups?.path;
+ if (requirePath) {
+ actualTscPath = path.join(path.dirname(tscPath), requirePath);
+ tscContent = fs.readFileSync(actualTscPath, 'utf8');
+ tscContent = transformTscContent(tscContent, proxyApiPath, extraSupportedExtensions, extraExtensionsToRemove, __filename, typescriptObject);
}
- catch {
- // Support the tsc shim used in Typescript v5.7 and up
- const requireRegex = /module\.exports\s*=\s*require\((?:"|')(?<path>\.\/\w+\.js)(?:"|')\)/;
- const requirePath = requireRegex.exec(tsc)?.groups?.path;
- if (requirePath) {
- tsc = readFileSync(path.join(path.dirname(tscPath), requirePath), 'utf8');
- return transformTscContent(tsc, proxyApiPath, extraSupportedExtensions, extraExtensionsToRemove, __filename, typescriptObject);
- }
- else {
- throw new Error('Failed to locate tsc module path from shim');
- }
+ else {
+ throw new Error('Failed to locate tsc module path from shim');
+ }
+ }
+
+ // Write transformed content to same directory to preserve relative paths for lib files
+ const hash = crypto.createHash('md5').update(actualTscPath + Date.now()).digest('hex').substring(0, 8);
+ const parsedPath = path.parse(actualTscPath);
+ const tempPath = path.join(parsedPath.dir, `${parsedPath.name}.volar-${hash}${parsedPath.ext}`);
+ fs.writeFileSync(tempPath, tscContent, 'utf8');
+
+ try {
+ return require(tempPath);
+ }
+ finally {
+ // Clean up
+ delete require.cache[tempPath];
+ try {
+ fs.unlinkSync(tempPath);
+ } catch {
+ // Ignore cleanup errors
}
}
- return readFileSync(...args);
- };
- try {
- return require(tscPath);
}
finally {
- fs.readFileSync = readFileSync;
delete require.cache[tscPath];
}
}
I use this patch to allow Bun to run vue-tsc. This creates a copy of TSC instead of monkey patching the FS methods. I feel monkey patching the FS library isn't the right idea anyway.