Skip to content

Add opt-in core bundle with on-demand localization - #410

Open
Alex Vallone (amv146) wants to merge 1 commit into
masterfrom
feature/core-localization-entrypoints
Open

Add opt-in core bundle with on-demand localization#410
Alex Vallone (amv146) wants to merge 1 commit into
masterfrom
feature/core-localization-entrypoints

Conversation

@amv146

@amv146 Alex Vallone (amv146) commented Aug 13, 2026

Copy link
Copy Markdown

Summary

This change adds a smaller, opt-in package entrypoint that excludes non-English localization templates from the initial bundle.

The existing @microsoft/powerquery-parser entrypoint remains unchanged and continues to load every supported locale synchronously. Consumers can migrate independently without a breaking change.

Changes

  • Add @microsoft/powerquery-parser/core.
    • Exposes the existing parser API.
    • Includes only en-US.
    • Falls back to en-US for unregistered locales.
  • Add LocalizationUtils.registerLocalizationTemplates(locale, templates).
  • Add locale-specific entrypoints such as:
    • @microsoft/powerquery-parser/locales/fr-FR
    • @microsoft/powerquery-parser/locales/de-DE
    • Equivalent entrypoints for every supported locale.
  • Add @microsoft/powerquery-parser/locales/all for consumers requiring every locale.
  • Preserve the existing TemplatesByLocale registry and direct-map mutation behavior.
  • Generate package-level entrypoints during the existing build.
  • Preserve legacy deep imports.
  • Add localization registration and compatibility tests.
  • Document the new entrypoints and fallback behavior.

Bundle impact

Measured using a minified Webpack production bundle:

Import Minified Gzip
Existing package root 665.8 KB 119.1 KB
Core 351.2 KB 64.3 KB
Core plus fr-FR 358.5 KB 66.1 KB

Using core reduces the initial parser payload by approximately 54.8 KB gzip.

Why createPackageEntrypoints.js is necessary

TypeScript currently emits the new core module at:

lib/powerquery-parser/core.js

Without a package exports map, Node resolves:

import ... from "@microsoft/powerquery-parser/core";

to a core.js file at the package root. The build script creates that thin proxy and its declaration file. It also creates stable locales/<locale> JavaScript and declaration entrypoints from the generated localization JSON files, allowing consumers to use named templates imports without maintaining a source wrapper for every locale.

A package exports map would normally provide these aliases without generated proxy files. It is not used here because defining exports restricts package access to explicitly exported paths. This package has historically allowed arbitrary deep imports under lib/powerquery-parser, and testing confirmed that introducing exports would block existing consumers of those paths.

Removing the script

The preferred long-term solution is a major-version release that:

  1. Defines the supported public API through package.json#exports.
  2. Maps ./core directly to ./lib/powerquery-parser/core.js.
  3. Maps locale subpaths directly to their emitted modules or JSON resources.
  4. Migrates consumers away from undocumented deep imports.
  5. Either changes locale imports to use the JSON module shape or retains explicit source wrappers when the named { templates } API is required.

Once arbitrary deep-import compatibility is no longer required, createPackageEntrypoints.js, the generated package-root proxies, and their .gitignore entries can be removed.

Migration guide

No migration is required for existing consumers:

import * as PowerQueryParser from "@microsoft/powerquery-parser";

This continues to include and support every locale.

English-only consumers

Replace root imports with the core entrypoint:

-import * as PowerQueryParser from "@microsoft/powerquery-parser";
+import * as PowerQueryParser from "@microsoft/powerquery-parser/core";

No other changes are required. Locale values without a registered translation fall back to en-US.

Consumers requiring one locale

Import the core parser, load the required locale, and register it before parsing:

import * as PowerQueryParser from "@microsoft/powerquery-parser/core";
import { templates as frFR } from "@microsoft/powerquery-parser/locales/fr-FR";

PowerQueryParser.LocalizationUtils.registerLocalizationTemplates("fr-FR", frFR);

Existing settings continue to select the locale normally:

const settings: PowerQueryParser.Settings = {
    ...PowerQueryParser.DefaultSettings,
    locale: "fr-FR",
};

Lazy-loading a locale

Applications can place translations in separate chunks:

import * as PowerQueryParser from "@microsoft/powerquery-parser/core";

async function registerLocale(locale: string): Promise<void> {
    if (locale.toLowerCase() === "fr-fr") {
        const { templates } = await import("@microsoft/powerquery-parser/locales/fr-FR");

        PowerQueryParser.LocalizationUtils.registerLocalizationTemplates(locale, templates);
    }
}

Registration must finish before constructing localized lexer or parser errors.

Consumers requiring every locale

import * as PowerQueryParser from "@microsoft/powerquery-parser/core";
import "@microsoft/powerquery-parser/locales/all";

Alternatively, continue using the existing package root.

Transitive dependencies

If another dependency imports @microsoft/powerquery-parser, changing only application imports may retain the full bundle. Applications can alias the root import to core in their bundler:

resolve: {
    alias: {
        "@microsoft/powerquery-parser$": require.resolve("@microsoft/powerquery-parser/core"),
    },
}

The application must then register every non-English locale it uses.

Compatibility

  • Existing root imports remain unchanged.
  • Existing locale selection remains unchanged.
  • Existing Templates exports remain available.
  • Existing TemplatesByLocale mutations continue to work.
  • Existing deep imports remain available.
  • Core adoption is entirely opt-in.

Validation

  • Build passes.
  • Lint passes.
  • Localization tests pass.
  • Packed-package root, core, individual locale, all-locales, and legacy deep imports verified.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

1 participant