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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant