Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: override module.createRequire #9469

Merged
merged 13 commits into from
Feb 1, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -364,21 +364,54 @@ describe('Runtime requireModule', () => {
expect(customRequire('./create_require_module').foo).toBe('foo');
}

// createRequire with URL
// createRequire with URL object
{
const customRequire = exports.createRequire(
pathToFileURL(runtime.__mockRootPath),
);
expect(customRequire('./create_require_module').foo).toBe('foo');
}

// createRequire with file URL string
{
const customRequire = exports.createRequire(
pathToFileURL(runtime.__mockRootPath).toString(),
);
expect(customRequire('./create_require_module').foo).toBe('foo');
}

// createRequire with absolute module path
{
const customRequire = exports.createRequire(runtime.__mockRootPath);
expect(customRequire('./create_require_module').foo).toBe('foo');
}

// createRequire with relative module path
expect(() => exports.createRequireFromPath('./relative/path')).toThrow(
new TypeError(
`[ERR_INVALID_ARG_VALUE] The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received './relative/path'`,
),
);

// createRequireFromPath with absolute module path
{
const customRequire = exports.createRequireFromPath(
runtime.__mockRootPath,
);
expect(customRequire('./create_require_module').foo).toBe('foo');
}

// createRequireFromPath with file URL object
expect(() =>
exports.createRequireFromPath(pathToFileURL(runtime.__mockRootPath)),
).toThrow(
new TypeError(
`[ERR_INVALID_ARG_VALUE] The argument 'filename' must be string. Received '${pathToFileURL(
runtime.__mockRootPath,
)}'. Use createRequire for URL filename.`,
),
);

expect(exports.syncBuiltinESMExports).not.toThrow();
expect(exports.builtinModules).toEqual(builtinModules);
}));
Expand Down
40 changes: 28 additions & 12 deletions packages/jest-runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -892,9 +892,17 @@ class Runtime {
const createRequire = (modulePath: string | URL) => {
const filename =
typeof modulePath === 'string'
? modulePath
? modulePath.startsWith('file:///')
? fileURLToPath(new URL(modulePath))
: modulePath
: fileURLToPath(modulePath);

if (!path.isAbsolute(filename)) {
throw new TypeError(
doniyor2109 marked this conversation as resolved.
Show resolved Hide resolved
`[ERR_INVALID_ARG_VALUE] The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received '${filename}'`,
);
}

return this._createRequireImplementation({
doniyor2109 marked this conversation as resolved.
Show resolved Hide resolved
children: [],
exports: {},
Expand All @@ -904,24 +912,32 @@ class Runtime {
});
};

const overriddenModule = {...nativeModule};
const overriddenModules: Partial<typeof nativeModule> = {};

if ('createRequire' in nativeModule) {
Object.defineProperty(overriddenModule, 'createRequire', {
value: createRequire,
});
overriddenModules.createRequire = createRequire;
}
if ('createRequireFromPath' in nativeModule) {
Object.defineProperty(overriddenModule, 'createRequireFromPath', {
value: (filename: string) => createRequire(filename),
});
overriddenModules.createRequireFromPath = (filename: string | URL) => {
if (typeof filename !== 'string') {
throw new TypeError(
`[ERR_INVALID_ARG_VALUE] The argument 'filename' must be string. Received '${filename}'.${
filename instanceof URL
? ' Use createRequire for URL filename.'
: ''
}`,
);
}
return createRequire(filename);
};
}
if ('syncBuiltinESMExports' in nativeModule) {
Object.defineProperty(overriddenModule, 'syncBuiltinESMExports', {
value: () => {},
});
overriddenModules.syncBuiltinESMExports = () => {};
}
return overriddenModule;

return Object.keys(overriddenModules).length > 0
? {...nativeModule, ...overriddenModules}
: nativeModule;
}

return require(moduleName);
Expand Down
7 changes: 6 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2164,7 +2164,12 @@
dependencies:
"@types/node" "*"

"@types/node@*", "@types/node@>= 8":
"@types/node@*":
version "13.7.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.0.tgz#b417deda18cf8400f278733499ad5547ed1abec4"
integrity sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ==

"@types/node@>= 8":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

roll back change here?

Copy link
Contributor Author

@doniyor2109 doniyor2109 Feb 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have upgraded @types/node to 13.7 because this version includes syncBuiltinESMExports in module.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reverted changes back. I just used another type

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh! I just didn't want 2 versions of it, could have deduped it to the newer ones. Lemme play with it locally. Thanks!

version "13.1.8"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.1.8.tgz#1d590429fe8187a02707720ecf38a6fe46ce294b"
integrity sha512-6XzyyNM9EKQW4HKuzbo/CkOIjn/evtCmsU+MUM1xDfJ+3/rNjBttM1NgN7AOQvN6tP1Sl1D1PIKMreTArnxM9A==
Expand Down