Skip to content

Commit

Permalink
fix(docs-json): use dts-bundle-generator to bundle types for docs-json (
Browse files Browse the repository at this point in the history
#4619)

This fixes an issue that crops up when building documentation using the
`docs-json` output target.

When #4212 was merged it included a change to
`src/declarations/stencil-public-docs.ts` which involved adding imports
from private Stencil type declarations. Previously this file had no
imports and so was "standalone", however, after this change it now
imported some types from `"./private"`.

This created a problem when using the `docs-json` output target because
when building a Stencil project with that output target enabled the
compiled typedef corresponding to `stencil-public-docs.ts` is copied out
of `node_modules` and into the users project. See here:

https://github.com/ionic-team/stencil/blob/43cfc584c8fbcb77122cbf2a813b1a0303085dce/src/compiler/docs/json/index.ts#L16-L18

This commit fixes the issue by using `dts-bundle-generator` to inline
the types imported by `stencil-public-docs.ts` so that the resulting
`.d.ts` file has no external dependencies and is therefore portable.
  • Loading branch information
alicewriteswrongs committed Jul 27, 2023
1 parent a5134df commit 6ba3249
Show file tree
Hide file tree
Showing 4 changed files with 362 additions and 252 deletions.
13 changes: 11 additions & 2 deletions scripts/bundles/internal.ts
@@ -1,7 +1,7 @@
import fs from 'fs-extra';
import { join } from 'path';

import { cleanDts } from '../utils/bundle-dts';
import { bundleDts, cleanDts } from '../utils/bundle-dts';
import type { BuildOptions } from '../utils/options';
import { writePkgJson } from '../utils/write-pkg-json';
import { internalAppData } from './internal-app-data';
Expand Down Expand Up @@ -70,7 +70,16 @@ async function copyStencilInternalDts(opts: BuildOptions, outputInternalDir: str
// @stencil/core/internal/stencil-public-docs.d.ts
const docsDtsSrcPath = join(declarationsInputDir, 'stencil-public-docs.d.ts');
const docsDtsDestPath = join(outputInternalDir, 'stencil-public-docs.d.ts');
const docsDts = cleanDts(await fs.readFile(docsDtsSrcPath, 'utf8'));
// We bundle with `dts-bundle-generator` here to ensure that when the `docs-json`
// OT writes a `docs.d.ts` file based on this file it is fully portable.
const docsDts = await bundleDts(opts, docsDtsSrcPath, {
// we want to suppress the `dts-bundle-generator` banner here because we do
// our own later on
noBanner: true,
// we also don't want the types which are inlined into our bundled file to
// be re-exported, which will change the 'surface' of the module
exportReferencedTypes: false,
});
await fs.writeFile(docsDtsDestPath, docsDts);

// @stencil/core/internal/stencil-public-runtime.d.ts
Expand Down
30 changes: 21 additions & 9 deletions scripts/utils/bundle-dts.ts
@@ -1,9 +1,21 @@
import { generateDtsBundle } from 'dts-bundle-generator/dist/bundle-generator.js';
import { EntryPointConfig, generateDtsBundle, OutputOptions } from 'dts-bundle-generator/dist/bundle-generator.js';
import fs from 'fs-extra';

import { BuildOptions } from './options';

export async function bundleDts(opts: BuildOptions, inputFile: string) {
/**
* A thin wrapper for `dts-bundle-generator` which uses our build options to
* set a few things up
*
* **Note**: this file caches its output to disk, and will return any
* previously cached file if not in a prod environment!
*
* @param opts an object holding information about the current build of Stencil
* @param inputFile the path to the file which should be bundled
* @param outputOptions options for bundling the file
* @returns a string containing the bundled typedef
*/
export async function bundleDts(opts: BuildOptions, inputFile: string, outputOptions?: OutputOptions): Promise<string> {
const cachedDtsOutput = inputFile + '-bundled.d.ts';

if (!opts.isProd) {
Expand All @@ -12,15 +24,15 @@ export async function bundleDts(opts: BuildOptions, inputFile: string) {
} catch (e) {}
}

const entries = [
{
filePath: inputFile,
},
];
const config: EntryPointConfig = {
filePath: inputFile,
};

let outputCode = generateDtsBundle(entries).join('\n');
if (outputOptions) {
config.output = outputOptions;
}

outputCode = cleanDts(outputCode);
const outputCode = cleanDts(generateDtsBundle([config]).join('\n'));

await fs.writeFile(cachedDtsOutput, outputCode);

Expand Down
9 changes: 8 additions & 1 deletion src/compiler/docs/json/index.ts
Expand Up @@ -14,7 +14,14 @@ export const generateJsonDocs = async (
return;
}
const docsDtsPath = join(config.sys.getCompilerExecutingPath(), '..', '..', 'internal', 'stencil-public-docs.d.ts');
const docsDts = await compilerCtx.fs.readFile(docsDtsPath);
let docsDts = await compilerCtx.fs.readFile(docsDtsPath);
// this file was written by dts-bundle-generator, which uses tabs for
// indentation. Instead, let's replace those with spaces!
docsDts = docsDts
.split('\n')
.map((line) => line.replace(/\t/g, ' '))
.join('\n');

const typesContent = `
/**
* This is an autogenerated file created by the Stencil compiler.
Expand Down

0 comments on commit 6ba3249

Please sign in to comment.