Skip to content

fix(compiler): eliminate false-positive mixin warnings for barrel imports and useDefineForClassFields:false#6691

Open
davidpett wants to merge 1 commit intomainfrom
fix/barrel-import-mixin-warning
Open

fix(compiler): eliminate false-positive mixin warnings for barrel imports and useDefineForClassFields:false#6691
davidpett wants to merge 1 commit intomainfrom
fix/barrel-import-mixin-warning

Conversation

@davidpett
Copy link
Copy Markdown

Summary

Two separate conditions in mergeExtendedClassMeta / resolveAndProcessExtendedClass produced spurious build warnings for valid mixin-factory patterns. Both are fixed in a single commit.


Fix 1 — useDefineForClassFields: false false positive

Root cause: detectModernPropDeclarations returns false whenever TypeScript has stripped PropertyDeclaration nodes from the class body. With useDefineForClassFields: false that stripping always happens, so the guard fired unconditionally and emitted:

"Component classes can only extend from other Stencil decorated base classes when targeting more modern JavaScript"

Fix: Guard the warning with buildCtx.config.tsCompilerOptions?.useDefineForClassFields !== false so the check is skipped entirely in that configuration (which is the recommended Stencil setup for "target": "es2022").


Fix 2 — Barrel re-export support

Root cause: When a mixin factory is imported through a barrel index file:

// mixins/index.ts
export * from './color';

// component.tsx
import { colorFactory } from '../mixins';

the direct statements.find() lookup in resolveAndProcessExtendedClass returns null because the barrel has no own declarations. This triggered:

"Please import class / mixin-factory declarations directly and not via barrel files"

even though the pattern is completely valid.

Fix: Added a resolveFromBarrelExports helper that follows export * from '...' and export { X } from '...' re-exports one level deep to locate the real declaration. The call site tries barrel traversal before emitting the warning. The dependentClasses entry is updated to record the actual source file / file name (not the barrel's) for correct downstream processing.


Test infrastructure

File What was added
src/compiler/transformers/test/transpile.ts transpileModules(files, config?, tsConfig?) — multi-file variant of transpileModule that pre-populates compilerCtx.moduleMap with auxiliary source files so cross-file scenarios work in unit tests without hitting the real file system
src/compiler/transformers/test/parse-mixin.spec.ts describe('mixin factory imported from a barrel index file') with 3 test cases: export * from barrel, named export { X as Y } from barrel, and explicit useDefineForClassFields: false

Testing

  • All 17 pre-existing tests in the relevant spec files continue to pass.
  • The 3 new tests pass.
  • npm run ts scripts/index.ts -- --prod --ci completes successfully. The only tsc.prod errors are pre-existing in src/testing/jest/jest-28/jest-environment.ts (unrelated, present on main).
  • Verified end-to-end in a downstream project that uses the mixin factory + barrel pattern with "useDefineForClassFields": false, "target": "es2022" — zero warnings after applying the fix.
…orts and useDefineForClassFields:false

Two unrelated conditions in `mergeExtendedClassMeta` / `resolveAndProcessExtendedClass`
caused spurious build warnings for valid mixin-factory patterns.

**Fix 1 — useDefineForClassFields: false**
`detectModernPropDeclarations` returns `false` whenever TypeScript has stripped
`PropertyDeclaration` nodes from the class body (which it always does when
`useDefineForClassFields: false`). Guard the warning with a check for that flag so
the "Component classes can only extend from other Stencil decorated base classes
when targeting more modern JavaScript" message is never emitted in that configuration.

**Fix 2 — barrel re-export support**
When a mixin factory is imported through a barrel index file
(`export * from './mixin'` / `export { X } from './mixin'`), the direct
`statements.find()` lookup in `resolveAndProcessExtendedClass` finds nothing,
triggering the "Please import class / mixin-factory declarations directly and not
via barrel files" warning even for a correct setup. A new `resolveFromBarrelExports`
helper follows re-exports one level deep so the real declaration is located before
the warning is emitted. The dependent-class entry now records the actual source file
and file name (not the barrel's) for correct downstream processing.

**Test infrastructure**
- `transpileModules()` added to `transpile.ts` — a multi-file variant of
  `transpileModule` that pre-populates `compilerCtx.moduleMap` with auxiliary
  source files so cross-file scenarios can be exercised in unit tests without
  hitting the real file system.
- Three new test cases in `parse-mixin.spec.ts` covering:
  - `export * from` barrel re-export → no warning
  - named `export { X as Y } from` re-export → no warning
  - explicit `useDefineForClassFields: false` → no warning
@davidpett davidpett requested a review from a team as a code owner April 27, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant