Skip to content

Commit

Permalink
fix(): ensure only components are exported
Browse files Browse the repository at this point in the history
  • Loading branch information
manucorporat committed Jun 14, 2019
1 parent e3e8ce3 commit 0712e88
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { DEFAULT_STYLE_MODE, augmentDiagnosticWithNode, buildError, validateComp
import { CLASS_DECORATORS_TO_REMOVE } from '../remove-stencil-import';


export function componentDecoratorToStatic(config: d.Config, diagnostics: d.Diagnostic[], cmpNode: ts.ClassDeclaration, newMembers: ts.ClassElement[], componentDecorator: ts.Decorator) {
export function componentDecoratorToStatic(config: d.Config, typeChecker: ts.TypeChecker, diagnostics: d.Diagnostic[], cmpNode: ts.ClassDeclaration, newMembers: ts.ClassElement[], componentDecorator: ts.Decorator) {
removeDecorators(cmpNode, CLASS_DECORATORS_TO_REMOVE);

const [ componentOptions ] = getDeclarationParameters<d.ComponentOptions>(componentDecorator);
if (!componentOptions) {
return;
}

if (!validateComponent(config, diagnostics, componentOptions, cmpNode, componentDecorator)) {
if (!validateComponent(config, diagnostics, typeChecker, componentOptions, cmpNode, componentDecorator)) {
return;
}

Expand Down Expand Up @@ -67,9 +67,10 @@ export function componentDecoratorToStatic(config: d.Config, diagnostics: d.Diag
newMembers.push(createStaticGetter('styles', convertValueToLiteral(styles)));
}
}

}

function validateComponent(config: d.Config, diagnostics: d.Diagnostic[], componentOptions: d.ComponentOptions, cmpNode: ts.ClassDeclaration, componentDecorator: ts.Node) {
function validateComponent(config: d.Config, diagnostics: d.Diagnostic[], typeChecker: ts.TypeChecker, componentOptions: d.ComponentOptions, cmpNode: ts.ClassDeclaration, componentDecorator: ts.Node) {
const extendNode = cmpNode.heritageClauses && cmpNode.heritageClauses.find(c => c.token === ts.SyntaxKind.ExtendsKeyword);
if (extendNode) {
const err = buildError(diagnostics);
Expand Down Expand Up @@ -111,6 +112,23 @@ function validateComponent(config: d.Config, diagnostics: d.Diagnostic[], compon
augmentDiagnosticWithNode(config, err, findTagNode('tag', componentDecorator));
return false;
}

if (!config._isTesting) {
const nonTypeExports = typeChecker.getExportsOfModule(typeChecker.getSymbolAtLocation(cmpNode.getSourceFile()))
.filter(symbol => (symbol.flags & (ts.SymbolFlags.Interface | ts.SymbolFlags.TypeAlias)) === 0)
.filter(symbol => symbol.name !== cmpNode.name.text);

nonTypeExports.forEach(symbol => {
const err = buildError(diagnostics);
err.messageText = `To allow efficient bundling with rollup, modules using @Component() can only have a single export which is the component class itself.
Any other exports should be moved to a separate file.
For further information check out: https://stenciljs.com/docs/module-bundling`;
augmentDiagnosticWithNode(config, err, symbol.valueDeclaration.modifiers[0]);
});
if (nonTypeExports.length > 0) {
return false;
}
}
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function visitClass(config: d.Config, diagnostics: d.Diagnostic[], typeChecker:
const newMembers: ts.ClassElement[] = [...cmpNode.members];

// parser component decorator (Component)
componentDecoratorToStatic(config, diagnostics, cmpNode, newMembers, componentDecorator);
componentDecoratorToStatic(config, typeChecker, diagnostics, cmpNode, newMembers, componentDecorator);

// parse member decorators (Prop, State, Listen, Event, Method, Element and Watch)
const decoratedMembers = newMembers.filter(member => Array.isArray(member.decorators) && member.decorators.length > 0);
Expand Down

0 comments on commit 0712e88

Please sign in to comment.