Skip to content

Commit

Permalink
Add resolver.unstable_enableSymlinks and remove symlinks+watchman r…
Browse files Browse the repository at this point in the history
…estriction

Summary:
**Note: this change does not mean that symlinks are respected by the resolver (yet)!**

Add `resolver.unstable_enableSymlinks` (default: `false`) option to Metro config, and pass it though to the existing `enableSymlinks` option in `metro-file-map`.

At this point this is purely for ease of testing end-to-end behaviour as we incrementally change Fast Refresh and resolution to cope with symlinks.

Removes the Jest-inherited prohibition on using `enableSymlinks` with `useWatchman`, which is no longer necessary or relevant to the new implementation.

**Bikeshed: Why under `resolver`?**
Symlink support is mostly relevant to the resolver, in that if the resolver resolves to a file through a link, that fact is transparent to the rest of Metro. Third-party solutions for symlink-based projects have focused on the resolver. The fact that 90% of the work for this solution is within `metro-file-map` is an implementation detail of in-memory resolution. That said, we'll have an opportunity to revisit this when the config is promoted from `unstable_`

Changlog: [Experimental] - Add `resolver.unstable_enableSymlinks` config for first phase of symlink support.

Reviewed By: jacdebug

Differential Revision: D42552674

fbshipit-source-id: a6cfe38973b2a484af85f4a11274c4073710a883
  • Loading branch information
robhogan authored and facebook-github-bot committed Jan 18, 2023
1 parent 5ae4b0d commit ed55455
Show file tree
Hide file tree
Showing 6 changed files with 8 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Object {
],
},
"unstable_enablePackageExports": false,
"unstable_enableSymlinks": false,
"useWatchman": true,
},
"serializer": Object {
Expand Down Expand Up @@ -259,6 +260,7 @@ Object {
],
},
"unstable_enablePackageExports": false,
"unstable_enableSymlinks": false,
"useWatchman": true,
},
"serializer": Object {
Expand Down Expand Up @@ -435,6 +437,7 @@ Object {
],
},
"unstable_enablePackageExports": false,
"unstable_enableSymlinks": false,
"useWatchman": true,
},
"serializer": Object {
Expand Down Expand Up @@ -611,6 +614,7 @@ Object {
],
},
"unstable_enablePackageExports": false,
"unstable_enableSymlinks": false,
"useWatchman": true,
},
"serializer": Object {
Expand Down
1 change: 1 addition & 0 deletions packages/metro-config/src/configTypes.flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ type ResolverConfigT = {
disableHierarchicalLookup: boolean,
dependencyExtractor: ?string,
emptyModulePath: string,
unstable_enableSymlinks: boolean,
extraNodeModules: {[name: string]: string, ...},
hasteImplModulePath: ?string,
nodeModulesPaths: $ReadOnlyArray<string>,
Expand Down
1 change: 1 addition & 0 deletions packages/metro-config/src/defaults/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const getDefaultValues = (projectRoot: ?string): ConfigT => ({
blockList: exclusionList(),
dependencyExtractor: undefined,
disableHierarchicalLookup: false,
unstable_enableSymlinks: false,
emptyModulePath: require.resolve(
'metro-runtime/src/modules/empty-module.js',
),
Expand Down
38 changes: 1 addition & 37 deletions packages/metro-file-map/src/__tests__/index-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -510,48 +510,12 @@ describe('HasteMap', () => {
expect(deepNormalize(await hasteMap.read())).toEqual(cacheContent);
});

it('throws if both symlinks and watchman is enabled', () => {
expect(
() => new HasteMap({...defaultConfig, enableSymlinks: true}),
).toThrow(
'Set either `enableSymlinks` to false or `useWatchman` to false.',
);
expect(
() =>
new HasteMap({
...defaultConfig,
enableSymlinks: true,
useWatchman: true,
}),
).toThrow(
'Set either `enableSymlinks` to false or `useWatchman` to false.',
);

expect(
() =>
new HasteMap({
...defaultConfig,
enableSymlinks: false,
useWatchman: true,
}),
).not.toThrow();

expect(
() =>
new HasteMap({
...defaultConfig,
enableSymlinks: true,
useWatchman: false,
}),
).not.toThrow();
});

describe('builds a haste map on a fresh cache with SHA-1s', () => {
it.each([
// `enableSymlinks` is currently not permitted with `useWatchman`
[false, false],
[false, true],
[true, false],
[true, true],
])(
'uses watchman: %s, symlinks enabled: %s',
async (useWatchman, enableSymlinks) => {
Expand Down
8 changes: 0 additions & 8 deletions packages/metro-file-map/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -324,14 +324,6 @@ export default class HasteMap extends EventEmitter {
buildParameters,
});

if (this._options.enableSymlinks && this._options.useWatchman) {
throw new Error(
'metro-file-map: enableSymlinks config option was set, but ' +
'is incompatible with watchman.\n' +
'Set either `enableSymlinks` to false or `useWatchman` to false.',
);
}

this._buildPromise = null;
this._worker = null;
this._startupPerfLogger?.point('constructor_end');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ function createHasteMap(
computeDependencies,
computeSha1: true,
dependencyExtractor: config.resolver.dependencyExtractor,
enableSymlinks: config.resolver.unstable_enableSymlinks,
extensions: Array.from(
new Set([
...config.resolver.sourceExts,
Expand Down

0 comments on commit ed55455

Please sign in to comment.