UNPKG

@backstage/cli

Version:

CLI for developing Backstage plugins and apps

88 lines (79 loc) 2.93 kB
/* * Copyright 2024 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const { pathToFileURL } = require('url'); const { transformSync } = require('@swc/core'); const { addHook } = require('pirates'); const { Module } = require('module'); // This hooks into module resolution and overrides imports of packages that // exist in the linked workspace to instead be resolved from the linked workspace. if (process.env.BACKSTAGE_CLI_LINKED_WORKSPACE) { const { join: joinPath } = require('path'); const { getPackagesSync } = require('@manypkg/get-packages'); const { packages: linkedPackages, root: linkedRoot } = getPackagesSync( process.env.BACKSTAGE_CLI_LINKED_WORKSPACE, ); // Matches all packages in the linked workspaces, as well as sub-path exports from them const replacementRegex = new RegExp( `^(?:${linkedPackages .map(pkg => pkg.packageJson.name) .join('|')})(?:/.*)?$`, ); const origLoad = Module._load; Module._load = function requireHook(request, parent) { if (!replacementRegex.test(request)) { return origLoad.call(this, request, parent); } // The package import that we're overriding will always existing in the root // node_modules of the linked workspace, so it's enough to override the // parent paths with that single entry return origLoad.call(this, request, { ...parent, paths: [joinPath(linkedRoot.dir, 'node_modules')], }); }; } addHook( (code, filename) => { const transformed = transformSync(code, { filename, sourceMaps: 'inline', module: { type: 'commonjs', ignoreDynamic: true, }, jsc: { target: 'es2022', parser: { syntax: 'typescript', }, }, }); process.send?.({ type: 'watch', path: filename }); return transformed.code; }, { extensions: ['.ts', '.cts'], ignoreNodeModules: true }, ); addHook( (code, filename) => { process.send?.({ type: 'watch', path: filename }); return code; }, { extensions: ['.js', '.cjs'], ignoreNodeModules: true }, ); // Register module hooks, used by "type": "module" in package.json, .mjs and // .mts files, as well as dynamic import(...)s, although dynamic imports will be // handled be the CommonJS hooks in this file if what it points to is CommonJS. Module.register('./nodeTransformHooks.mjs', pathToFileURL(__filename));