UNPKG

nitropage

Version:

A free and open source, extensible visual page builder based on SolidStart.

219 lines (210 loc) 6.74 kB
// src/build/start.ts import { defineConfig as defineConfig_ } from "@solidjs/start/config"; import { uniq } from "es-toolkit"; import lazyPlusPlugin from "solid-lazy-plus/vite"; import { mergeConfig } from "vite"; // src/lib/server/path.ts import { join, resolve } from "path"; import { fileURLToPath } from "url"; // src/lib/server/util/env.ts var env = (key) => process.env[key] || void 0; env.boolean = (key) => { const v = env(key); if (v == null) return; return v === "1" || v === "true"; }; env.number = (key) => { const v = Number(env(key)); if (Number.isNaN(v)) return; return v; }; // src/lib/server/path.ts var devPublicPath = join(process.cwd(), "public"); var dirname = fileURLToPath(new URL(".", import.meta?.url)); var outputDir = dirname.slice(0, dirname.lastIndexOf("/server/")); var publicPath = import.meta.env?.PROD ? resolve(outputDir, "public") : devPublicPath; var runtimePath = env("NP_RUNTIME_PATH") ?? "./src/runtime"; // src/build/lib.ts import chokidar from "chokidar"; import crypto from "crypto"; import { debounce } from "es-toolkit"; import { readFile, writeFile } from "fs/promises"; import { relative, resolve as resolve2 } from "path"; var resolveCwd = (...path) => resolve2(process.cwd(), ...path); var fsWatcher; var initVinxiReload = () => { if (fsWatcher) fsWatcher.close(); fsWatcher = chokidar.watch( [ resolveCwd(runtimePath, "server.config.ts"), resolveCwd(runtimePath, "plugin.ts") ].filter(Boolean), { ignoreInitial: true, persistent: true } ); fsWatcher.on("all", reloadVinxi); }; var reloadVinxi = debounce(async () => { const appConfigPath = resolveCwd("app.config.ts"); const content = await readFile(appConfigPath, "utf-8"); await writeFile(appConfigPath, content); }, 250); var hashCache = {}; var cwd = process.cwd(); var manualChunks = (id) => { if (!id.endsWith("module.css")) { return; } const relativeId = relative(cwd, id); const hash = hashCache[id] ??= crypto.createHash("sha256").update(relativeId).digest("hex").slice(0, 10); return hash; }; // src/build/solidRealmsPatch.ts import MagicString from "magic-string"; var isPlainObjectTmpl = ` function isPlainObject(obj) { if (obj.constructor === undefined) return true; const proto = obj.constructor.prototype; if (typeof proto !== "object") return false; if (proto.hasOwnProperty('isPrototypeOf') === false) return false; return true; };`; var solidRealmsPatchPlugin = () => { const regex = new RegExp("(solid-js/store/dist/store)|(solid-js_store)\\.js"); return { name: "solid-realms-patch", transform(code, id, options) { if (options?.ssr) return; if (!id.match(regex)) return; const s = new MagicString(code); s.replace("proto === Object.prototype", "isPlainObject(obj)"); if (!s.hasChanged) { console.error("Failed to patch Solid isWrappable!"); return; } s.replace( "function isWrappable", `${isPlainObjectTmpl} function isWrappable` ); const newCode = s.toString(); if (!newCode.includes("function isPlainObject(obj)")) { console.error("Failed to patch Solid isWrappable!"); return; } const result = { code: newCode, map: s.generateMap() }; return result; } }; }; // src/build/start.ts var defineConfig = (opts) => { const { vite, ...optsRest } = opts; const { plugins: serverPlugins, ...serverRest } = optsRest.server ??= {}; const isBuild = process.env.NODE_ENV === "production"; const isMonoRepo = import.meta.url.endsWith( "packages/nitropage/dist/start/start.js" ); if (!isBuild) { initVinxiReload(); } return defineConfig_({ middleware: resolveCwd(runtimePath, "middleware.ts"), vite(params) { const { router } = params; const user = vite ? typeof vite === "function" ? vite(params) : vite : {}; const noOptimize = ["nitropage", "@npio/server"]; let internalLibraries = [ "@lufrai/quill", "isobject", "@paralleldrive/cuid2" ]; if (!isMonoRepo) { internalLibraries = internalLibraries.map((v) => `nitropage > ` + v); } const optimizeOnClient = ["clsx", ...internalLibraries]; const solidLibraries = [ "@corvu/resizable", "@kobalte/core", "@modular-forms/solid", "corvu", "fela-plugin-multiple-selectors", "fela-plugin-prefixer", "serfu", "solid-lazy-plus" ]; const serverLibraries = ["bcrypt", "fsevents", "minio", "sharp"]; const serverBundleLibraries = isBuild ? ["dotenv"] : []; const userOutput = user.build?.rollupOptions?.output; if (userOutput && !Array.isArray(userOutput) && userOutput.manualChunks) { console.warn( "Custom manualChunks is currently not supported and will be disabled!" ); delete userOutput.manualChunks; } const merged = mergeConfig( { build: { assetsInlineLimit: (path) => { if (path.match(/\.(j|t)sx?$/)) { return false; } return; }, rollupOptions: { output: { manualChunks } } }, resolve: { alias: { "#client": resolveCwd( runtimePath, router === "client" ? "client.config.hot.ts" : "client.config.tsx" ) } }, plugins: [solidRealmsPatchPlugin(), lazyPlusPlugin({ router })], optimizeDeps: { include: optimizeOnClient, exclude: uniq([ ...noOptimize, ...solidLibraries, ...serverLibraries ]) }, ssr: { external: uniq([...serverLibraries, ...optimizeOnClient]), noExternal: uniq([...serverBundleLibraries, ...solidLibraries]) } }, user ); return merged; }, ...optsRest, server: { plugins: serverPlugins ?? [resolveCwd(runtimePath, "plugin.ts")], compressPublicAssets: false, esbuild: { options: { // Building projects outside of the monorepo fails without this // Nitro doesn't transpile typescript files in dependencies imported by plugins // https://github.com/nitrojs/nitro/blob/231c516e866a43c7e437e651c97ac14218ce1300/src/rollup/plugins/esbuild.ts#L42 exclude: [/node_modules(?!\/(.pnpm\/)?(nitropage|@npio))/], target: "esnext" } }, ...serverRest } }); }; export { defineConfig };