chai: mutating chai exports no longer works in v5
As raised in chaijs/chai-http#310, the move to ESM actually had another breaking change we didn’t catch
in the past, you could do something like this:
const chai = require('chai');
chai.use((ex) => {
ex['oogabooga'] = 303;
});
chai.oogabooga; // 303
of course, in es modules, this will no longer work:
import * as chai from 'chai';
chai.oogabooga = 303; // TypeError, object is not extensible
chai.use((ex) => {
ex['oogabooga'] = 303; // works but doesn't mutate `chai`
});
chai.oogabooga; // undefined
we can’t really ‘fix’ this. imports are immutable objects when using *, so we can’t just stick things onto the end.
it means we probably need to make a decision of what the ‘new way’ of doing this is. some suggestions:
- require that consumers do something like
chai = chaiOriginal.use(foo).use(bar); - introduce some kind of
chai.extensions, a mutable object we store these things in
About this issue
- Original URL
- State: open
- Created 6 months ago
- Reactions: 4
- Comments: 22 (10 by maintainers)
Commits related to this issue
- #0: fix chai import for chai-files relates to chaijs/chai/issues/1569 — committed to Accenture/sfmc-devtools by JoernBerkefeld 5 months ago
it is pretty much convenience, because people used to import chai as a default import (
const chai = require(...)).this just doesn’t work in esm anymore without exporting a
chaiconst, which we shouldn’t really do imo.so my suggestion is to just recommend the
chai = chai.use(...)pattern.otherwise, i think we end up with something like
chai.ext.mypluginI confirm, this drives me crazy. I downgrade back to v4.
@keithamus I have indeed been able to use your guidance to fix my issue with it! Thank you for that! It took less effort than I thought it would in the end.
FWIW this only impacts objects attached to the chai context from within a plugin. Regular assertions are attached to the Assertion prototype which is mutable in the module record. So only plugins which come with an additional “global” objects are effected. Those plugins can expose those objects as part of their module records, and we can also establish a convention that people should either import those objects from those libraries, or destructure the return value of the
use()call. For examplechai-http(an impacted plugin):OR
We can, as @43081j states, also add an object that is exported to simplify for other modules, so they don’t need to repeat the
usecalls or additional imports between files:@43081j done, see #1603
Thank you!
We’re all the author/maintainer of this software. You can make a PR to update the docs ❤️