Skip to content

Commit

Permalink
feat(compiler): add component compiler metadata to results
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdbradley committed Jul 26, 2019
1 parent e6cc6da commit b354444
Show file tree
Hide file tree
Showing 16 changed files with 83 additions and 64 deletions.
39 changes: 19 additions & 20 deletions src/compiler/browser/browser-compile-options.ts
Expand Up @@ -6,32 +6,30 @@ import ts from 'typescript';

export const getCompileOptions = (input: d.CompileOptions) => {
const rtn: d.CompileOptions = {
componentExport: (typeof input.componentExport === 'string' ? input.componentExport.toLowerCase().trim() : ''),
componentMetadata: (typeof input.componentMetadata === 'string' ? input.componentMetadata.toLowerCase().trim() : ''),
module: (typeof input.module === 'string' ? input.module.toLowerCase().trim() : ''),
script: (typeof input.script === 'string' ? input.script.toLowerCase().trim() : ''),
style: (typeof input.style === 'string' ? input.style.toLowerCase().trim() : '')
componentExport: getConfig(input.componentExport, VALID_EXPORT, 'customelement'),
componentMetadata: getConfig(input.componentMetadata, VALID_METADATA, null),
proxy: getConfig(input.proxy, VALID_PROXY, 'defineproperty'),
module: getConfig(input.module, VALID_MODULE, 'esm'),
script: getConfig(input.script, VALID_SCRIPT, 'es2017'),
style: getConfig(input.style, VALID_STYLE, 'import')
};

if (!VALID_METADATA.has(rtn.componentMetadata)) {
rtn.componentMetadata = 'proxy';
}

if (!VALID_OUTPUT.has(rtn.componentExport)) {
rtn.componentExport = 'customelement';
}

if (!VALID_STYLE.has(rtn.style)) {
rtn.style = 'import';
}

return rtn;
};

const getConfig = (value: any, validValues: Set<string>, defaultValue: string) => {
value = (typeof value === 'string' ? value.toLowerCase().trim() : null);
if (validValues.has(value)) {
return value;
}
return defaultValue;
};

const VALID_METADATA = new Set(['pending', 'static']);
const VALID_OUTPUT = new Set(['customelement', 'module']);
const VALID_PROXY = new Set(['defineproperty', null]);
const VALID_METADATA = new Set(['runtimestatic', 'compilerstatic', null]);
const VALID_EXPORT = new Set(['customelement', 'module']);
const VALID_STYLE = new Set(['import', 'inline']);
const VALID_MODULE = new Set(['esm', 'cjs']);
const VALID_SCRIPT = new Set(['latest', 'esnext', 'es2017', 'es2015', 'es5']);


export const getTransformOptions = (compilerOpts: d.CompileOptions) => {
Expand Down Expand Up @@ -64,6 +62,7 @@ export const getTransformOptions = (compilerOpts: d.CompileOptions) => {
coreImportPath: '@stencil/core/internal/client',
componentExport: null,
componentMetadata: compilerOpts.componentMetadata as any,
proxy: compilerOpts.proxy as any,
scopeCss: true,
style: compilerOpts.style as any,
};
Expand Down
15 changes: 11 additions & 4 deletions src/compiler/browser/browser-compile.ts
@@ -1,6 +1,7 @@
import * as d from '../../declarations';
import { catchError } from '@utils';
import { getCompileOptions, getCompilerConfig, getTransformOptions } from './browser-compile-options';
import { getPublicCompilerMeta } from '../transformers/add-component-meta-static';
import { initTypescript } from '../../sys/browser/browser-typescript';
import { transpileModule } from '../transpile/transpile-module';

Expand All @@ -13,7 +14,8 @@ export const compile = async (code: string, opts: d.CompileOptions = {}): Promis
inputFilePath: (typeof opts.file === 'string' ? opts.file.trim() : 'module.tsx'),
outputFilePath: null,
inputOptions: null,
imports: []
imports: [],
componentMeta: []
};

try {
Expand All @@ -38,10 +40,15 @@ export const compile = async (code: string, opts: d.CompileOptions = {}): Promis
results.inputFilePath = transpileResults.sourceFilePath;
}

results.outputFilePath = transpileResults.moduleFile.jsFilePath;
const moduleFile = transpileResults.moduleFile;
if (moduleFile) {
results.outputFilePath = moduleFile.jsFilePath;

if (transpileResults.moduleFile) {
transpileResults.moduleFile.originalImports.forEach(originalImport => {
moduleFile.cmps.forEach(cmp => {
results.componentMeta.push(getPublicCompilerMeta(cmp));
});

moduleFile.originalImports.forEach(originalImport => {
results.imports.push({
path: originalImport
});
Expand Down
1 change: 1 addition & 0 deletions src/compiler/component-lazy/update-to-lazy-component.ts
Expand Up @@ -20,6 +20,7 @@ export const updateToLazyComponent = async (config: d.Config, compilerCtx: d.Com
coreImportPath: '@stencil/core',
componentExport: null,
componentMetadata: null,
proxy: null,
scopeCss: false,
style: 'inline'
};
Expand Down
35 changes: 21 additions & 14 deletions src/compiler/transformers/add-component-meta-static.ts
Expand Up @@ -4,20 +4,9 @@ import ts from 'typescript';


export const addComponentMetaStatic = (cmpNode: ts.ClassDeclaration, cmpMeta: d.ComponentCompilerMeta) => {
const copyCmp = Object.assign({}, cmpMeta);

// no need to copy all compiler meta data to the static getter
delete copyCmp.assetsDirs;
delete copyCmp.dependencies;
delete copyCmp.excludeFromCollection;
delete copyCmp.isCollectionDependency;
delete copyCmp.docs;
delete copyCmp.jsFilePath;
delete copyCmp.potentialCmpRefs;
delete copyCmp.styleDocs;
delete copyCmp.sourceFilePath;

const cmpMetaStaticProp = createStaticGetter('COMPILER_META', convertValueToLiteral(copyCmp));
const publicCompilerMeta = getPublicCompilerMeta(cmpMeta);

const cmpMetaStaticProp = createStaticGetter('COMPILER_META', convertValueToLiteral(publicCompilerMeta));
const classMembers = [...cmpNode.members, cmpMetaStaticProp];

return ts.updateClassDeclaration(
Expand All @@ -30,3 +19,21 @@ export const addComponentMetaStatic = (cmpNode: ts.ClassDeclaration, cmpMeta: d.
classMembers
);
};


export const getPublicCompilerMeta = (cmpMeta: d.ComponentCompilerMeta) => {
const publicCompilerMeta = Object.assign({}, cmpMeta);

// no need to copy all compiler meta data
delete publicCompilerMeta.assetsDirs;
delete publicCompilerMeta.dependencies;
delete publicCompilerMeta.excludeFromCollection;
delete publicCompilerMeta.isCollectionDependency;
delete publicCompilerMeta.docs;
delete publicCompilerMeta.jsFilePath;
delete publicCompilerMeta.potentialCmpRefs;
delete publicCompilerMeta.styleDocs;
delete publicCompilerMeta.sourceFilePath;

return publicCompilerMeta;
};
Expand Up @@ -68,6 +68,7 @@ function transpileCollectionEntry(config: d.Config, compilerCtx: d.CompilerCtx,
coreImportPath: '@stencil/core',
componentExport: null,
componentMetadata: null,
proxy: null,
scopeCss: false,
style: 'inline'
})
Expand Down
Expand Up @@ -15,6 +15,7 @@ export const transformToHydrateComponentText = (compilerCtx: d.CompilerCtx, buil
coreImportPath: '@stencil/core',
componentExport: null,
componentMetadata: null,
proxy: null,
scopeCss: false,
style: 'inline'
};
Expand Down
12 changes: 2 additions & 10 deletions src/compiler/transformers/component-native/native-component.ts
Expand Up @@ -3,11 +3,9 @@ import { addNativeConnectedCallback } from './native-connected-callback';
import { addNativeElementGetter } from './native-element-getter';
import { addWatchers } from '../watcher-meta-transform';
import { createStaticGetter } from '../transform-utils';
import { getScopeId } from '../../style/scope-css';
import { getStyleImportPath } from '../static-to-meta/styles';
import { HTML_ELEMENT, RUNTIME_APIS, addCoreRuntimeApi } from '../core-runtime-apis';
import { removeStaticMetaProperties } from '../remove-static-meta-properties';
import { scopeCss } from '../../../utils/shadow-css';
import { transformHostData } from '../host-data-transform';
import { updateNativeConstructor } from './native-constructor';
import ts from 'typescript';
Expand Down Expand Up @@ -78,19 +76,13 @@ export const addStaticStyle = (transformOpts: d.TransformOptions, classMembers:
}

if (typeof style.styleStr === 'string') {
let styleStr = style.styleStr;

if (transformOpts.scopeCss && cmp.encapsulation === 'scoped') {
const scopeId = getScopeId(cmp.tagName);
styleStr = scopeCss(styleStr, scopeId, false);
}
classMembers.push(createStaticGetter('style', ts.createStringLiteral(styleStr)));
classMembers.push(createStaticGetter('style', ts.createStringLiteral(style.styleStr)));

} else if (typeof style.styleIdentifier === 'string') {
let rtnExpr: ts.Expression;

if (transformOpts.module === ts.ModuleKind.CommonJS && style.externalStyles.length > 0) {
const importPath = getStyleImportPath(cmp, style);
const importPath = getStyleImportPath(style);

rtnExpr = ts.createCall(
ts.createIdentifier('require'),
Expand Down
Expand Up @@ -17,6 +17,7 @@ export const transformToNativeComponentText = (compilerCtx: d.CompilerCtx, build
coreImportPath: '@stencil/core',
componentExport: null,
componentMetadata: null,
proxy: null,
scopeCss: false,
style: 'inline'
};
Expand Down Expand Up @@ -77,7 +78,7 @@ export const nativeComponentTransform = (compilerCtx: d.CompilerCtx, transformOp
// define custom element, and remove "export" from components
tsSourceFile = defineCustomElement(tsSourceFile, moduleFile, transformOpts);

} else if (transformOpts.componentMetadata === 'proxy') {
} else if (transformOpts.proxy === 'defineproperty') {
// exporting as a module, but also add the component proxy fn
tsSourceFile = addModuleMetadataProxies(tsSourceFile, moduleFile);
}
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/transformers/static-to-meta/component.ts
Expand Up @@ -130,7 +130,7 @@ export const parseStaticComponentMeta = (config: d.Config, compilerCtx: d.Compil
cmp.potentialCmpRefs = unique(cmp.potentialCmpRefs);
setComponentBuildConditionals(cmp);

if (transformOpts.componentMetadata === 'static') {
if (transformOpts.componentMetadata === 'compilerstatic') {
cmpNode = addComponentMetaStatic(cmpNode, cmp);
}

Expand Down
12 changes: 4 additions & 8 deletions src/compiler/transformers/static-to-meta/styles.ts
Expand Up @@ -103,7 +103,7 @@ const addEsmStyleImports = (tsSourceFile: ts.SourceFile, moduleFile: d.Module) =
moduleFile.cmps.forEach(cmp => {
cmp.styles.forEach(style => {
if (style.styleIdentifier && style.externalStyles.length > 0) {
styleImports.push(createStyleImport(cmp, style));
styleImports.push(createStyleImport(style));
}
});
});
Expand All @@ -127,10 +127,10 @@ const addEsmStyleImports = (tsSourceFile: ts.SourceFile, moduleFile: d.Module) =
};


const createStyleImport = (cmp: d.ComponentCompilerMeta, style: d.StyleCompiler) => {
const createStyleImport = (style: d.StyleCompiler) => {
const importName = ts.createIdentifier(style.styleIdentifier);

let importPath = getStyleImportPath(cmp, style);
let importPath = getStyleImportPath(style);
if (!importPath.startsWith('.') && !importPath.startsWith('/') && !importPath.startsWith('\\')) {
importPath = './' + importPath;
}
Expand All @@ -146,15 +146,11 @@ const createStyleImport = (cmp: d.ComponentCompilerMeta, style: d.StyleCompiler)
);
};

export const getStyleImportPath = (cmp: d.ComponentCompilerMeta, style: d.StyleCompiler) => {
export const getStyleImportPath = (style: d.StyleCompiler) => {
let importPath = style.externalStyles[0].originalComponentPath;
if (!importPath.startsWith('.') && !importPath.startsWith('/') && !importPath.startsWith('\\')) {
importPath = './' + importPath;
}

if (cmp.encapsulation === 'scoped') {
importPath += '#scopedcss';
}

return importPath;
};
1 change: 1 addition & 0 deletions src/compiler/transpile/transpile-service.ts
Expand Up @@ -120,6 +120,7 @@ const buildTsService = async (config: d.Config, compilerCtx: d.CompilerCtx, buil
coreImportPath: '@stencil/core',
componentExport: null,
componentMetadata: null,
proxy: null,
scopeCss: false,
style: 'inline'
};
Expand Down
4 changes: 3 additions & 1 deletion src/declarations/browser-compile.ts
Expand Up @@ -2,7 +2,8 @@ import * as d from '.';

export interface CompileOptions {
file?: string;
componentMetadata?: 'proxy' | 'static' | string | undefined;
componentMetadata?: 'runtimestatic' | 'compilerstatic' | string | undefined;
proxy?: 'defineproperty' | string | undefined;
module?: 'cjs' | 'esm' | string;
componentExport?: 'customelement' | 'module' | string | undefined;
script?: CompileScript;
Expand All @@ -17,6 +18,7 @@ export interface CompileResults {
outputFilePath: string;
inputOptions: CompileOptions;
imports: { path: string; }[];
componentMeta: any[];
}

export interface CompileScriptMinifyOptions {
Expand Down
3 changes: 2 additions & 1 deletion src/declarations/transpile.ts
Expand Up @@ -22,7 +22,8 @@ export interface ValidateTypesResults {
export interface TransformOptions extends ts.CompilerOptions {
coreImportPath: string;
componentExport: 'lazy' | 'native' | 'customelement' | null;
componentMetadata: 'proxy' | 'static' | null;
componentMetadata: 'runtimestatic' | 'compilerstatic' | null;
proxy: 'defineproperty' | null;
scopeCss: boolean;
style: 'import' | 'inline' | null;
}
3 changes: 2 additions & 1 deletion src/testing/test-transpile.ts
Expand Up @@ -22,7 +22,8 @@ const TRANSPILE_CONFIG: d.Config = {
const DEFAULT_TRANSFORM_OPTS: d.TransformOptions = {
coreImportPath: '@stencil/core',
componentExport: null,
componentMetadata: 'static',
componentMetadata: 'compilerstatic',
proxy: null,
scopeCss: false,
style: null,
transformOutput: 'lazy'
Expand Down
2 changes: 1 addition & 1 deletion test/browser-compile/src/components/app-root/app-root.css
Expand Up @@ -52,7 +52,7 @@ textarea {
}

.source textarea {
height: calc(100% - 195px);
height: calc(100% - 215px);
}

.build textarea {
Expand Down
13 changes: 11 additions & 2 deletions test/browser-compile/src/components/app-root/app-root.tsx
Expand Up @@ -16,6 +16,7 @@ export class AppRoot {
bundledInput: HTMLTextAreaElement;
htmlCodeInput: HTMLTextAreaElement;
componentMetadata: HTMLSelectElement;
proxy: HTMLSelectElement;
module: HTMLSelectElement;
script: HTMLSelectElement;
componentExport: HTMLSelectElement;
Expand Down Expand Up @@ -57,6 +58,7 @@ export class AppRoot {
file: this.file.value,
componentExport: this.componentExport.value,
componentMetadata: this.componentMetadata.value,
proxy: this.componentMetadata.value,
module: this.module.value,
script: this.script.value,
style: this.style.value
Expand Down Expand Up @@ -260,11 +262,18 @@ export class AppRoot {
<option value="inline">inline</option>
</select>
</label>
<label>
<span>Proxy:</span>
<select ref={el => this.proxy = el} onInput={this.compile.bind(this)}>
<option value="defineproperty">defineproperty</option>
<option value="">null</option>
</select>
</label>
<label>
<span>Metadata:</span>
<select ref={el => this.componentMetadata = el} onInput={this.compile.bind(this)}>
<option value="proxy">proxy</option>
<option value="static">static</option>
<option value="">null</option>
<option value="compilerstatic">compilerstatic</option>
</select>
</label>
</div>
Expand Down

0 comments on commit b354444

Please sign in to comment.