Skip to content

fix: externalize prettier/plugins/estree to prevent comment formatting crash#425

Merged
evoactivity merged 2 commits intoember-tooling:mainfrom
lifeart:fix-estree-external
Mar 31, 2026
Merged

fix: externalize prettier/plugins/estree to prevent comment formatting crash#425
evoactivity merged 2 commits intoember-tooling:mainfrom
lifeart:fix-estree-external

Conversation

@lifeart
Copy link
Copy Markdown
Contributor

@lifeart lifeart commented Mar 30, 2026

Summary

Fixes #424

The vite config listed prettier/plugins/estree.js and prettier/plugins/babel.js as external, but the source imports prettier/plugins/estree and prettier/plugins/babel (no .js extension). This mismatch caused vite to bundle prettier's estree printer into the plugin instead of keeping it external.

When the user installs a newer version of prettier (e.g. 3.6.2), the plugin still uses the old bundled estree code whose canAttachComment function expects 2 arguments (node, ancestors), while prettier 3.6+'s core calls it with only 1 argument (node). This causes a crash:

TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
    at getSortedChildNodes (prettier/index.mjs)
    at decorateComment (prettier/index.mjs)
    at attachComments (prettier/index.mjs)

when formatting any .gts file that contains both a comment and a <template> tag.

Fix

Remove the .js extension from the external config entries so they match the actual import paths in the source code:

-'prettier/plugins/estree.js',
-'prettier/plugins/babel.js',
+'prettier/plugins/estree',
+'prettier/plugins/babel',

This ensures prettier's estree and babel plugins are loaded from the user's installed prettier version at runtime rather than being bundled at build time.

Minimal reproduction

// x
<template></template>

Test

Added tests/cases/gts/comment-with-template.gts regression test case.

Copilot AI review requested due to automatic review settings March 30, 2026 11:31
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

Adjusts the Vite/Rollup build configuration so Prettier’s estree/babel plugin modules are truly externalized (matching the source import specifiers), preventing runtime crashes caused by bundling an outdated Prettier printer implementation when users run newer Prettier versions.

Changes:

  • Fix Rollup external entries to match prettier/plugins/estree and prettier/plugins/babel import paths (no .js extension).
  • Add a .gts regression case covering “comment + <template>” formatting.
  • Update Vitest snapshots for the new test case across relevant config suites.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
vite.config.mjs Fixes externalization specifiers so Prettier plugin modules aren’t bundled unintentionally.
tests/cases/gts/comment-with-template.gts Adds regression input reproducing the crash scenario.
tests/unit-tests/snapshots/format.test.ts.snap Records expected formatting output for the new case in the default suite.
tests/unit-tests/config/snapshots/semi-false.test.ts.snap Records expected formatting output for the new case under semi: false.
tests/unit-tests/config/snapshots/template-export-default.test.ts.snap Records expected formatting output for the new case under templateExportDefault: true.

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

The vite config listed `prettier/plugins/estree.js` as external, but the
source imports `prettier/plugins/estree` (no .js extension). This mismatch
caused vite to bundle prettier's estree printer into the plugin instead of
keeping it external. When the user installs a newer version of prettier
(e.g. 3.6.2), the plugin still uses the old bundled estree code whose
`canAttachComment` function expects 2 arguments, while prettier 3.6+'s
core calls it with 1 argument. This causes a crash:

  TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))

when formatting any .gts file that contains both a comment and a <template> tag.

The fix removes the .js extension from the external config so it matches
the actual import paths. Also adds a regression test case.

Closes ember-tooling#424
@lifeart lifeart force-pushed the fix-estree-external branch from 1719d02 to 2cbbfe5 Compare March 30, 2026 11:37
…ests

Fix lint issues in build-externals test (import style, naming conventions,
encoding identifier) and add missing `pnpm build` step to test-prettier-versions
CI job so the dist file exists when the build-externals test runs. Also make
assertions resilient to both CJS and ESM output formats.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
const distribution = readFileSync(distributionPath, 'utf8');

expect(distribution).toMatch(
/require\(["']prettier\/plugins\/babel["']\)|from\s+["']prettier\/plugins\/babel["']/,
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.

covering cjs/esm cases (esm - for future use)

@evoactivity evoactivity merged commit 7425506 into ember-tooling:main Mar 31, 2026
14 checks passed
@github-actions github-actions Bot mentioned this pull request Mar 31, 2026
@evoactivity evoactivity added the bug Something isn't working label Mar 31, 2026
@lifeart lifeart deleted the fix-estree-external branch March 31, 2026 07:46
@github-actions github-actions Bot mentioned this pull request Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Crash when formatting .gts file containing any comment + template tag (prettier 3.6.2)

3 participants