nx
Version:
96 lines (95 loc) • 4.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.unregisterPluginTSTranspiler = void 0;
exports.registerPluginTSTranspiler = registerPluginTSTranspiler;
exports.forceRegisterPluginTSTranspiler = forceRegisterPluginTSTranspiler;
exports.pluginTranspilerIsRegistered = pluginTranspilerIsRegistered;
exports.cleanupPluginTSTranspiler = cleanupPluginTSTranspiler;
const node_fs_1 = require("node:fs");
const posix_1 = require("node:path/posix");
const register_1 = require("../../plugins/js/utils/register");
const typescript_1 = require("../../plugins/js/utils/typescript");
const workspace_root_1 = require("../../utils/workspace-root");
exports.unregisterPluginTSTranspiler = null;
const NOOP = () => { };
/**
* Register swc-node or ts-node if they are not currently registered
* with some default settings which work well for Nx plugins.
*
* When the runtime supports native TypeScript stripping and the user hasn't
* opted out, this is a noop - Node loads plugin `.ts` files directly. The
* lazy fallback in `handleImport` will call `forceRegisterPluginTSTranspiler`
* if a plugin uses unsupported syntax (enum, runtime namespace, etc.).
*/
function registerPluginTSTranspiler() {
if (exports.unregisterPluginTSTranspiler !== null) {
return;
}
if ((0, register_1.isNativeStripPreferred)()) {
// Native strip handles `.ts` syntax but doesn't rewrite NodeNext-style
// `.js` relative specifiers to their `.ts` sources. Patch the CJS resolver
// so `require('./foo.js')` from a `.ts` plugin source falls back to
// `./foo.ts`, and register an ESM resolution hook so the same rewrite
// happens on the dynamic-import path (the CJS patch can't reach ESM
// resolution). Both are idempotent and best-effort.
(0, register_1.ensureCjsResolverPatched)();
(0, register_1.ensureNodeNextEsmResolverRegistered)();
// Sentinel so pluginTranspilerIsRegistered() reports true and callers
// don't keep retrying. The actual transpiler stays unregistered until
// a fallback forces it.
exports.unregisterPluginTSTranspiler = NOOP;
return;
}
doRegisterPluginTSTranspiler();
}
/**
* Always register swc-node or ts-node + tsconfig-paths, ignoring the native
* strip preference. Called from the fallback path in `handleImport` when a
* plugin `.ts` file throws `ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX` under native
* stripping.
*/
function forceRegisterPluginTSTranspiler() {
// If the previous registration was the native-strip sentinel, throw it
// out so we actually wire up swc/ts-node.
if (exports.unregisterPluginTSTranspiler === NOOP) {
exports.unregisterPluginTSTranspiler = null;
}
if (exports.unregisterPluginTSTranspiler !== null) {
return;
}
doRegisterPluginTSTranspiler();
}
function doRegisterPluginTSTranspiler() {
// Get the first tsconfig that matches the allowed set
const tsConfigName = [
(0, posix_1.join)(workspace_root_1.workspaceRoot, 'tsconfig.base.json'),
(0, posix_1.join)(workspace_root_1.workspaceRoot, 'tsconfig.json'),
].find((x) => (0, node_fs_1.existsSync)(x));
if (!tsConfigName) {
return;
}
const tsConfig = tsConfigName
? (0, typescript_1.readTsConfigWithoutFiles)(tsConfigName)
: {};
const cleanupFns = [
(0, register_1.registerTsConfigPaths)(tsConfigName),
(0, register_1.registerTranspiler)({
experimentalDecorators: true,
emitDecoratorMetadata: true,
...tsConfig.options,
}, tsConfig.raw),
];
// Fall back from NodeNext `.js` specifiers to their `.ts` sources when a
// `.ts` plugin source require()s a sibling. Idempotent.
(0, register_1.ensureCjsResolverPatched)();
exports.unregisterPluginTSTranspiler = () => {
cleanupFns.forEach((fn) => fn?.());
};
}
function pluginTranspilerIsRegistered() {
return exports.unregisterPluginTSTranspiler !== null;
}
function cleanupPluginTSTranspiler() {
(0, exports.unregisterPluginTSTranspiler)?.();
exports.unregisterPluginTSTranspiler = null;
}