Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(compiler): add defineCustomElements method & signature typedef #3619

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(compiler): add defineCustomElements method & signature typedef
This commit adds a `defineCustomElements` function to the `dist-custom-elements` output target that can be used to define all custom elements at once. TBD on if this will always be available, for certain export behaviors, or as a dedicated export behavior
Tanner Reits committed Sep 17, 2022
commit afeab08e8c28011276f6fc4642fe1978dded3425
Original file line number Diff line number Diff line change
@@ -96,6 +96,18 @@ const generateCustomElementsTypesOutput = async (
` rel?: (el: EventTarget, eventName: string, listener: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions) => void;`,
`}`,
`export declare const setPlatformOptions: (opts: SetPlatformOptions) => void;`,
``,
`/**`,
` * Utility to define all custom elements within this package using the tag name provided in the component's source. `,
` * When defining each custom element, it will also check it's safe to define by:`,
` *`,
` * 1. Ensuring the "customElements" registry is available in the global context (window).`,
` * 2. The component tag name is not already defined.`,
` *`,
` * Use the standard [customElements.define()](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define) `,
` * method instead to define custom elements individually, or to provide a different tag name.`,
` */`,
`export declare const defineCustomElements: (opts?: any) => void;`,
];

const componentsDtsRelPath = relDts(outputTarget.dir!, join(typesDir, 'components.d.ts'));
26 changes: 23 additions & 3 deletions src/compiler/output-targets/dist-custom-elements/index.ts
Original file line number Diff line number Diff line change
@@ -190,6 +190,8 @@ export const addCustomElementInputs = (
const components = buildCtx.components;
// an array to store the imports of these modules that we're going to add to our entry chunk
const indexImports: string[] = [];
const indexExports: string[] = [];
const exportNames: string[] = [];

components.forEach((cmp) => {
const exp: string[] = [];
@@ -200,7 +202,7 @@ export const addCustomElementInputs = (

if (cmp.isPlain) {
exp.push(`export { ${importName} as ${exportName} } from '${cmp.sourceFilePath}';`);
indexImports.push(`export { {${exportName} } from '${coreKey}';`);
indexExports.push(`export { {${exportName} } from '${coreKey}';`);
} else {
// the `importName` may collide with the `exportName`, alias it just in case it does with `importAs`
exp.push(
@@ -215,19 +217,37 @@ export const addCustomElementInputs = (
// correct virtual module, if we instead referenced, for instance,
// `cmp.sourceFilePath`, we would end up with duplicated modules in our
// output.
indexImports.push(
indexExports.push(
`export { ${exportName}, defineCustomElement as defineCustomElement${exportName} } from '${coreKey}';`
);
}

indexImports.push(`import { ${exportName} } from '${coreKey}';`);
exportNames.push(exportName);

bundleOpts.inputs[cmp.tagName] = coreKey;
bundleOpts.loader![coreKey] = exp.join('\n');
});

bundleOpts.loader!['\0core'] += indexImports.join('\n');

// Only re-export component definitions if the barrel export behavior is set
if (outputTarget.customElementsExportBehavior === 'single-export-module') {
bundleOpts.loader!['\0core'] += indexImports.join('\n');
bundleOpts.loader!['\0core'] += indexExports.join('\n');
}

bundleOpts.loader!['\0core'] += `
export const defineCustomElements = (opts) => {
if (typeof customElements !== 'undefined') {
[
${exportNames.join(',\n ')}
].forEach(cmp => {
if (!customElements.get(cmp.is)) {
customElements.define(cmp.is, cmp, opts);
}
});
}
};`;
};

/**