@@ -172,7 +172,7 @@ function buildExtendsTree(
172172 }
173173 }
174174 } catch ( _e ) {
175- // sad path (normally >1 levels removed): the extends type does not resolve so let's find it manually:
175+ // sad path (>1 levels removed or node_modules ): the extends type does not resolve so let's find it manually:
176176
177177 let currentSource : ts . SourceFile = classDeclaration . getSourceFile ( ) ;
178178 let matchedStatement : ts . ClassDeclaration | ts . FunctionDeclaration | ts . VariableStatement ;
@@ -185,7 +185,13 @@ function buildExtendsTree(
185185 matchedStatement = currentSource . statements . find ( matchesNamedDeclaration ( extendee . getText ( ) ) ) ;
186186 }
187187
188- if ( ! currentSource ) return ;
188+ if ( ! currentSource ) {
189+ // no source file :(
190+ const err = buildWarn ( buildCtx . diagnostics ) ;
191+ err . messageText = `Unable to find source file for class "${ classDeclaration . name ?. getText ( ) } "` ;
192+ if ( ! buildCtx . config . _isTesting ) augmentDiagnosticWithNode ( err , classDeclaration ) ;
193+ return ;
194+ }
189195
190196 // try to see if we can find the class in the current source file first
191197 if ( matchedStatement && ts . isClassDeclaration ( matchedStatement ) ) {
@@ -233,14 +239,33 @@ function buildExtendsTree(
233239 let foundSource : ts . SourceFile = compilerCtx . moduleMap . get (
234240 foundFile . resolvedModule . resolvedFileName ,
235241 ) ?. staticSourceFile ;
242+
236243 if ( ! foundSource ) {
237- // Stencil only loads module entries from node_modules collections,
244+ // Stencil only loads full-fledged component modules from node_modules collections,
238245 // so if we didn't find the source file in the module map,
239246 // let's create a temporary program and get the source file from there
240247 foundSource = tsGetSourceFile ( buildCtx . config , foundFile ) ;
248+
249+ if ( ! foundSource ) {
250+ // ts could not resolve the module. Likely because `allowJs` is not set to `true`
251+ const err = buildWarn ( buildCtx . diagnostics ) ;
252+ err . messageText = `Unable to resolve import "${ statement . moduleSpecifier . getText ( ) } " from "${ currentSource . fileName } ".
253+ This can happen when trying to resolve .js files and "allowJs" is not set to "true" in your tsconfig.json.` ;
254+ if ( ! buildCtx . config . _isTesting ) augmentDiagnosticWithNode ( err , classDeclaration ) ;
255+ return ;
256+ }
241257 }
242258
243259 const matchedStatement = foundSource . statements . find ( matchesNamedDeclaration ( className ) ) ;
260+ if ( ! matchedStatement ) {
261+ // we couldn't find the imported declaration as an exported statement in the module
262+ const err = buildWarn ( buildCtx . diagnostics ) ;
263+ err . messageText = `Unable to find "${ className } " in the imported module "${ statement . moduleSpecifier . getText ( ) } ".
264+ Please import class / mixin-factory declarations directly and not via barrel files.` ;
265+ if ( ! buildCtx . config . _isTesting ) augmentDiagnosticWithNode ( err , classDeclaration ) ;
266+ return ;
267+ }
268+
244269 foundClassDeclaration = matchedStatement
245270 ? ts . isClassDeclaration ( matchedStatement )
246271 ? matchedStatement
0 commit comments