polen
Version:
A framework for delightful GraphQL developer portals
164 lines • 6.96 kB
JavaScript
import { Vite } from '#dep/vite/index';
import { ViteVirtual } from '#lib/vite-virtual/index';
import { debugPolen } from '#singletons/debug';
import { Fs, Path } from '@wollybeard/kit';
import packageJson from '../../../../package.json' with { type: 'json' };
import { isKitUnusedExternalImport, isRadixModuleLevelDirective } from '../log-filters.js';
import { polenVirtual } from '../vi.js';
export const Build = (config) => {
const debug = debugPolen.sub(`vite-build`);
debug(`construct`);
// let viteConfigResolved: Vite.ResolvedConfig
// const outDir = Path.join(config.paths.project.rootDir, `dist`)
return [
Manifest(config),
BuildManifest(config),
{
name: `polen:build-client`,
apply: `build`,
applyToEnvironment: Vite.isEnvironmentClient,
// HACK: For some reason the ?url import doesn't lead to a rewrite in the build.
// Furthermore we need to rely on the manifest to get its final name because it is
// generated by the client build before the server build.
// However, we still need the asset in development.
// But we cannot exclude the import in build.
// So this does that for us but it is really hacky.
// FIXME
// 1. Raise issue about having ?url lead to expected build path rewrite?
// 2. And: Move asset generation to server build?
// 3. And/or: Use Vite Environments API?
generateBundle(_, bundle, isWrite) {
if (isWrite) {
for (const chunkOrAsset of Object.values(bundle)) {
if (chunkOrAsset.type === `asset` && chunkOrAsset.names.includes(`entry.client.jsx`)) {
delete bundle[chunkOrAsset.fileName];
}
}
}
},
onLog(_, message) {
if (isRadixModuleLevelDirective(message))
return;
if (isKitUnusedExternalImport(message))
return;
},
config() {
return {
environments: {
client: {
build: {
manifest: true,
rollupOptions: {
input: [config.paths.framework.template.absolute.client.entrypoint],
external: id => id.startsWith(`node:`),
onwarn(message) {
if (isKitUnusedExternalImport(message))
return;
},
},
},
},
},
};
},
},
{
name: `polen-ssr-build`,
apply: `build`,
applyToEnvironment: Vite.isEnvironmentSsr,
config() {
return {
// Have to configure this here??
// @see https://github.com/vitejs/vite/issues/20098
ssr: {
noExternal: true,
},
environments: {
ssr: {
build: {
// NO EFFECT (see above)
// Bundle all dependencies instead of externalizing them
// noExternal: true,
// The SSR build will follow the client build, and emptying the dir would lose the output of the client build.
emptyOutDir: false,
rollupOptions: {
input: [config.paths.framework.template.absolute.server.entrypoint],
output: {
entryFileNames: config.paths.project.relative.build.relative.serverEntrypoint,
},
},
},
},
},
};
},
onLog(_, message) {
if (isKitUnusedExternalImport(message))
return;
},
// generateBundle(_, bundle, isWrite) {
// if (isWrite) {
// for (const chunkOrAsset of Object.values(bundle)) {
// console.log(chunkOrAsset)
// if (chunkOrAsset.type === `chunk`) {
// if (chunkOrAsset.facadeModuleId === viClientManifest.resolved) {
// delete bundle[chunkOrAsset.fileName]
// }
// }
// }
// }
// },
async closeBundle() {
/**
* clean up the manifest. Was generated by client. For server build. Not needed after (unless debugging).
*/
if (!config.advanced.debug) {
await Fs.remove(Path.join(config.paths.project.absolute.build.root, `.vite`));
}
},
},
];
};
const viClientManifest = polenVirtual([`vite`, `client`, `manifest`]);
const Manifest = (config) => {
let configEnv;
return {
name: `polen-manifest`,
config(_, configEnv_) {
configEnv = configEnv_;
},
...ViteVirtual.IdentifiedLoader.toHooks({
identifier: viClientManifest,
loader: async () => {
// In development just return an empty manifest
if (configEnv.mode === Vite.ModeName.development) {
return `export default {}`;
}
const manifestPath = Path.join(config.paths.project.absolute.build.root, `.vite`, `manifest.json`);
const module = await import(manifestPath, { with: { type: `json` } });
return `export default ${JSON.stringify(module.default)}`;
},
}),
};
};
const BuildManifest = (config) => {
return {
name: `polen:build-manifest`,
apply: `build`,
applyToEnvironment: Vite.isEnvironmentClient,
async generateBundle() {
const manifest = {
type: config.build.architecture === `ssr` ? `ssr` : `ssg`,
version: packageJson.version,
basePath: config.build.base ?? `/`,
};
// Emit the manifest as an asset
this.emitFile({
type: `asset`,
fileName: `.polen/build.json`,
source: JSON.stringify(manifest, null, 2),
});
},
};
};
//# sourceMappingURL=build.js.map