Skip to content

Commit 854d498

Browse files
authoredJul 13, 2022
fix(compiler): fix typedef file generated for dist-custom-elements (#3468)
This fixes the typedef file generated for the `index.js` file produced by `dist-custom-elements`. Previously it was mistakenly assuming that the path to a component's `d.ts` file could be generated on the basis of the `tag` set on the component. This _is_ the case if the component's filename is equal to it's tag, but there is no requirement that that be the case. This changes the way that the relative path from `${outputDir}/components/index.d.ts` to the `.d.ts` file for a specific component is generated. Previously we were doing something like: ```ts ${outputDir}/types/components/${component.tagName}/${component.tagName} ``` This doesn't work if a component is saved in `src/components/button/button.tsx` but has a tag like `custom-button`. So to fix this we can instead: - find the relative path from the source root to the component, giving us e.g. `components/button/button.tsx` - join that relative path with the relative path from where `index.d.ts` is going to be saved (`${outputDir}/components/index.d.ts`) to the directory where types are written (e.g. `${outputDir}/types`) This will give us an import in `index.d.ts` that looks like: ```ts export { Button as CustomButton } from '../types/components/button/button.tsx'; ```
1 parent b9fbe85 commit 854d498

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed
 

‎src/compiler/output-targets/dist-custom-elements/custom-elements-types.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const generateCustomElementsTypesOutput = async (
4545
// the path where we're going to write the typedef for the whole dist-custom-elements output
4646
const customElementsDtsPath = join(outputTarget.dir!, 'index.d.ts');
4747
// the directory where types for the individual components are written
48-
const componentsTypeDirectoryPath = relative(outputTarget.dir!, join(typesDir, 'components'));
48+
const componentsTypeDirectoryRelPath = relative(outputTarget.dir!, typesDir);
4949

5050
const components = buildCtx.components.filter((m) => !m.isCollectionDependency);
5151

@@ -56,7 +56,14 @@ const generateCustomElementsTypesOutput = async (
5656
const importName = component.componentClassName;
5757
// typedefs for individual components can be found under paths like
5858
// $TYPES_DIR/components/my-component/my-component.d.ts
59-
const componentDTSPath = join(componentsTypeDirectoryPath, component.tagName, component.tagName);
59+
//
60+
// To construct this path we:
61+
//
62+
// - get the relative path to the component's source file from the source directory
63+
// - join that relative path to the relative path from the `index.d.ts` file to the
64+
// directory where typedefs are saved
65+
const componentSourceRelPath = relative(config.srcDir, component.sourceFilePath).replace('.tsx', '');
66+
const componentDTSPath = join(componentsTypeDirectoryRelPath, componentSourceRelPath);
6067

6168
return `export { ${importName} as ${exportName} } from '${componentDTSPath}';`;
6269
}),

‎src/compiler/output-targets/dist-custom-elements/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export const addCustomElementInputs = (buildCtx: d.BuildCtx, bundleOpts: BundleO
204204
exp.push(`export const ${exportName} = ${importAs};`);
205205
exp.push(`export const defineCustomElement = cmpDefCustomEle;`);
206206

207-
// Here we push an export (with a rename for `defineCustomElement` for
207+
// Here we push an export (with a rename for `defineCustomElement`) for
208208
// this component onto our array which references the `coreKey` (prefixed
209209
// with `\0`). We have to do this so that our import is referencing the
210210
// correct virtual module, if we instead referenced, for instance,

‎src/compiler/output-targets/test/custom-elements-types.spec.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,16 @@ const setup = () => {
3131

3232
describe('Custom Elements Typedef generation', () => {
3333
it('should generate an index.d.ts file corresponding to the index.js file', async () => {
34-
const componentOne = stubComponentCompilerMeta();
34+
// this component tests the 'happy path' of a component's filename coinciding with its
35+
// tag name
36+
const componentOne = stubComponentCompilerMeta({
37+
tagName: 'my-component',
38+
sourceFilePath: '/src/components/my-component/my-component.tsx',
39+
});
40+
// this component tests that we correctly resolve its path when the component tag does
41+
// not match its filename
3542
const componentTwo = stubComponentCompilerMeta({
43+
sourceFilePath: '/src/components/the-other-component/my-real-best-component.tsx',
3644
componentClassName: 'MyBestComponent',
3745
tagName: 'my-best-component',
3846
});
@@ -47,11 +55,11 @@ describe('Custom Elements Typedef generation', () => {
4755

4856
const expectedTypedefOutput = [
4957
'/* TestApp custom elements */',
50-
`export { StubCmp as StubCmp } from '${join(componentsTypeDirectoryPath, 'stub-cmp', 'stub-cmp')}';`,
58+
`export { StubCmp as MyComponent } from '${join(componentsTypeDirectoryPath, 'my-component', 'my-component')}';`,
5159
`export { MyBestComponent as MyBestComponent } from '${join(
5260
componentsTypeDirectoryPath,
53-
'my-best-component',
54-
'my-best-component'
61+
'the-other-component',
62+
'my-real-best-component'
5563
)}';`,
5664
'',
5765
'/**',

0 commit comments

Comments
 (0)
Please sign in to comment.