-
Notifications
You must be signed in to change notification settings - Fork 72
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
fix(compartment-mapper): Defer all importHook errors when importing a… #2610
Conversation
… dependency if they're intended to be deferred
return deferError( | ||
moduleSpecifier, | ||
Error( | ||
throw Error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
returning instead of throwing could be slightly more performant
@@ -502,89 +502,88 @@ export const makeImportHookMaker = ( | |||
// for lint rule | |||
await null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw Error( | ||
`Cannot find file for internal module ${q( | ||
moduleSpecifier, | ||
)} (with candidates ${candidates | ||
.map(x => q(x)) | ||
.join(', ')}) in package ${packageLocation}`, | ||
), | ||
); | ||
); | ||
} catch (error) { | ||
return deferError(moduleSpecifier, error); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO this should probably just return the deferError
instead of throwing and catching it immediately, but if there's a good reason for doing this then ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no good reason, just being DRY/consistent. Didn't feel good doing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this would cause missing exits to be discovered much later, I would like this to be enabled with an option. Otherwise, this is well-motivated and I’m in favor.
@kriskowal Reconsider? This looks like a bugfix to me. |
For CJS compat, the top-level `this` must be equal to `module.exports` (which must be equal to `exports`). This implementation changes the CJS parsers to call the wrapper `functor` using the context of `module.exports`. (This PR targets #2610)
For CJS compat, the top-level `this` must be equal to `module.exports` (which must be equal to `exports`). This implementation changes the CJS parsers to call the wrapper `functor` using the context of `module.exports`. (This PR targets #2610)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see it now, thanks. More errors are caught, but those are released again for non-heuristic parsers. This only changes behavior for heuristic parsers.
Consider adding to NEWS. |
For CJS compat, the top-level `this` must be equal to `module.exports` (which must be equal to `exports`). This implementation changes the CJS parsers to call the wrapper `functor` using the context of `module.exports`. (This PR targets #2610)
# By Turadg Aleahmad (11) and others # Via GitHub (4) and Kris Kowal (1) * master: docs(ses): Finish embracing permits terminology fix(ses): Clarify lockdown types feat(ses): Lockdown reporting option chore(deps): yarn dedupe chore(types): fix import tags lint: enable jsdoc/recommended-typescript-flavor chore: rm dup config key chore(deps): bump eslint-plugin-jsdoc build(deps): bump typescript (patch) chore(types): conform to verbatimModuleSyntax ci: enable verbatimModuleSyntax style: prettier chore(deps): bump prettier build(deps): bump yarn to 4.5.1 feat(compartment-mapper): Collect unretained module descriptors test(compartment-mapper): Mark and sweep unused module descriptors feat(ses): permit Promise.prototype.try (#2609) # Conflicts: # packages/compartment-mapper/NEWS.md
For CJS compat, the top-level `this` must be equal to `module.exports` (which must be equal to `exports`). This implementation changes the CJS parsers to call the wrapper `functor` using the context of `module.exports`. (This PR targets #2610)
I've updated and added a blurb to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With request for qualification in NEWS.
For CJS compat, the top-level `this` must be equal to `module.exports` (which must be equal to `exports`). This implementation changes the CJS parsers to call the wrapper `functor` using the context of `module.exports`. (This PR targets #2610)
For CJS compat, the top-level `this` must be equal to `module.exports` (which must be equal to `exports`). This implementation changes the CJS parsers to call the wrapper `functor` using the context of `module.exports`. (This PR targets #2610)
… dependency if they're intended to be deferred
Description
When importHook is used to load dependencies, they might be coming from
imports
that were identified by a parser that uses heuristics to find them. (e.g. cjs parser implementation uses a lexer to find allrequire
calls even if they're not the require function but a local require function)In such cases we want to defer loading errors to runtime, so the error doesn't happen until actual
require
is actually called to get it.That was true for loading known dependency, but exit modules (via exitModuleImportHook) were not covered.
Security Considerations
no changes security-wise
Scaling Considerations
The way this is currently implemented - one big try-catch instead of returning the deferred error without throwing and catching, might be less performant. Should we consider trading aesthetics for a tiny performance gain here?
Note this only makes a difference for cases where non-dynamic
require
is called on a specifier that causes an error.Documentation Considerations
It's a fix of unintended behavior. No changes to what needs to be documented.
Testing Considerations
Fix was added test-first
Compatibility Considerations
Compatibility is improved. Packages can now do:
to silently attempt to load something that is only useful in their own development process. (typescript does that)
Upgrade Considerations
While it's a fix, not a breaking change, it does change one specific behavior - an error resulting from calling exitModuleImportHook (the
importHook
passed to compartment-mapper, not the one in Compartment options) is now thrown at runtime, not during loading, which could be noteworthy for the Archive use-case.(insert mandatory xkcd about breaking changes)