Developers diving into Shopify's Hydrogen framework often appreciate its
innovative approach to building custom storefronts using React. However, an
aspect that can catch many off guard is that the Shopify's
Oxygen runtime environment
does not include a traditional Node.js environment. Oxygen use a worker-based
Javascript runtime that is built on
Cloudflare's workerd library. While Shopify has implemented some standard and critical functionality like
the
Fetch API, the fetch method, and the
Web Crypto API, some third party dependencies may throw errors about missing core packages.
The documentation has a full list of implemented features. This limitation can introduce various bugs and compatibility issues,
especially for those accustomed to Node's extensive
ecosystem.
One common issue developers face is the absence of core Node modules like
path
and fs
. Many third-party libraries rely on these modules, and their
absence in the Hydrogen runtime can lead to unexpected errors and broken
functionality. For instance, a library designed to handle file operations
might throw an error because it cannot access the fs
module.
To tackle these issues, one effective solution is to use
polyfills. Polyfills are code that provide the functionality of missing features,
enabling developers to bridge the gap between environments. For instance, the
path
module, which is used for handling and transforming file
paths, can be polyfilled using packages like path-browserify
. The
latest versions of Remix allow both server side and browser side Node module
polyfills to be configured simply by name in the
remix.config.js
file in the project root using the
serverNodeBuiltinsPolyfill option.
/** @type {import('@remix-run/dev').AppConfig} */
module.exports = {
serverNodeBuiltinsPolyfill: {
modules: {
buffer: true, // Provide a JSPM polyfill
fs: "empty", // Provide an empty polyfill
},
globals: {
Buffer: true,
},
},
};
Beyond polyfilling, another strategy would be to abstract the incompatible functionality to serverless functions that can support the missing packages. AWS Lambda for example.