perf(vscode-extension): keep the language server out of the client bundle - #1275
perf(vscode-extension): keep the language server out of the client bundle#1275EvilGenius13 wants to merge 4 commits into
Conversation
b70dcb1 to
2ac1ab6
Compare
…of the client bundle
2ac1ab6 to
4e4df97
Compare
There was a problem hiding this comment.
I love the outcome of this PR but not a huge fan of how we're getting there. Reaching into the dist folder is creating an implicit connection to theme-check-common's build process. I'd rather fix this in theme-check-common itself by adding some public subpath exports that we intend for consumers to use.
Also side note: I don't think the type imports need this? I don't think these are included at runtime.
There was a problem hiding this comment.
Thanks for the suggestion Gray.
Type imports - you were totally right so I put it back the way it was.
Instead of reaching into the dist folder they got moved into the packages themselves and they each have an entry point pointing to the actual file. No more weird connections.
I tried the subpath exports but I ran into a couple problems. Our TS setup falls back to the older resolution mode and it ignores exports completely. When I tried setting up the new mode if a path wasn't explicitly listed it stopped resolving. It messed up deep-imports of MockTheme and MockFileSystem`. My concern is if any user of the libraries has deep links we would probably break for them as well.
What do you think about this current method vs the subpath export?
…paths Replace the vscode-extension's `dist/` deep imports with root-level re-export stubs, so consumers get a supported entry point instead of reaching into build output. `@shopify/theme-check-common/path` and `@shopify/theme-language-server-common/types` re-export their `dist` modules. The extension imports values from those subpaths and takes types from the package barrels, keeping the language server out of the client bundle: browser/extension.js is 2,103,681 bytes and node/extension.js is 1,410,426 bytes, versus 6,722,159 and 6,497,684 when the same values come from a barrel. Purely additive. No package.json, tsconfig, or webpack changes, and the barrel imports behave exactly as before.
Add curated `exports` + `typesVersions` maps to
`@shopify/theme-check-common` (`.`, `./path`, `./test`, `./package.json`)
and `@shopify/theme-language-server-common` (`.`, `./types`,
`./package.json`), replacing the root `path.*` / `types.*` forwarder
files with a single declared public surface.
BREAKING CHANGE: deep imports into `dist/` and `src/` no longer resolve.
Seven symbols previously reached via `dist/` deep paths are promoted to
the `@shopify/theme-check-common` barrel: `getPosition`,
`createDisabledChecksModule`, `UNMATCHED_COMMENT_CLOSE_PARSER_ERROR`,
`UNMATCHED_RAW_CLOSE_PARSER_ERROR`,
`hasRubyAcceptedInertCommentBodyCloser`, `hasJavascriptClosingTagAfter`,
and `hasRubyAcceptedRawTagCloserWithMarkup`.
In-repo `@shopify/theme-check-common/{src,dist}/test` call sites move to
the public `/test` subpath. New `package-exports.spec.ts` in each package
locks both the declared subpaths and the removed legacy ones.
What this does
The VS Code extension was shipping a lot more code than it needed.
It pulls a couple of small helpers from two shared packages. Both came in through the package barrel (
@shopify/theme-check-common), and a barrel import drags in everything the barrel touches — including the whole theme-check rule suite, which the extension never runs.This trims it down.
Less to download, quicker to start — most noticeable on the web version.
How
Both packages now declare their public entry points in
package.jsonexports.@shopify/theme-check-common—.,./path,./test,./package.json@shopify/theme-language-server-common—.,./types,./package.json./pathand./typesare narrow entry points: importing one loads that module alone, not the barrel. That's how the extension gets the path helpers and the LSP request types without pulling the server along. Putting them inexportsis what makes them the supported public API rather than an informal convention.typesVersionsmirrors the map so TypeScript keeps up. This repo compiles withmoduleResolution: node, which ignoresexportsentirely. WithouttypesVersionsthe subpaths would resolve at runtime but fail to type-check — that was the blocker from the earlier round of review, and this is the fix.Unlisted deep imports are now unsupported, on purpose. Anything outside the map —
@shopify/theme-check-common/src/...,.../dist/...— throwsERR_PACKAGE_PATH_NOT_EXPORTEDin Node and in bundlers. That's the point: the packages own their internal layout again, and the bundle win holds because there is no back door into the barrel. Both libraries aremajorin the changeset.What that cost inside the repo:
getPosition,createDisabledChecksModule,UNMATCHED_COMMENT_CLOSE_PARSER_ERROR,UNMATCHED_RAW_CLOSE_PARSER_ERROR,hasRubyAcceptedInertCommentBodyCloser,hasJavascriptClosingTagAfter,hasRubyAcceptedRawTagCloserWithMarkup. Everything else those modules exposed stays private./test. Seven language-server specs that reached into@shopify/theme-check-common/src/test(or/dist/test) now import@shopify/theme-check-common/test. One stale relative import oftest-setupwas dropped — Vitest already loads it throughsetupFiles.pathsin the root config andtheme-language-server-common/src/tsconfig.jsonmap the new subpaths tosrc/so in-repo development still resolves to source.Type-only imports are type-only again. Roughly half the extension's imports were types, which never reach the bundle in the first place; those are back on the barrel as
import type.Known external consumer:
shop/worldhas fivedist/deep imports acrossareas/clients/shell/packages/theme-check/check.tsandcheck-liquid-fused.ts. All the symbols they need are on the barrel now, but that migration has to land before that repo picks up the new majors.Checked
package-exports.spec.tsin both packages — 22 tests asserting every public subpath resolves to the expecteddistfile, every retiredsrc//dist/path fails withERR_PACKAGE_PATH_NOT_EXPORTED, and all seven promoted symbols are present on the barrelpnpm build:ts,pnpm type-check,pnpm format:checkpass;pnpm changeset statusreports 7 major + 2 patchbrowser/extension.js2,103,405 B,node/extension.js1,410,146 B