Skip to content

CJS build emits class fields that break conservative bundlers (VTEX IO compatibility issue) #1608

@augustofarnese

Description

@augustofarnese

Context

I'm integrating algoliasearch v5 into a VTEX IO storefront environment.

VTEX’s build pipeline does not transpile node_modules and uses a parser that fails when encountering modern JavaScript syntax (specifically public class fields) inside CommonJS files.

This leads to build-time errors such as:
Module parse failed: Unexpected token

Example failing code from dist/common.cjs:

var AlgoliaError = class extends Error {
  name = "AlgoliaError";

While this syntax is valid modern JavaScript, VTEX’s bundler cannot parse class fields inside dependencies.

Root Cause

The current tsup configuration targets:

target: 'node14'

from getBaseNodeOptions

When targeting node14, esbuild preserves public class fields in the emitted CJS output.

Because VTEX parses .cjs files from node_modules without transpilation, the build fails at parse time.

Proposed Solution (Minimal and Safe)

Lower the target only for the CJS build to:

target: 'es2018'

This forces esbuild to downlevel public class fields into constructor assignments.

Current output (node14 target)

var AlgoliaError = class extends Error {
  name = "AlgoliaError";
  constructor(message, name) {
    super(message);

Output with target: 'es2018'

var AlgoliaError = class extends Error {
  constructor(message, name) {
    super(message);
    __publicField(this, "name", "AlgoliaError");
;

This change:

  • Removes class fields from the CJS output
  • Maintains full runtime compatibility
  • Does not affect the ESM build
  • Has minimal impact on bundle size
  • Significantly improves compatibility with conservative bundlers

Suggested Implementation

Modify the tsup.config.ts for the CJS build only:

{
  ...getBaseNodeOptions(pkg, __dirname),
  format: 'cjs',
  target: 'es2018',
  dts: { entry: { common: 'src/index.ts' } },
  entry: { common: 'src/index.ts' },
},

Keep the ESM target unchanged to preserve modern output.

Why This Matters

This small adjustment would:

  • Improve compatibility with environments that do not transpile node_modules
  • Prevent downstream consumers from needing to fork or patch the SDK
  • Maintain modern output for ESM users
  • Reduce friction in enterprise storefront environments like VTEX

On summary, this is not a request to change runtime behavior — only to adjust the CJS build target for broader bundler compatibility.

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions