@embeddable.com/sdk-core
Version:
Core Embeddable SDK module responsible for web-components bundling and publishing.
128 lines (108 loc) • 3.45 kB
text/typescript
import * as fs from "node:fs/promises";
import * as path from "node:path";
import * as vite from "vite";
import ora from "ora";
import { ResolvedEmbeddableConfig } from "./defineConfig";
import {
findFiles,
getComponentLibraryConfig,
getContentHash,
} from "@embeddable.com/sdk-utils";
import fg from "fast-glob";
export const EMB_TYPE_FILE_REGEX = /^(.*)\.type\.emb\.[jt]s$/;
export const EMB_OPTIONS_FILE_REGEX = /^(.*)\.options\.emb\.[jt]s$/;
export default async (ctx: ResolvedEmbeddableConfig) => {
const progress = ora("Building types...").start();
await generate(ctx);
await build(ctx);
await cleanup(ctx);
progress.succeed("Types built completed");
};
async function generate(ctx: ResolvedEmbeddableConfig) {
const typeFiles = await findFiles(ctx.client.srcDir, EMB_TYPE_FILE_REGEX);
const optionsFiles = await findFiles(
ctx.client.srcDir,
EMB_OPTIONS_FILE_REGEX,
);
const additionalImports =
await getAdditionalImportsFromInstalledLibraries(ctx);
const repositoryTypeImports = typeFiles
.concat(optionsFiles)
.map(
([_fileName, filePath]) =>
`import '../${path
.relative(ctx.client.rootDir, filePath)
.replaceAll("\\", "/")}';`,
)
.join("\n");
const typeImports = additionalImports.join("\n") + repositoryTypeImports;
await fs.writeFile(
path.resolve(
ctx.client.buildDir,
ctx.outputOptions.typesEntryPointFilename,
),
typeImports,
);
}
async function build(ctx: ResolvedEmbeddableConfig) {
const typesFilePath = path.resolve(
ctx.client.buildDir,
ctx.outputOptions.typesEntryPointFilename,
);
await vite.build({
logLevel: "error",
build: {
emptyOutDir: false,
sourcemap: ctx.dev?.watch ? (false as const) : true, // No sourcemaps for types in dev
minify: !ctx.dev?.watch, // No minification in dev
rollupOptions: ctx.dev?.watch ? { treeshake: false } : undefined,
lib: {
entry: typesFilePath,
formats: ["es"],
fileName: "embeddable-types",
},
outDir: ctx.client.buildDir,
},
});
if (!ctx.dev?.watch) {
const fileContent = await fs.readFile(typesFilePath, "utf8");
const fileHash = getContentHash(fileContent);
const fileName = `embeddable-types-${fileHash}.js`;
await fs.rename(
path.resolve(ctx.client.buildDir, "embeddable-types.js"),
path.resolve(ctx.client.buildDir, fileName),
);
}
}
async function cleanup(ctx: ResolvedEmbeddableConfig) {
await fs.rm(
path.resolve(ctx.client.buildDir, "embeddable-types-entry-point.js"),
);
}
async function getAdditionalImportsFromInstalledLibraries(
ctx: ResolvedEmbeddableConfig,
) {
const componentLibraries = ctx.client.componentLibraries;
const additionalImports: string[] = [];
for (const componentLibrary of componentLibraries) {
const { libraryName } = getComponentLibraryConfig(componentLibrary);
try {
fg.sync(
path.resolve(
ctx.client.rootDir,
"node_modules",
libraryName,
"dist",
"embeddable-types-*.js",
),
).forEach((file: string) => {
const fileName = path.basename(file);
additionalImports.push(`import '${libraryName}/dist/${fileName}';`);
});
} catch (e) {
console.error(`Can't load component library: ${libraryName}`, e);
throw e;
}
}
return additionalImports;
}