An increasing number of packages in the npm ecosystem use the package-browser-spec - GitHub - defunctzombie/package-browser-field-spec: Spec document for the 'browser' field in package.json - to differentiate between code intended for use in browsers vs. code for use in nodejs (along with other flavors).
As configured currently, the @forge/bundler webpack configuration leads to the use of browser settings when present, resulting in platform errors as those packages try to use browser-based objects/code that does not exist in the node/lambda environment.
One sample library that does this is OpenTelemetry which uses this pattern for all of their js libraries, but even the most basic uses it - e.g. opentelemetry-js/package.json at main · open-telemetry/opentelemetry-js · GitHub
Impact
This is a really difficult bug to figure out as it manifests as either Snapshotting errors, when the system is unable to find expected objects, or runtime errors. The developer is stuck scratching their head wondering why their server-side function is trying to access browser objects they never called. It creates an amazingly frustrating developer experience.
Workaround
This issue is fixed by manually editing @forge/bundler/out/webpack.js
, adding aliasFields: []
to the resolve
block near line 83.
In context:
node: {
__dirname: true
},
performance: false,
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
ADDED==> aliasFields: []
},
resolveLoader: {
modules: require.resolve.paths('babel-loader') || undefined
},
This is not sustainable as it does not work in CI/CD, and would better be the default I believe.
Recommended Fix
Since the bundler is only every targeting node and not the browser, setting aliasFields to an empty list should be the default.
Webpack config reference: Resolve | webpack
More webpack config docs on how/why packages target multiple environments - Package exports | webpack