index.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. "use strict";
  2. const assert = require("assert");
  3. function findModuleNotFound(err, name) {
  4. // Check the first line of the error message
  5. const msg = err.message.split("\n")[0];
  6. return msg && (
  7. // Check for "Cannot find module 'foo'"
  8. msg.includes(`'${name}'`)
  9. // Check for "Your application tried to access foo (a peer dependency) ..." (Yarn v2 PnP)
  10. // https://github.com/yarnpkg/berry/blob/e81dc0d29bb2f41818d9c5c1c74bab1406fb979b/packages/yarnpkg-pnp/sources/loader/makeApi.ts#L680
  11. || msg.includes(` ${name} `)
  12. // Check for "Your application tried to access foo. While ..." (Yarn v2 PnP)
  13. // https://github.com/yarnpkg/berry/blob/e81dc0d29bb2f41818d9c5c1c74bab1406fb979b/packages/yarnpkg-pnp/sources/loader/makeApi.ts#L704
  14. || msg.includes(` ${name}. `)
  15. // Check for "Your application tried to access foo, but ..." (Yarn v2 PnP)
  16. // https://github.com/yarnpkg/berry/blob/e81dc0d29bb2f41818d9c5c1c74bab1406fb979b/packages/yarnpkg-pnp/sources/loader/makeApi.ts#L718
  17. || msg.includes(` ${name}, `)
  18. );
  19. }
  20. function _optionalRequire(callerRequire, resolve, path, message) {
  21. let opts;
  22. if (typeof message === "object") {
  23. opts = message;
  24. assert(
  25. !(opts.hasOwnProperty("notFound") && opts.hasOwnProperty("default")),
  26. "optionalRequire: options set with both `notFound` and `default`"
  27. );
  28. } else {
  29. opts = { message };
  30. }
  31. try {
  32. return resolve ? callerRequire.resolve(path) : callerRequire(path);
  33. } catch (e) {
  34. if (e.code !== "MODULE_NOT_FOUND" || !findModuleNotFound(e, path)) {
  35. // if the module we are requiring fail because it try to require a
  36. // module that's not found, then we have to report this as failed.
  37. if (typeof opts.fail === "function") {
  38. return opts.fail(e);
  39. }
  40. throw e;
  41. }
  42. if (opts.message) {
  43. const message = typeof opts.message === "string" ? `${opts.message} - ` : "";
  44. const r = resolve ? "resolved" : "found";
  45. optionalRequire.log(`${message}optional module not ${r}`, path);
  46. }
  47. if (typeof opts.notFound === "function") {
  48. return opts.notFound(e);
  49. }
  50. return opts.default;
  51. }
  52. }
  53. const tryRequire = (callerRequire, path, message) => _optionalRequire(callerRequire, false, path, message);
  54. const tryResolve = (callerRequire, path, message) => _optionalRequire(callerRequire, true, path, message);
  55. function optionalRequire(callerRequire) {
  56. const x = (path, message) => tryRequire(callerRequire, path, message);
  57. x.resolve = (path, message) => tryResolve(callerRequire, path, message);
  58. return x;
  59. }
  60. optionalRequire.try = tryRequire;
  61. optionalRequire.tryResolve = tryResolve;
  62. optionalRequire.resolve = tryResolve;
  63. optionalRequire.log = (message, path) => console.log(`Just FYI: ${message}; Path "${path}"`);
  64. module.exports = optionalRequire;