Skip to content

Commit

Permalink
chore: Add TypeScript declaration generation for build outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
klarstrup committed Sep 6, 2024
1 parent 1fe361c commit 1d04c06
Showing 1 changed file with 41 additions and 4 deletions.
45 changes: 41 additions & 4 deletions esbuild.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {build, context} from 'esbuild';
import {stylusLoader} from 'esbuild-stylus-loader';
import {readFileSync} from 'fs';
import {writeFile} from 'fs/promises';
import nib from 'nib';
import path from 'path';
import ts from 'typescript';
import * as url from 'url';
import packageJson from './package.json' assert {type: 'json'};

Expand Down Expand Up @@ -105,7 +107,13 @@ switch (process.argv[2]) {
case 'build': {
const buildResults = await Promise.all(
bundles
.map(({name, input, output}) => [
.map(({name, input, output, pkg}) => [
name &&
emitDeclaration({
inFile: path.join(libDir, input),
outFile: path.join(distDir, output + '.d.ts'),
pkg
}),
name &&
build({
...commonOptions,
Expand Down Expand Up @@ -149,13 +157,14 @@ switch (process.argv[2]) {
const modulePackageJsons = {};

for (const {warnings, errors, metafile} of buildResults) {
if (warnings.length) {
if (warnings?.length) {
for (const warning of warnings) console.warn(warning);
}
if (errors.length) {
if (errors?.length) {
for (const error of errors) console.error(error);
break;
}
if (!metafile) continue;
for (const [path, output] of Object.entries(metafile.outputs)) {
if (!output.entryPoint) continue;
const moduleDir = path.match(/dist\/(.+)\//)[1];
Expand All @@ -170,10 +179,14 @@ switch (process.argv[2]) {
const moduleJson = modulePackageJsons[moduleDir];

const fileName = path.match(/dist\/(.+)\/(.+)/)[2];
if (fileName.endsWith('.cjs.js')) moduleJson.main = fileName;
if (fileName.endsWith('.cjs.js')) {
moduleJson.main = fileName;
moduleJson.types = fileName.replace('.cjs.js', '.d.ts');
}
if (fileName.endsWith('.es.js')) {
moduleJson.module = fileName;
moduleJson['jsnext:main'] = fileName;
moduleJson.types = fileName.replace('.es.js', '.d.ts');
}

const externalsSet = new Set();
Expand All @@ -197,3 +210,27 @@ switch (process.argv[2]) {
break;
}
}

function emitDeclaration({inFile, outFile, pkg}) {
const options = {
...readFileSync(path.join(__dirname, 'tsconfig.json'), 'utf-8'),
declaration: true,
emitDeclarationOnly: true,
outFile
};

const host = ts.createCompilerHost(options);
const writeFile = host.writeFile.bind(host);
host.writeFile = (path, code) =>
writeFile(
path,
code.replace(
`declare module "${inFile
.replace(__dirname, '')
.replace('.ts', '')}" {`,
`declare module "${pkg.name}" {`
)
);

ts.createProgram([inFile], options, host).emit();
}

0 comments on commit 1d04c06

Please sign in to comment.