Fastboot incompatible with modern state of the ecosystem
Issues:
- Expected globals are not present, such as
fetch,HeadersReadableStreametc. - ~
buildSandboxGlobalno longer runs, so there is no way to enhance the built in globals with WHATWG spec implementations of APIs such asAbortControllerandfetcheven when these things exist as globals in node.~ (this turned out to be a config mishap for ember-cli-fastboot-testing see https://github.com/embermap/ember-cli-fastboot-testing/issues/488) -
fastbootDependenciesdoes not allow whitelisting local dependencies, which prevents applications from addressing this shortcoming short of usingpnpm patchto splice in new globals. For instance the following fails to resolve withFastboot.require
{
"dependencies": {
"fastboot-abort-controller": "file:./fastboot-overrides/abort-controller"
},
"fastbootDependencies": [
"fastboot-abort-controller",
]
}
Example recommended config for use with EmberData and fetch
/* global ReadableStream, WritableStream, TransformStream */
module.exports = function (environment) {
return {
buildSandboxGlobals(defaultGlobals) {
return Object.assign({}, defaultGlobals, {
AbortController,
fetch: fetch,
ReadableStream:
typeof ReadableStream !== 'undefined' ? ReadableStream : require('node:stream/web').ReadableStream,
WritableStream:
typeof WritableStream !== 'undefined' ? WritableStream : require('node:stream/web').WritableStream,
TransformStream:
typeof TransformStream !== 'undefined' ? TransformStream : require('node:stream/web').TransformStream,
Headers: typeof Headers !== 'undefined' ? Headers : undefined,
});
},
};
};
AFAIK there's no reason to use Fastboot.require anymore, because ember-auto-import and embroider both allow you to import dependencies and keep those working in both browser and fastboot.
It was only needed in the era when apps didn't normally import NPM dependencies. It makes no sense as an API anymore.
Both embroider and ember-auto-import test under fastboot to make sure this works.
@ef4 are you saying that ember-auto-import allows you to require any node (not browser) module? This seems suspect, because for instance import fetch from "node:fetch" isn't valid unless you are in a Fastboot context, but if this works there's probably a bunch of docs updates to do 😅
Oh yeah, no, I don't mean node built-ins or packages with native binaries will work both ways.
But even for those you can manage the swap between them with embroider/macros. That's actually what embroider does internally when we encounter classical fastboot directories that are intended to override a module only in fastboot.