Nothing was removed or renamed. Two defaults moved, though - the first two entries below are what
to read before upgrading.
- behaviour change: a scoped library is now handed a
<script>element of its own to be found
by. While it runs,document.currentScriptanswers with an inert element carrying the library's
real url, and that element stays in the document where the older
getElementsByTagName('script')idiom finds it too. Libraries derive their base url this way -
amcharts-core.jscould not load at all without it, sincecurrentScriptis null inside an
evaland the fallback found the page's own inline script. On by default, becausenullis not
a neutral answer: a library that asks and gets nothing falls through to a worse heuristic or
crashes, and one that never asks cannot tell the difference.scriptElement: falseturns it
off. The element'stypeis not a JS MIME type, so it is never fetched or executed, and the
currentScriptoverride is unwound as soon as the library's synchronous run ends - the host
page's own scripts never see it. Libraries out of a bundle get one too: nothing fetches them, so
loadasks the registry where they would have come from. See doc/no-iframe.md. - behaviour change: the string form of
registry( which is also the default,/assets/lib/)
built its path fromname/version/pathand ignored a lib's ownurl, while_reftakes
the registry's answer over whatever the lib carried - sonew rescope!loading{url: '...'}
fetched/assets/lib/undefined/main/index.min.jsand 404'd. A lib given a url now keeps it. A
function registry could always express this itself and every caller of one already did
(({url, name}) -> url or ...); this is the same rule for the form that could not. - no longer create an iframe just to read a pristine list of window property names.
proxinnow
classifies the target window's own property descriptors instead, which was verified to give the
same answer ( 1211 names against the iframe's 1192, the only platform name missed being
chrome, now inproxin.native-extra). loading six libraries went from 18 iframes to 6. - the peek window is created on demand and reused, so a page that never needs one never gets one.
bundlenow records each library's export names asprop. a page loading such a bundle knows
them up front, so it skips the peek entirely: no iframe, and each library runs once instead of
twice. measured: six libraries from a bundle, zero iframes. an older rescope ignores the field
and peeks as it always did, so bundles stay readable both ways.- add
scope: 'with'. the library runs insidewith(scope), so every free identifier -var
declarations included - resolves through the proxy. no peek, no iframe at all, and the host
page's own globals stop leaking into scoped code (window.parentno longer reaches the real
window either ). costs library run time - roughly 3x on amomentformat loop - so it is
opt-in. see doc/no-iframe.md. - add
delivery: 'script'. the wrapper is handed to a script element through a blob instead of
being compiled, so CSP sees a script load rather thaneval. combined withscope: 'with'or
a bundle that carriesprop, rescope runs with no'unsafe-eval'grant at all - verified under
nonce+strict-dynamicand underscript-src 'self' 'unsafe-inline' blob:. - generated wrappers now carry
//# sourceURLand are compiled with an indirectevalrather
than theFunctionconstructor, which prepended a header and shifted every reported line by
two. a library throwing from its line 4 now reportslib.js:4:9- the same as if it had been
loaded with a plain<script src>, down to the column, and confirmed againstwindow.onerror's
ownfilename/lineno/colnorather than against a parsed stack string. devtools
registers it as a real source, so breakpoints survive a reload and the library's own
sourceMappingURL resolves against the real library url rather than against ablob:one. what
that map then points at is a half-step behind: line numbers match, but the wrapper's prologue
shares the library's first line, so every column mapped on line 1 - which is every column of a
minified file - is off by the prologue's length. see README's Source Maps section. - the peek's
evalcarries the samesourceURL. the peek runs a library before the wrapper
does, so a library that throws while loading throws out of the peek, and that is the trace
the caller gets - it used to name rescope's own file with no line of the library's in it. - fix bug: intrinsics were handed out as bound wrappers, so
global.Object === Objectwas false.
libraries fingerprint their global that way; lodash concluded it had not been given a real
global, fell back toFunction('return this')(), and installed itself on the host page -
overwriting the page's ownwindow._- whileloadrejected withTypeError: Expected a function. lodash now loads, in the browser and under jsdom. - fix bug:
_wraprestored the host window's globals after the library's code, so a library that
threw skipped every restore and left them blanked. the restores are in afinallynow. - fix bug:
__winwas assigned withoutvarin the generated wrapper, making it a global on the
real window. - fix bug:
_exportsdroppedctxin its recursive call, so only the first library's props ever
reached the caller's dual-context. - fix bug: reading a function off the proxy failed when
Reflect.getdeclines to answer for a
foreign receiver, which is how jsdom implements its interface objects. - fix bug: the generated wrapper continued on the same line as the library's last one, so a
minified file ending in//# sourceMappingURL=...with no trailing newline had everything
after it commented out - an unterminatedtry, or a lostreturn. found bymomentunder
jsdom. - add a regression suite:
./build && npm test. see test/README.md.