main
js 88 lines 2.71 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7 'use strict';
8
9 const path = require('path');
10 const semver = require('semver');
11
12 function resolveRelatively(importee, importer) {
13 if (semver.gte(process.version, '8.9.0')) {
14 return require.resolve(importee, {
15 paths: [path.dirname(importer)],
16 });
17 } else {
18 // `paths` argument is not available in older Node.
19 // This works though.
20 // https://github.com/nodejs/node/issues/5963
21 const Module = require('module');
22 return Module._findPath(importee, [
23 path.dirname(importer),
24 ...module.paths,
25 ]);
26 }
27 }
28
29 let resolveCache = new Map();
30 function useForks(forks) {
31 let resolvedForks = new Map();
32 Object.keys(forks).forEach(srcModule => {
33 // Fork paths are relative to the project root. They must include the full
34 // path, including the extension. We intentionally don't use Node's module
35 // resolution algorithm because 1) require.resolve doesn't work with ESM
36 // modules, and 2) the behavior is easier to predict.
37 const targetModule = forks[srcModule];
38 resolvedForks.set(
39 path.resolve(process.cwd(), srcModule),
40 // targetModule could be a string (a file path),
41 // or an error (which we'd throw if it gets used).
42 // Don't try to "resolve" errors, but cache
43 // resolved file paths.
44 typeof targetModule === 'string'
45 ? path.resolve(process.cwd(), targetModule)
46 : targetModule
47 );
48 });
49 return {
50 name: 'scripts/rollup/plugins/use-forks-plugin',
51 resolveId(importee, importer) {
52 if (!importer || !importee) {
53 return null;
54 }
55 if (importee.startsWith('\u0000')) {
56 // Internal Rollup reference, ignore.
57 // Passing that to Node file functions can fatal.
58 return null;
59 }
60 let resolvedImportee = null;
61 let cacheKey = `${importer}:::${importee}`;
62 if (resolveCache.has(cacheKey)) {
63 // Avoid hitting file system if possible.
64 resolvedImportee = resolveCache.get(cacheKey);
65 } else {
66 try {
67 resolvedImportee = resolveRelatively(importee, importer);
68 } catch (err) {
69 // Not our fault, let Rollup fail later.
70 }
71 if (resolvedImportee) {
72 resolveCache.set(cacheKey, resolvedImportee);
73 }
74 }
75 if (resolvedImportee && resolvedForks.has(resolvedImportee)) {
76 // We found a fork!
77 const fork = resolvedForks.get(resolvedImportee);
78 if (fork instanceof Error) {
79 throw fork;
80 }
81 return fork;
82 }
83 return null;
84 },
85 };
86 }
87
88 module.exports = useForks;