mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Alternative to #23254 Our build script has a custom plugin to resolve internal module forks. Currently, it uses require.resolve to resolve the path to a real file on disk. Instead, I've updated all the forked module paths to match their location on disk, relative to the project root, to remove the need to resolve them in the build script's runtime. The main motivation is because require.resolve doesn't work with ESM modules, but aside from that, hardcoding the relative paths is more predictable — the Node module resolution algorithm is complicated, and we don't really need its features for this purpose.
89 lines
2.7 KiB
JavaScript
89 lines
2.7 KiB
JavaScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
'use strict';
|
|
|
|
const path = require('path');
|
|
const semver = require('semver');
|
|
|
|
function resolveRelatively(importee, importer) {
|
|
if (semver.gte(process.version, '8.9.0')) {
|
|
return require.resolve(importee, {
|
|
paths: [path.dirname(importer)],
|
|
});
|
|
} else {
|
|
// `paths` argument is not available in older Node.
|
|
// This works though.
|
|
// https://github.com/nodejs/node/issues/5963
|
|
const Module = require('module');
|
|
return Module._findPath(importee, [
|
|
path.dirname(importer),
|
|
...module.paths,
|
|
]);
|
|
}
|
|
}
|
|
|
|
let resolveCache = new Map();
|
|
function useForks(forks) {
|
|
let resolvedForks = new Map();
|
|
Object.keys(forks).forEach(srcModule => {
|
|
// Fork paths are relative to the project root. They must include the full
|
|
// path, including the extension. We intentionally don't use Node's module
|
|
// resolution algorithm because 1) require.resolve doesn't work with ESM
|
|
// modules, and 2) the behavior is easier to predict.
|
|
const targetModule = forks[srcModule];
|
|
resolvedForks.set(
|
|
path.resolve(process.cwd(), srcModule),
|
|
// targetModule could be a string (a file path),
|
|
// or an error (which we'd throw if it gets used).
|
|
// Don't try to "resolve" errors, but cache
|
|
// resolved file paths.
|
|
typeof targetModule === 'string'
|
|
? path.resolve(process.cwd(), targetModule)
|
|
: targetModule
|
|
);
|
|
});
|
|
return {
|
|
name: 'scripts/rollup/plugins/use-forks-plugin',
|
|
resolveId(importee, importer) {
|
|
if (!importer || !importee) {
|
|
return null;
|
|
}
|
|
if (importee.startsWith('\u0000')) {
|
|
// Internal Rollup reference, ignore.
|
|
// Passing that to Node file functions can fatal.
|
|
return null;
|
|
}
|
|
let resolvedImportee = null;
|
|
let cacheKey = `${importer}:::${importee}`;
|
|
if (resolveCache.has(cacheKey)) {
|
|
// Avoid hitting file system if possible.
|
|
resolvedImportee = resolveCache.get(cacheKey);
|
|
} else {
|
|
try {
|
|
resolvedImportee = resolveRelatively(importee, importer);
|
|
} catch (err) {
|
|
// Not our fault, let Rollup fail later.
|
|
}
|
|
if (resolvedImportee) {
|
|
resolveCache.set(cacheKey, resolvedImportee);
|
|
}
|
|
}
|
|
if (resolvedImportee && resolvedForks.has(resolvedImportee)) {
|
|
// We found a fork!
|
|
const fork = resolvedForks.get(resolvedImportee);
|
|
if (fork instanceof Error) {
|
|
throw fork;
|
|
}
|
|
return fork;
|
|
}
|
|
return null;
|
|
},
|
|
};
|
|
}
|
|
|
|
module.exports = useForks;
|