Support modern ESM dependencies (e.g. @texel/color)#32
Open
mattdesl wants to merge 1 commit into
Open
Conversation
Importing a package authored as native ES modules (e.g.
`import { convert } from "@texel/color"`) previously failed with
"'import' and 'export' may appear only with 'sourceType: module'".
The bundler used esmify with `nodeModules: false`, so ESM published to
node_modules was never converted to CommonJS for browserify. Even with
that flag flipped, browserify's parser (an older acorn via module-deps)
can't read modern operators like `??` and `?.` that such packages use.
This adds a narrowly-scoped esbuild transform that runs over node_modules
files only:
- converts import/export to CommonJS so browserify can bundle them
- lowers just the operators the parser can't read (target es2019), and
keeps non-ASCII identifiers literal (charset utf8)
It is NOT a transpile-to-ES5 step: modern syntax (classes, async/await,
arrow fns, spread, etc.) is preserved. Local source is still handled by
esmify, which keeps the static-require analysis that glslify/brfs rely on,
so no existing behavior changes. Build and dev-server paths, glslify, env
injection, CJS deps, source maps and minification all continue to work.
Adds a test covering bundling of a modern ESM-only dependency.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Importing a package authored as native ES modules fails today:
The CLI runs
esmifywithnodeModules: false, so ESM published tonode_modulesis never converted to CommonJS for browserify. And even with that flag flipped, browserify's parser (an olderacornviamodule-deps) can't read modern operators like??and?.that such packages use —@texel/colorhits both (core.jsuses??, other files use non-ASCII identifiers likelet ε = …).Approach
Rather than rip out browserify/budo (which would risk the dev server, hot reload, glslify static analysis, and instrumentation), this adds a narrowly-scoped esbuild transform that only touches
node_modules— which currently isn't transformed at all, so the change is purely additive:import/export→ CommonJS so browserify can bundle the dependencytarget: es2019) and keeps non-ASCII identifiers literal (charset: utf8)import/export/??/?.)This is not a transpile-to-ES5 step. Modern syntax (classes, async/await, arrow functions, spread, template literals, destructuring, …) is preserved — only what the parser literally can't read is lowered.
Local source is untouched and still handled by
esmify, which preserves the static-requireanalysis thatglslify/brfsdepend on. So no existing behavior changes.Verified
import { convert, sRGB, OKLCH } from "@texel/color"now bundles and runs (both the--buildpath and the budo dev server)import, aglslifytemplate tag (#define GLSLIFY 1still injected ✓), a CJS dep (canvas-sketch), and the ESM dep all bundle together correctlyChanges
src/plugins/transform-esbuild.js— new node_modules-only esbuild transformsrc/index.js— register the transform as a global (-g) browserify transformpackage.json— addesbuilddependencytest/test-esm-deps.js+ fixture — coverage for bundling an ESM-only dephttps://claude.ai/code/session_01K5PbUnmY8T48tcRZ7VL6cq
Generated by Claude Code