Skip to content

[SPFx 1.23.2 / 1.24.0-beta.2] heft test / Jest fails: sp-core-library unconditionally requires unpublished @msinternal/* packages #11035

Description

Target SharePoint environment

SharePoint Online

What SharePoint development model, framework, SDK or API is this about?

💥 SharePoint Framework

Developer environment

Windows

What browser(s) / client(s) have you tested

  • 💥 Internet Explorer
  • 💥 Microsoft Edge
  • 💥 Google Chrome
  • 💥 FireFox
  • 💥 Safari
  • mobile (iOS/iPadOS)
  • mobile (Android)
  • not applicable
  • other (enter in the "Additional environment details" area below)

Additional environment details

  • SPFx version: 1.23.2 (GA) — also reproduced on 1.24.0-beta.2
  • Node.js version: v22.22.0
  • Build system: Heft/Rush Stack (@rushstack/heft 1.2.17), scaffolded with --use-heft (not gulp)
  • Jest version: 30.2.0 (via @microsoft/spfx-web-build-rig's default jest.config.json / @rushstack/heft-jest-plugin)
  • Affected packages: @microsoft/sp-core-library, @microsoft/sp-http, @microsoft/sp-http-base

Describe the bug / error

@microsoft/sp-core-library's compiled SPFlight.js and SPExperiment.js modules contain unconditional,
top-level require()/import statements for Microsoft-internal packages — e.g. @msinternal/ecs-flight
and @msinternal/odsp-core-bundle. Scanning the wider @microsoft/sp-* dependency tree turns up dozens
more of these (@msinternal/odsp-datasources, @msinternal/odsp-utilities, @msinternal/sp-telemetry,
@msinternal/sp-safehtml, etc.).

These @msinternal/* packages are listed only under sp-core-library's own devDependencies (never as a
regular "dependency"), are not published to the public npm registry, and are therefore never present
in a consuming project's node_modules.

In a production Webpack build this goes unnoticed, since nothing in application code calls SPFlight/
SPExperiment directly, so tree-shaking drops the unused re-export before Webpack needs to resolve the
import. But heft test (Jest) eagerly evaluates CommonJS modules with a plain require(), which
unconditionally runs sp-core-library's module top-level code — including the @msinternal/* require —
for any test file that transitively imports @microsoft/sp-http's AadHttpClient (or anything else in
the dependency graph that reaches SPFlight.js/SPExperiment.js). The test suite fails to even load:

Cannot find module '@msinternal/ecs-flight' from 'node_modules/@microsoft/sp-core-library/lib-commonjs/SPFlight.js'

Require stack:
node_modules/@microsoft/sp-core-library/lib-commonjs/SPFlight.js
node_modules/@microsoft/sp-core-library/lib-commonjs/index.js
node_modules/@microsoft/sp-http-base/lib-commonjs/aadHttpClient/AadHttpClient.js
node_modules/@microsoft/sp-http-base/lib-commonjs/index.js
node_modules/@microsoft/sp-http/lib-commonjs/index.js

This reproduces identically on both the current GA release (1.23.2) and the 1.24.0-beta.2
— the compiled output style changed (tslib helpers in 1.23.2 vs. @swc/helpers
in 1.24.0-beta.2), but the unconditional require("@msinternal/ecs-flight") at the top of SPFlight.js
is unchanged between versions.

The default Jest config shipped by @microsoft/spfx-web-build-rig / @rushstack/heft-jest-plugin has no
moduleNameMapper/transformIgnorePatterns entry to protect against this, so any SPFx project scaffolded
with --use-heft (the current default/only build system) hits this the moment a test touches
AadHttpClient, SPComponentLoader, or anything else that pulls in sp-core-library's flighting code —
with zero custom application code involved.

Steps to reproduce

  1. Scaffold (or open) any Heft-based SPFx project on 1.23.2 or 1.24.0-beta.2 that depends on @microsoft/sp-http.

  2. Add a trivial test file, e.g.:

    import { AadHttpClient } from '@microsoft/sp-http';

    test('sp-http imports without crashing', () => {
    expect(AadHttpClient).toBeDefined();
    });

  3. Run heft test --clean (or npm run test).

  4. Observe: "Cannot find module '@msinternal/ecs-flight'" — the test suite fails to run at all.

Expected behavior

heft test / Jest should be able to load and run tests that import @microsoft/sp-http (or any other
@microsoft/sp-* package) without requiring knowledge of Microsoft-internal, unpublished @msinternal/*
packages. Either:

  • sp-core-library's published lib/lib-commonjs output should not statically/unconditionally require
    packages that are only its own devDependencies and are never published (e.g. gate them behind a
    dynamic require/lazy accessor, or strip the dead code path from the published build), or
  • The default Jest configuration in @microsoft/spfx-web-build-rig / @rushstack/heft-jest-plugin should
    stub out the @msinternal/* scope out of the box.

We worked around it locally with a project-level Jest moduleNameMapper regex stub for ^@msinternal/.*$,
but this shouldn't be necessary for a first-party Microsoft package to be testable.

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions