Skip to content

Switch to ESM#2138

Open
kibertoad wants to merge 14 commits intohandlebars-lang:masterfrom
kibertoad:feat/switch-to-esm
Open

Switch to ESM#2138
kibertoad wants to merge 14 commits intohandlebars-lang:masterfrom
kibertoad:feat/switch-to-esm

Conversation

@kibertoad
Copy link
Copy Markdown
Contributor

  • Drop support for legacy formats like CJS/AMD/UMD
  • Convert everything relevant to ESM (grunt part will be dropped together with another PR)

@kibertoad
Copy link
Copy Markdown
Contributor Author

kibertoad commented Mar 19, 2026

we need to convert parser package first (handlebars-lang/handlebars-parser#30)

@kibertoad kibertoad marked this pull request as draft March 19, 2026 22:25
@jaylinski
Copy link
Copy Markdown
Member

we need to convert parser package first (handlebars-lang/handlebars-parser#30)

Hm... it already exports modules as ESM, why doesn't this work?

@@ -1,12 +0,0 @@
import Handlebars from 'handlebars/runtime';
import hbs from 'handlebars-inline-precompile';
import { assertEquals } from '../../webpack-test/src/lib/assert';
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a niche pattern that seems to be already dead, https://www.npmjs.com/package/@roundingwellos/babel-plugin-handlebars-inline-precompile has only 80 weekly downloads (and it doesn't work with ESM)

@kibertoad kibertoad marked this pull request as ready for review March 22, 2026 14:12
@kibertoad
Copy link
Copy Markdown
Contributor Author

@jaylinski finally ready for the review!

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR completes a broad ESM migration across the package (including build/test tooling), while removing legacy CJS/AMD/UMD-related assets and expectations.

Changes:

  • Switch the published package to ESM (type: "module") and define explicit exports for main + runtime entrypoints.
  • Convert build/test configs and task scripts to ESM; remove AMD/CJS/UMD integration paths and fixtures.
  • Introduce a conditional #source-node implementation to keep source-map support workable across Node vs browser bundling.

Reviewed changes

Copilot reviewed 76 out of 85 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
vitest.config.js Updates coverage paths/thresholds for ESM/lib output.
types/tsconfig.json Switches TS module settings to ESM + bundler resolution.
types/index.d.ts Updates runtime module typing away from export =.
tests/rspack/rspack.test.js Updates rspack output tests for ESM + removed legacy formats.
tests/integration/webpack-test/src/handlebars-esm-import-test.js Imports from package root (handlebars) instead of deep path.
tests/integration/webpack-babel-test/webpack.config.js Removes obsolete webpack+babel integration test config.
tests/integration/webpack-babel-test/test.sh Removes obsolete integration runner.
tests/integration/webpack-babel-test/src/lib/assert.js Removes obsolete helper.
tests/integration/webpack-babel-test/src/handlebars-inline-precompile-test.js Removes obsolete integration test case.
tests/integration/webpack-babel-test/package.json Removes obsolete integration package.
tests/integration/webpack-babel-test/.gitignore Removes obsolete integration ignores.
tests/integration/webpack-babel-test/.babelrc Removes obsolete babel config.
tests/integration/rollup-test/src/index.js Updates rollup integration to import from package root.
tests/integration/rollup-test/package.json Marks rollup integration package as ESM (type: module).
tests/integration/multi-nodejs-test/run-handlebars.js Converts multi-node test script to ESM imports.
tests/integration/multi-nodejs-test/package.json Marks multi-node integration as ESM (type: module).
tests/browser/tests/lib.spec.js Converts Playwright test file to ESM and drops UMD smoke pages.
tests/browser/playwright.config.js Converts Playwright config to ESM export default.
tests/bench/templates.js Adds benchmark template corpus in .js (ESM) form.
tests/bench/size.js Switches bench imports from .mjs to .js.
tests/bench/report.js Adds bench reporting utilities in .js (ESM).
tests/bench/perf.js Switches bench imports from .mjs to .js.
tests/bench/compare.js Switches compare imports/help text from .mjs to .js.
tasks/version.js Converts version task to ESM + exports helper.
tasks/util/git.js Converts git util to ESM named exports.
tasks/util/exec-file.js Removes unused exec wrapper module.
tasks/tests/publish-to-aws.test.js Converts task tests to ESM imports.
tasks/tests/git.test.js Converts git util tests to ESM imports.
tasks/tests/fake-s3.js Converts fake S3 server helper to ESM export.
tasks/tests/cli.test.js Converts CLI tests to ESM + updates CLI filename/options.
tasks/publish-to-aws.js Converts publish script to ESM + adds “run as script” guard.
spec/vendor/require.js Removes vendored RequireJS (AMD no longer supported).
spec/umd.html Removes UMD smoke test page.
spec/umd-runtime.html Removes UMD runtime smoke test page.
spec/tokenizer.js Removes tokenizer spec file (legacy test coverage).
spec/spec.js Converts mustache-spec loader to ESM-safe JSON reading.
spec/source-map.js Simplifies source-map loading logic (now ESM context).
spec/require.js Removes require.extensions-based tests.
spec/precompiler.js Converts precompiler specs to import ESM lib sources.
spec/expected/source.map.amd.js Removes AMD expected artifact.
spec/expected/partial.template.js Removes AMD expected artifact.
spec/expected/non.empty.amd.known.helper.js Removes AMD expected artifact.
spec/expected/non.default.extension.amd.js Removes AMD expected artifact.
spec/expected/namespace.amd.js Removes AMD expected artifact.
spec/expected/help.menu.txt Updates CLI help expectations for new flags/filename.
spec/expected/handlebar.path.amd.js Removes AMD expected artifact.
spec/expected/empty.root.amd.js Removes AMD expected artifact.
spec/expected/empty.namespace.js Updates expected namespace output for non-AMD wrapper.
spec/expected/empty.name.amd.js Removes AMD expected artifact.
spec/expected/empty.amd.simple.js Removes AMD expected artifact.
spec/expected/empty.amd.namespace.js Removes AMD expected artifact.
spec/expected/empty.amd.min.js Removes AMD expected artifact.
spec/expected/empty.amd.js Removes AMD expected artifact.
spec/expected/bom.amd.js Removes AMD expected artifact.
spec/env/node.js Converts node spec env bootstrap to ESM imports.
spec/env/browser.js Converts browser spec env bootstrap to ESM + createRequire.
runtime.js Switches runtime alias to ESM re-export from lib/.
runtime.d.ts Updates runtime typings to default-import style.
rspack.config.js Converts bundler config to ESM + changes output library type to self.
package.json Enables ESM (type: module), adds exports/imports, removes SWC CJS build, updates scripts.
lib/precompiler.js Converts precompiler implementation to ESM exports + removes AMD/CJS wrappers + async minify import.
lib/index.js Makes ESM entrypoint and adds many named exports for CJS interop.
lib/handlebars/runtime.js Updates internal imports to include .js extensions.
lib/handlebars/logger.js Updates internal imports to include .js extensions.
lib/handlebars/internal/proto-access.js Updates internal imports to include .js extensions.
lib/handlebars/helpers/with.js Updates internal imports to include .js extensions.
lib/handlebars/helpers/if.js Updates internal imports to include .js extensions.
lib/handlebars/helpers/each.js Updates internal imports to include .js extensions.
lib/handlebars/helpers/block-helper-missing.js Updates internal imports to include .js extensions.
lib/handlebars/helpers.js Updates internal imports to include .js extensions.
lib/handlebars/decorators/inline.js Updates internal imports to include .js extensions.
lib/handlebars/decorators.js Updates internal imports to include .js extensions.
lib/handlebars/compiler/source-node.node.js Adds Node SourceNode entry using source-map.
lib/handlebars/compiler/source-node.browser.js Adds browser stub SourceNode implementation.
lib/handlebars/compiler/javascript-compiler.js Updates internal imports to include .js extensions.
lib/handlebars/compiler/compiler.js Updates internal imports to include .js extensions.
lib/handlebars/compiler/code-gen.js Switches SourceNode resolution to #source-node.
lib/handlebars/base.js Updates internal imports to include .js extensions.
lib/handlebars.runtime.js Adds named re-exports for runtime CJS interop.
lib/handlebars.js Converts primary entry to ESM + updates import extensions.
eslint.config.js Adds compat lint config targeting lib/**.
.swcrc Removes SWC config used for CJS builds.
.oxlintrc.json Updates bench file glob from .mjs to .js.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread spec/precompiler.js
Comment thread tests/rspack/rspack.test.js
Comment thread tests/rspack/rspack.test.js
Comment thread spec/source-map.js
Comment thread tasks/version.js Outdated
Comment thread lib/index.js
@kibertoad
Copy link
Copy Markdown
Contributor Author

@jaylinski all review comments addressed

@kibertoad
Copy link
Copy Markdown
Contributor Author

@jaylinski is anything left on this one?

@jaylinski
Copy link
Copy Markdown
Member

@jaylinski is anything left on this one?

I still want to give this a thorough (manual) test. Planned for tomorrow. Sorry for the wait.

Copy link
Copy Markdown
Member

@jaylinski jaylinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! 💯

(Please fix merge conflicts and merge.)

Comment thread package.json
"#source-node": {
"node": "./lib/handlebars/compiler/source-node.node.js",
"default": "./lib/handlebars/compiler/source-node.browser.js"
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice hack. Didn't know you can do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants