Skip to content

fix(prettier-plugin-liquid): route standalone externals to prettier/standalone#1192

Open
SinhSinhAn wants to merge 1 commit intoShopify:mainfrom
SinhSinhAn:fix/prettier-plugin-standalone-import
Open

fix(prettier-plugin-liquid): route standalone externals to prettier/standalone#1192
SinhSinhAn wants to merge 1 commit intoShopify:mainfrom
SinhSinhAn:fix/prettier-plugin-standalone-import

Conversation

@SinhSinhAn
Copy link
Copy Markdown
Contributor

What is this PR?

Fixes #1098. The standalone browser bundle of @shopify/prettier-plugin-liquid has been emitting require("prettier") in its UMD wrapper, which breaks browser consumers because prettier's main entry imports Node builtins (module, url, path).

What was the issue?

The reporter's screenshot on the issue shows three webpack errors when consuming standalone.js from a browser build:

ERROR in ./node_modules/prettier/index.mjs
  Module not found: Error: Can't resolve 'module' in '…/node_modules/prettier'
ERROR in ./node_modules/prettier/index.mjs
  Module not found: Error: Can't resolve 'url'
ERROR in ./node_modules/prettier/index.mjs
  Module not found: Error: Can't resolve 'path'

The root cause is the webpack externals declaration at packages/prettier-plugin-liquid/webpack.config.js:

externals: {
  prettier: {
    commonjs: 'prettier',        // wrong
    commonjs2: 'prettier',       // wrong
    amd: 'prettier/standalone',  // correct
    root: 'prettier',            // correct — script tag global
  },
},

The generated UMD wrapper checks commonjs/commonjs2 first (because module.exports is defined), so downstream bundlers target those branches and get require("prettier"). That resolves to prettier/index.mjs, which is the full Node-flavored entry that imports module, url, and path. Those are Node builtins and cannot be resolved for browser targets.

The intended browser entry, prettier/standalone, is browser-safe and already correctly wired for the AMD branch.

How this PR fixes it

One-file change in webpack.config.js: route the commonjs and commonjs2 keys to prettier/standalone, matching the amd branch. The root: 'prettier' key stays as-is because a <script> tag for prettier/standalone.js still populates window.prettier, so the global name is unchanged.

Verification

After the fix, the top of the freshly built standalone.js now shows:

(function webpackUniversalModuleDefinition(root, factory) {
    if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory(require("prettier/standalone"));
    else if(typeof define === 'function' && define.amd)
        define(["prettier/standalone"], factory);
    else if(typeof exports === 'object')
        exports["prettierPluginLiquid"] = factory(require("prettier/standalone"));
    else
        root["prettierPluginLiquid"] = factory(root["prettier"]);
})(this, );

grep 'require("prettier")' standalone.js returns zero matches. All references to prettier inside the bundle are now routed through the browser-safe entry.

Tests

All 141 existing prettier-plugin-liquid tests still pass. No existing test covered the build output of standalone.js (the test suite is formatter-input/output scenarios run through Node), and the fix is entirely a build-configuration change.

Closes #1098

…tandalone

The webpack config for the browser `standalone.js` bundle declared
the `prettier` external with `commonjs: 'prettier'` and
`commonjs2: 'prettier'`. The resulting UMD wrapper emitted
`require('prettier')` in both the `module.exports` and `exports[...]`
branches, so downstream bundlers (webpack, rollup, vite) processing
`standalone.js` for a browser target resolved prettier's Node-flavored
main entry. That entry imports `module`, `url`, and `path` and crashes
browser builds with "Module not found" errors.

Route the `commonjs` and `commonjs2` keys to `prettier/standalone`,
matching the `amd` branch, so downstream bundlers land on prettier's
browser-safe entry. Keep `root: 'prettier'` so <script>-tag consumers
still bind against the `window.prettier` global populated by
`prettier/standalone.js` on the page.

Closes Shopify#1098
@SinhSinhAn SinhSinhAn requested a review from a team as a code owner April 22, 2026 19:49
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.

Standalone prettier plugin build imports "prettier" instead of "prettier/standalone"

1 participant