@sanity/cli-build 7.0.0 → 7.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -29,7 +29,13 @@ import { resolveVendorBuildConfig } from './resolveVendorBuildConfig.js';
|
|
|
29
29
|
const outputDir = path.resolve(outDir || defaultOutputDir);
|
|
30
30
|
const installedSdkVersion = await getLocalPackageVersion('@sanity/sdk-react', workDir);
|
|
31
31
|
const installedSanityVersion = await getLocalPackageVersion('sanity', workDir);
|
|
32
|
-
|
|
32
|
+
// A Media Library config ships no SDK app — its inputs are island-rendered
|
|
33
|
+
// by `sanity`, so verify that instead and skip the SDK auto-update
|
|
34
|
+
// machinery. Checked via the `appType` discriminator, not the mere presence
|
|
35
|
+
// of a config: a future `ConfigSchema` member must not inherit these
|
|
36
|
+
// media-library build semantics by default.
|
|
37
|
+
const isMediaLibraryConfigBuild = options.exposes?.config?.appType === 'media-library';
|
|
38
|
+
if (!installedSdkVersion && !isMediaLibraryConfigBuild) {
|
|
33
39
|
output.error(`Failed to find installed @sanity/sdk-react version`, {
|
|
34
40
|
exit: exitCodes.RUNTIME_ERROR
|
|
35
41
|
});
|
|
@@ -37,9 +43,17 @@ import { resolveVendorBuildConfig } from './resolveVendorBuildConfig.js';
|
|
|
37
43
|
mfManifest: undefined
|
|
38
44
|
};
|
|
39
45
|
}
|
|
46
|
+
if (isMediaLibraryConfigBuild && !installedSanityVersion) {
|
|
47
|
+
output.error(`Failed to find installed sanity version`, {
|
|
48
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
mfManifest: undefined
|
|
52
|
+
};
|
|
53
|
+
}
|
|
40
54
|
let autoUpdatesImports = {};
|
|
41
55
|
let autoUpdatesCssUrls = [];
|
|
42
|
-
if (autoUpdatesEnabled) {
|
|
56
|
+
if (autoUpdatesEnabled && !isMediaLibraryConfigBuild) {
|
|
43
57
|
// Get the clean version without build metadata: https://semver.org/#spec-item-10
|
|
44
58
|
const cleanSDKVersion = semverParse(installedSdkVersion)?.version;
|
|
45
59
|
if (!cleanSDKVersion) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/build/buildApp.ts"],"sourcesContent":["import {rm} from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {exitCodes} from '@sanity/cli-core/ExitCodes'\nimport {getLocalPackageVersion} from '@sanity/cli-core/package-manager'\nimport {getCliTelemetry} from '@sanity/cli-core/telemetry'\nimport {type CliConfig, type Output, type UserViteConfig} from '@sanity/cli-core/types'\nimport {isInteractive} from '@sanity/cli-core/util'\nimport {confirm, getTimer, logSymbols, spinner, type SpinnerInstance} from '@sanity/cli-core/ux'\nimport {readBuiltManifest, type WorkbenchExposes} from '@sanity/workbench-cli/build'\nimport {parse as semverParse} from 'semver'\n\nimport {AppBuildTrace} from '../../telemetry/build.telemetry.js'\nimport {CompareDependencyVersionsResult} from '../../util/compareDependencyVersions.js'\nimport {formatModuleSizes, sortModulesBySize} from '../../util/moduleFormatUtils.js'\nimport {buildDebug} from './buildDebug.js'\nimport {buildStaticFiles} from './buildStaticFiles.js'\nimport {BuildEventListener} from './eventListener.js'\nimport {getAutoUpdatesCssUrls, getAutoUpdatesImportMap} from './getAutoUpdatesImportMap.js'\nimport {getAppEnvironmentVariables} from './getEnvironmentVariables.js'\nimport {handlePrereleaseVersions} from './handlePrereleaseVersions.js'\nimport {resolveVendorBuildConfig} from './resolveVendorBuildConfig.js'\n\nexport type BuildAppEventListener = BuildEventListener\nexport interface BuildOptions {\n appId: string | undefined\n appTitle: string | undefined\n autoUpdatesEnabled: boolean\n checkAppId: () => void\n compareDependencyVersions: (\n packages: {name: string; version: string}[],\n ) => Promise<CompareDependencyVersionsResult>\n determineBasePath: () => string\n entry: string | undefined\n eventListener: Partial<BuildAppEventListener>\n isWorkbenchApp: boolean\n minify: boolean\n outDir: string | undefined\n output: Output\n reactCompiler: CliConfig['reactCompiler']\n schemaExtraction: CliConfig['schemaExtraction']\n sourceMap: boolean\n stats: boolean\n unattendedMode: boolean\n vite: UserViteConfig | undefined\n workDir: string\n\n exposes?: WorkbenchExposes\n /**\n * The build is running under Sanity Blueprints (invoked programmatically by\n * `@sanity/runtime-cli`), so emit the statically-imported resource-bindings\n * module Brett rewrites at deploy. Defaults to `false`, so a normal\n * `sanity build`/`dev`/`preview` never emits it.\n */\n isBlueprints?: boolean\n\n /** The workbench app's bus identity (`__SANITY_APP_ID__`). */\n workbenchAppId?: string\n}\n\n/**\n * Internal build app that avoids depending on flags for CLI config.\n * @param options - options for the build\n */\nexport async function buildApp(\n options: BuildOptions,\n): Promise<{mfManifest: Record<string, unknown> | undefined}> {\n buildDebug(`Building app`)\n\n const {appId, determineBasePath, eventListener, outDir, output, workDir} = options\n let {autoUpdatesEnabled} = options\n const unattendedMode = options.unattendedMode\n\n const timer = getTimer()\n\n const defaultOutputDir = path.resolve(path.join(workDir, 'dist'))\n const outputDir = path.resolve(outDir || defaultOutputDir)\n\n const installedSdkVersion = await getLocalPackageVersion('@sanity/sdk-react', workDir)\n const installedSanityVersion = await getLocalPackageVersion('sanity', workDir)\n\n if (!installedSdkVersion) {\n output.error(`Failed to find installed @sanity/sdk-react version`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n return {mfManifest: undefined}\n }\n\n let autoUpdatesImports = {}\n let autoUpdatesCssUrls: string[] = []\n\n if (autoUpdatesEnabled) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSDKVersion = semverParse(installedSdkVersion)?.version\n if (!cleanSDKVersion) {\n output.error(`Failed to parse installed SDK version: ${installedSdkVersion}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n return {mfManifest: undefined}\n }\n\n // Sanity might not be installed, but if it is, we want to auto update it.\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n\n const autoUpdatedPackages = [\n {name: '@sanity/sdk', version: cleanSDKVersion},\n {name: '@sanity/sdk-react', version: cleanSDKVersion},\n ...(cleanSanityVersion\n ? [{cssFile: 'index.css', name: 'sanity' as const, version: cleanSanityVersion}]\n : []),\n ]\n autoUpdatesImports = getAutoUpdatesImportMap(autoUpdatedPackages, {appId})\n autoUpdatesCssUrls = getAutoUpdatesCssUrls(autoUpdatedPackages, {appId})\n\n output.log(`${logSymbols.info} Building with auto-updates enabled`)\n\n // Warn if auto updates enabled but no appId configured.\n options.checkAppId()\n\n // Check the versions\n const {mismatched, unresolvedPrerelease} =\n await options.compareDependencyVersions(autoUpdatedPackages)\n\n if (unresolvedPrerelease.length > 0) {\n await handlePrereleaseVersions({\n onPreReleaseInInteractiveAutoUpdate: eventListener.onPreReleaseInInteractiveAutoUpdate,\n onPreReleaseInNonInteractiveAutoUpdate:\n eventListener.onPreReleaseInNonInteractiveAutoUpdate,\n unattendedMode,\n unresolvedPrerelease,\n })\n autoUpdatesImports = {}\n autoUpdatesCssUrls = []\n autoUpdatesEnabled = false\n }\n\n if (mismatched.length > 0 && autoUpdatesEnabled) {\n const versionMismatchWarning =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you test locally with the same versions before deploying. \\n\\n` +\n `${mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}`\n\n // If it is non-interactive or in unattended mode, we don't want to prompt\n if (isInteractive() && !unattendedMode) {\n const shouldContinue = await confirm({\n default: false,\n message: styleText('yellow', `${versionMismatchWarning} \\n\\nContinue anyway?`),\n })\n\n if (!shouldContinue) {\n output.error('Declined to continue with build', {exit: exitCodes.RUNTIME_ERROR})\n return {mfManifest: undefined}\n }\n } else {\n // if non-interactive or unattended, just show the warning\n output.warn(versionMismatchWarning)\n }\n }\n }\n\n const envVarKeys = Object.keys(getAppEnvironmentVariables())\n if (envVarKeys.length > 0) {\n output.log('\\nIncluding the following environment variables as part of the JavaScript bundle:')\n for (const key of envVarKeys) output.log(`- ${key}`)\n output.log('')\n }\n\n let shouldClean = true\n if (outputDir !== defaultOutputDir && !unattendedMode && isInteractive()) {\n shouldClean = await confirm({\n default: true,\n message: `Do you want to delete the existing directory (${outputDir}) first?`,\n })\n }\n\n const basePath = determineBasePath()\n\n let spin: SpinnerInstance\n if (shouldClean) {\n timer.start('cleanOutputFolder')\n spin = spinner('Clean output folder').start()\n await rm(outputDir, {force: true, recursive: true})\n const cleanDuration = timer.end('cleanOutputFolder')\n spin.text = `Clean output folder (${cleanDuration.toFixed(0)}ms)`\n spin.succeed()\n }\n\n spin = spinner(`Building Sanity application`).start()\n\n const trace = getCliTelemetry().trace(AppBuildTrace)\n trace.start()\n\n let autoUpdates\n if (autoUpdatesEnabled && !options.isWorkbenchApp) {\n autoUpdates = {\n cssUrls: autoUpdatesCssUrls,\n imports: autoUpdatesImports,\n vendor: await resolveVendorBuildConfig({cwd: workDir, isApp: true}),\n }\n }\n\n try {\n timer.start('bundleStudio')\n\n const bundle = await buildStaticFiles({\n appTitle: options.appTitle,\n autoUpdates,\n basePath,\n cwd: workDir,\n entry: options.entry,\n exposes: options.exposes,\n isApp: true,\n isBlueprints: options.isBlueprints,\n isWorkbenchApp: options.isWorkbenchApp,\n minify: options.minify,\n outputDir,\n reactCompiler: options.reactCompiler,\n schemaExtraction: options.schemaExtraction,\n sourceMap: options.sourceMap,\n vite: options.vite,\n workbenchAppId: options.workbenchAppId,\n })\n const mfManifest = options.isWorkbenchApp ? await readBuiltManifest(outputDir) : undefined\n\n trace.log({\n outputSize: bundle.chunks\n .flatMap((chunk) => chunk.modules.flatMap((mod) => mod.renderedLength))\n .reduce((sum, n) => sum + n, 0),\n })\n const buildDuration = timer.end('bundleStudio')\n\n spin.text = `Build Sanity application (${buildDuration.toFixed(0)}ms)`\n spin.succeed()\n\n if (options.stats) {\n output.log('\\nLargest module files:')\n output.log(formatModuleSizes(sortModulesBySize(bundle.chunks).slice(0, 15)))\n }\n\n trace.complete()\n return {mfManifest}\n } catch (error) {\n spin.fail()\n trace.error(error)\n const message = error instanceof Error ? error.message : String(error)\n buildDebug(`Failed to build Sanity application`, {error})\n output.error(`Failed to build Sanity application: ${message}`, {exit: exitCodes.RUNTIME_ERROR})\n return {mfManifest: undefined}\n }\n}\n"],"names":["rm","path","styleText","exitCodes","getLocalPackageVersion","getCliTelemetry","isInteractive","confirm","getTimer","logSymbols","spinner","readBuiltManifest","parse","semverParse","AppBuildTrace","formatModuleSizes","sortModulesBySize","buildDebug","buildStaticFiles","getAutoUpdatesCssUrls","getAutoUpdatesImportMap","getAppEnvironmentVariables","handlePrereleaseVersions","resolveVendorBuildConfig","buildApp","options","appId","determineBasePath","eventListener","outDir","output","workDir","autoUpdatesEnabled","unattendedMode","timer","defaultOutputDir","resolve","join","outputDir","installedSdkVersion","installedSanityVersion","error","exit","RUNTIME_ERROR","mfManifest","undefined","autoUpdatesImports","autoUpdatesCssUrls","cleanSDKVersion","version","cleanSanityVersion","autoUpdatedPackages","name","cssFile","log","info","checkAppId","mismatched","unresolvedPrerelease","compareDependencyVersions","length","onPreReleaseInInteractiveAutoUpdate","onPreReleaseInNonInteractiveAutoUpdate","versionMismatchWarning","map","mod","pkg","installed","remote","shouldContinue","default","message","warn","envVarKeys","Object","keys","key","shouldClean","basePath","spin","start","force","recursive","cleanDuration","end","text","toFixed","succeed","trace","autoUpdates","isWorkbenchApp","cssUrls","imports","vendor","cwd","isApp","bundle","appTitle","entry","exposes","isBlueprints","minify","reactCompiler","schemaExtraction","sourceMap","vite","workbenchAppId","outputSize","chunks","flatMap","chunk","modules","renderedLength","reduce","sum","n","buildDuration","stats","slice","complete","fail","Error","String"],"mappings":"AAAA,SAAQA,EAAE,QAAO,mBAAkB;AACnC,OAAOC,UAAU,YAAW;AAC5B,SAAQC,SAAS,QAAO,YAAW;AAEnC,SAAQC,SAAS,QAAO,6BAA4B;AACpD,SAAQC,sBAAsB,QAAO,mCAAkC;AACvE,SAAQC,eAAe,QAAO,6BAA4B;AAE1D,SAAQC,aAAa,QAAO,wBAAuB;AACnD,SAAQC,OAAO,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,OAAO,QAA6B,sBAAqB;AAChG,SAAQC,iBAAiB,QAA8B,8BAA6B;AACpF,SAAQC,SAASC,WAAW,QAAO,SAAQ;AAE3C,SAAQC,aAAa,QAAO,qCAAoC;AAEhE,SAAQC,iBAAiB,EAAEC,iBAAiB,QAAO,kCAAiC;AACpF,SAAQC,UAAU,QAAO,kBAAiB;AAC1C,SAAQC,gBAAgB,QAAO,wBAAuB;AAEtD,SAAQC,qBAAqB,EAAEC,uBAAuB,QAAO,+BAA8B;AAC3F,SAAQC,0BAA0B,QAAO,+BAA8B;AACvE,SAAQC,wBAAwB,QAAO,gCAA+B;AACtE,SAAQC,wBAAwB,QAAO,gCAA+B;AAuCtE;;;CAGC,GACD,OAAO,eAAeC,SACpBC,OAAqB;IAErBR,WAAW,CAAC,YAAY,CAAC;IAEzB,MAAM,EAACS,KAAK,EAAEC,iBAAiB,EAAEC,aAAa,EAAEC,MAAM,EAAEC,MAAM,EAAEC,OAAO,EAAC,GAAGN;IAC3E,IAAI,EAACO,kBAAkB,EAAC,GAAGP;IAC3B,MAAMQ,iBAAiBR,QAAQQ,cAAc;IAE7C,MAAMC,QAAQ1B;IAEd,MAAM2B,mBAAmBlC,KAAKmC,OAAO,CAACnC,KAAKoC,IAAI,CAACN,SAAS;IACzD,MAAMO,YAAYrC,KAAKmC,OAAO,CAACP,UAAUM;IAEzC,MAAMI,sBAAsB,MAAMnC,uBAAuB,qBAAqB2B;IAC9E,MAAMS,yBAAyB,MAAMpC,uBAAuB,UAAU2B;IAEtE,IAAI,CAACQ,qBAAqB;QACxBT,OAAOW,KAAK,CAAC,CAAC,kDAAkD,CAAC,EAAE;YACjEC,MAAMvC,UAAUwC,aAAa;QAC/B;QACA,OAAO;YAACC,YAAYC;QAAS;IAC/B;IAEA,IAAIC,qBAAqB,CAAC;IAC1B,IAAIC,qBAA+B,EAAE;IAErC,IAAIf,oBAAoB;QACtB,iFAAiF;QACjF,MAAMgB,kBAAkBnC,YAAY0B,sBAAsBU;QAC1D,IAAI,CAACD,iBAAiB;YACpBlB,OAAOW,KAAK,CAAC,CAAC,uCAAuC,EAAEF,qBAAqB,EAAE;gBAC5EG,MAAMvC,UAAUwC,aAAa;YAC/B;YACA,OAAO;gBAACC,YAAYC;YAAS;QAC/B;QAEA,0EAA0E;QAC1E,MAAMK,qBAAqBrC,YAAY2B,yBAAyBS;QAEhE,MAAME,sBAAsB;YAC1B;gBAACC,MAAM;gBAAeH,SAASD;YAAe;YAC9C;gBAACI,MAAM;gBAAqBH,SAASD;YAAe;eAChDE,qBACA;gBAAC;oBAACG,SAAS;oBAAaD,MAAM;oBAAmBH,SAASC;gBAAkB;aAAE,GAC9E,EAAE;SACP;QACDJ,qBAAqB1B,wBAAwB+B,qBAAqB;YAACzB;QAAK;QACxEqB,qBAAqB5B,sBAAsBgC,qBAAqB;YAACzB;QAAK;QAEtEI,OAAOwB,GAAG,CAAC,GAAG7C,WAAW8C,IAAI,CAAC,mCAAmC,CAAC;QAElE,wDAAwD;QACxD9B,QAAQ+B,UAAU;QAElB,qBAAqB;QACrB,MAAM,EAACC,UAAU,EAAEC,oBAAoB,EAAC,GACtC,MAAMjC,QAAQkC,yBAAyB,CAACR;QAE1C,IAAIO,qBAAqBE,MAAM,GAAG,GAAG;YACnC,MAAMtC,yBAAyB;gBAC7BuC,qCAAqCjC,cAAciC,mCAAmC;gBACtFC,wCACElC,cAAckC,sCAAsC;gBACtD7B;gBACAyB;YACF;YACAZ,qBAAqB,CAAC;YACtBC,qBAAqB,EAAE;YACvBf,qBAAqB;QACvB;QAEA,IAAIyB,WAAWG,MAAM,GAAG,KAAK5B,oBAAoB;YAC/C,MAAM+B,yBACJ,CAAC,mGAAmG,CAAC,GACrG,CAAC,yGAAyG,CAAC,GAC3G,GAAGN,WAAWO,GAAG,CAAC,CAACC,MAAQ,CAAC,GAAG,EAAEA,IAAIC,GAAG,CAAC,iBAAiB,EAAED,IAAIE,SAAS,CAAC,mBAAmB,EAAEF,IAAIG,MAAM,CAAC,CAAC,CAAC,EAAE/B,IAAI,CAAC,OAAO;YAE5H,0EAA0E;YAC1E,IAAI/B,mBAAmB,CAAC2B,gBAAgB;gBACtC,MAAMoC,iBAAiB,MAAM9D,QAAQ;oBACnC+D,SAAS;oBACTC,SAASrE,UAAU,UAAU,GAAG6D,uBAAuB,qBAAqB,CAAC;gBAC/E;gBAEA,IAAI,CAACM,gBAAgB;oBACnBvC,OAAOW,KAAK,CAAC,mCAAmC;wBAACC,MAAMvC,UAAUwC,aAAa;oBAAA;oBAC9E,OAAO;wBAACC,YAAYC;oBAAS;gBAC/B;YACF,OAAO;gBACL,0DAA0D;gBAC1Df,OAAO0C,IAAI,CAACT;YACd;QACF;IACF;IAEA,MAAMU,aAAaC,OAAOC,IAAI,CAACtD;IAC/B,IAAIoD,WAAWb,MAAM,GAAG,GAAG;QACzB9B,OAAOwB,GAAG,CAAC;QACX,KAAK,MAAMsB,OAAOH,WAAY3C,OAAOwB,GAAG,CAAC,CAAC,EAAE,EAAEsB,KAAK;QACnD9C,OAAOwB,GAAG,CAAC;IACb;IAEA,IAAIuB,cAAc;IAClB,IAAIvC,cAAcH,oBAAoB,CAACF,kBAAkB3B,iBAAiB;QACxEuE,cAAc,MAAMtE,QAAQ;YAC1B+D,SAAS;YACTC,SAAS,CAAC,8CAA8C,EAAEjC,UAAU,QAAQ,CAAC;QAC/E;IACF;IAEA,MAAMwC,WAAWnD;IAEjB,IAAIoD;IACJ,IAAIF,aAAa;QACf3C,MAAM8C,KAAK,CAAC;QACZD,OAAOrE,QAAQ,uBAAuBsE,KAAK;QAC3C,MAAMhF,GAAGsC,WAAW;YAAC2C,OAAO;YAAMC,WAAW;QAAI;QACjD,MAAMC,gBAAgBjD,MAAMkD,GAAG,CAAC;QAChCL,KAAKM,IAAI,GAAG,CAAC,qBAAqB,EAAEF,cAAcG,OAAO,CAAC,GAAG,GAAG,CAAC;QACjEP,KAAKQ,OAAO;IACd;IAEAR,OAAOrE,QAAQ,CAAC,2BAA2B,CAAC,EAAEsE,KAAK;IAEnD,MAAMQ,QAAQnF,kBAAkBmF,KAAK,CAAC1E;IACtC0E,MAAMR,KAAK;IAEX,IAAIS;IACJ,IAAIzD,sBAAsB,CAACP,QAAQiE,cAAc,EAAE;QACjDD,cAAc;YACZE,SAAS5C;YACT6C,SAAS9C;YACT+C,QAAQ,MAAMtE,yBAAyB;gBAACuE,KAAK/D;gBAASgE,OAAO;YAAI;QACnE;IACF;IAEA,IAAI;QACF7D,MAAM8C,KAAK,CAAC;QAEZ,MAAMgB,SAAS,MAAM9E,iBAAiB;YACpC+E,UAAUxE,QAAQwE,QAAQ;YAC1BR;YACAX;YACAgB,KAAK/D;YACLmE,OAAOzE,QAAQyE,KAAK;YACpBC,SAAS1E,QAAQ0E,OAAO;YACxBJ,OAAO;YACPK,cAAc3E,QAAQ2E,YAAY;YAClCV,gBAAgBjE,QAAQiE,cAAc;YACtCW,QAAQ5E,QAAQ4E,MAAM;YACtB/D;YACAgE,eAAe7E,QAAQ6E,aAAa;YACpCC,kBAAkB9E,QAAQ8E,gBAAgB;YAC1CC,WAAW/E,QAAQ+E,SAAS;YAC5BC,MAAMhF,QAAQgF,IAAI;YAClBC,gBAAgBjF,QAAQiF,cAAc;QACxC;QACA,MAAM9D,aAAanB,QAAQiE,cAAc,GAAG,MAAM/E,kBAAkB2B,aAAaO;QAEjF2C,MAAMlC,GAAG,CAAC;YACRqD,YAAYX,OAAOY,MAAM,CACtBC,OAAO,CAAC,CAACC,QAAUA,MAAMC,OAAO,CAACF,OAAO,CAAC,CAAC5C,MAAQA,IAAI+C,cAAc,GACpEC,MAAM,CAAC,CAACC,KAAKC,IAAMD,MAAMC,GAAG;QACjC;QACA,MAAMC,gBAAgBlF,MAAMkD,GAAG,CAAC;QAEhCL,KAAKM,IAAI,GAAG,CAAC,0BAA0B,EAAE+B,cAAc9B,OAAO,CAAC,GAAG,GAAG,CAAC;QACtEP,KAAKQ,OAAO;QAEZ,IAAI9D,QAAQ4F,KAAK,EAAE;YACjBvF,OAAOwB,GAAG,CAAC;YACXxB,OAAOwB,GAAG,CAACvC,kBAAkBC,kBAAkBgF,OAAOY,MAAM,EAAEU,KAAK,CAAC,GAAG;QACzE;QAEA9B,MAAM+B,QAAQ;QACd,OAAO;YAAC3E;QAAU;IACpB,EAAE,OAAOH,OAAO;QACdsC,KAAKyC,IAAI;QACThC,MAAM/C,KAAK,CAACA;QACZ,MAAM8B,UAAU9B,iBAAiBgF,QAAQhF,MAAM8B,OAAO,GAAGmD,OAAOjF;QAChExB,WAAW,CAAC,kCAAkC,CAAC,EAAE;YAACwB;QAAK;QACvDX,OAAOW,KAAK,CAAC,CAAC,oCAAoC,EAAE8B,SAAS,EAAE;YAAC7B,MAAMvC,UAAUwC,aAAa;QAAA;QAC7F,OAAO;YAACC,YAAYC;QAAS;IAC/B;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/build/buildApp.ts"],"sourcesContent":["import {rm} from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {exitCodes} from '@sanity/cli-core/ExitCodes'\nimport {getLocalPackageVersion} from '@sanity/cli-core/package-manager'\nimport {getCliTelemetry} from '@sanity/cli-core/telemetry'\nimport {type CliConfig, type Output, type UserViteConfig} from '@sanity/cli-core/types'\nimport {isInteractive} from '@sanity/cli-core/util'\nimport {confirm, getTimer, logSymbols, spinner, type SpinnerInstance} from '@sanity/cli-core/ux'\nimport {readBuiltManifest, type WorkbenchExposes} from '@sanity/workbench-cli/build'\nimport {parse as semverParse} from 'semver'\n\nimport {AppBuildTrace} from '../../telemetry/build.telemetry.js'\nimport {CompareDependencyVersionsResult} from '../../util/compareDependencyVersions.js'\nimport {formatModuleSizes, sortModulesBySize} from '../../util/moduleFormatUtils.js'\nimport {buildDebug} from './buildDebug.js'\nimport {buildStaticFiles} from './buildStaticFiles.js'\nimport {BuildEventListener} from './eventListener.js'\nimport {getAutoUpdatesCssUrls, getAutoUpdatesImportMap} from './getAutoUpdatesImportMap.js'\nimport {getAppEnvironmentVariables} from './getEnvironmentVariables.js'\nimport {handlePrereleaseVersions} from './handlePrereleaseVersions.js'\nimport {resolveVendorBuildConfig} from './resolveVendorBuildConfig.js'\n\nexport type BuildAppEventListener = BuildEventListener\nexport interface BuildOptions {\n appId: string | undefined\n appTitle: string | undefined\n autoUpdatesEnabled: boolean\n checkAppId: () => void\n compareDependencyVersions: (\n packages: {name: string; version: string}[],\n ) => Promise<CompareDependencyVersionsResult>\n determineBasePath: () => string\n entry: string | undefined\n eventListener: Partial<BuildAppEventListener>\n isWorkbenchApp: boolean\n minify: boolean\n outDir: string | undefined\n output: Output\n reactCompiler: CliConfig['reactCompiler']\n schemaExtraction: CliConfig['schemaExtraction']\n sourceMap: boolean\n stats: boolean\n unattendedMode: boolean\n vite: UserViteConfig | undefined\n workDir: string\n\n exposes?: WorkbenchExposes\n /**\n * The build is running under Sanity Blueprints (invoked programmatically by\n * `@sanity/runtime-cli`), so emit the statically-imported resource-bindings\n * module Brett rewrites at deploy. Defaults to `false`, so a normal\n * `sanity build`/`dev`/`preview` never emits it.\n */\n isBlueprints?: boolean\n\n /** The workbench app's bus identity (`__SANITY_APP_ID__`). */\n workbenchAppId?: string\n}\n\n/**\n * Internal build app that avoids depending on flags for CLI config.\n * @param options - options for the build\n */\nexport async function buildApp(\n options: BuildOptions,\n): Promise<{mfManifest: Record<string, unknown> | undefined}> {\n buildDebug(`Building app`)\n\n const {appId, determineBasePath, eventListener, outDir, output, workDir} = options\n let {autoUpdatesEnabled} = options\n const unattendedMode = options.unattendedMode\n\n const timer = getTimer()\n\n const defaultOutputDir = path.resolve(path.join(workDir, 'dist'))\n const outputDir = path.resolve(outDir || defaultOutputDir)\n\n const installedSdkVersion = await getLocalPackageVersion('@sanity/sdk-react', workDir)\n const installedSanityVersion = await getLocalPackageVersion('sanity', workDir)\n\n // A Media Library config ships no SDK app — its inputs are island-rendered\n // by `sanity`, so verify that instead and skip the SDK auto-update\n // machinery. Checked via the `appType` discriminator, not the mere presence\n // of a config: a future `ConfigSchema` member must not inherit these\n // media-library build semantics by default.\n const isMediaLibraryConfigBuild = options.exposes?.config?.appType === 'media-library'\n\n if (!installedSdkVersion && !isMediaLibraryConfigBuild) {\n output.error(`Failed to find installed @sanity/sdk-react version`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n return {mfManifest: undefined}\n }\n\n if (isMediaLibraryConfigBuild && !installedSanityVersion) {\n output.error(`Failed to find installed sanity version`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n return {mfManifest: undefined}\n }\n\n let autoUpdatesImports = {}\n let autoUpdatesCssUrls: string[] = []\n\n if (autoUpdatesEnabled && !isMediaLibraryConfigBuild) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSDKVersion = semverParse(installedSdkVersion)?.version\n if (!cleanSDKVersion) {\n output.error(`Failed to parse installed SDK version: ${installedSdkVersion}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n return {mfManifest: undefined}\n }\n\n // Sanity might not be installed, but if it is, we want to auto update it.\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n\n const autoUpdatedPackages = [\n {name: '@sanity/sdk', version: cleanSDKVersion},\n {name: '@sanity/sdk-react', version: cleanSDKVersion},\n ...(cleanSanityVersion\n ? [{cssFile: 'index.css', name: 'sanity' as const, version: cleanSanityVersion}]\n : []),\n ]\n autoUpdatesImports = getAutoUpdatesImportMap(autoUpdatedPackages, {appId})\n autoUpdatesCssUrls = getAutoUpdatesCssUrls(autoUpdatedPackages, {appId})\n\n output.log(`${logSymbols.info} Building with auto-updates enabled`)\n\n // Warn if auto updates enabled but no appId configured.\n options.checkAppId()\n\n // Check the versions\n const {mismatched, unresolvedPrerelease} =\n await options.compareDependencyVersions(autoUpdatedPackages)\n\n if (unresolvedPrerelease.length > 0) {\n await handlePrereleaseVersions({\n onPreReleaseInInteractiveAutoUpdate: eventListener.onPreReleaseInInteractiveAutoUpdate,\n onPreReleaseInNonInteractiveAutoUpdate:\n eventListener.onPreReleaseInNonInteractiveAutoUpdate,\n unattendedMode,\n unresolvedPrerelease,\n })\n autoUpdatesImports = {}\n autoUpdatesCssUrls = []\n autoUpdatesEnabled = false\n }\n\n if (mismatched.length > 0 && autoUpdatesEnabled) {\n const versionMismatchWarning =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you test locally with the same versions before deploying. \\n\\n` +\n `${mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}`\n\n // If it is non-interactive or in unattended mode, we don't want to prompt\n if (isInteractive() && !unattendedMode) {\n const shouldContinue = await confirm({\n default: false,\n message: styleText('yellow', `${versionMismatchWarning} \\n\\nContinue anyway?`),\n })\n\n if (!shouldContinue) {\n output.error('Declined to continue with build', {exit: exitCodes.RUNTIME_ERROR})\n return {mfManifest: undefined}\n }\n } else {\n // if non-interactive or unattended, just show the warning\n output.warn(versionMismatchWarning)\n }\n }\n }\n\n const envVarKeys = Object.keys(getAppEnvironmentVariables())\n if (envVarKeys.length > 0) {\n output.log('\\nIncluding the following environment variables as part of the JavaScript bundle:')\n for (const key of envVarKeys) output.log(`- ${key}`)\n output.log('')\n }\n\n let shouldClean = true\n if (outputDir !== defaultOutputDir && !unattendedMode && isInteractive()) {\n shouldClean = await confirm({\n default: true,\n message: `Do you want to delete the existing directory (${outputDir}) first?`,\n })\n }\n\n const basePath = determineBasePath()\n\n let spin: SpinnerInstance\n if (shouldClean) {\n timer.start('cleanOutputFolder')\n spin = spinner('Clean output folder').start()\n await rm(outputDir, {force: true, recursive: true})\n const cleanDuration = timer.end('cleanOutputFolder')\n spin.text = `Clean output folder (${cleanDuration.toFixed(0)}ms)`\n spin.succeed()\n }\n\n spin = spinner(`Building Sanity application`).start()\n\n const trace = getCliTelemetry().trace(AppBuildTrace)\n trace.start()\n\n let autoUpdates\n if (autoUpdatesEnabled && !options.isWorkbenchApp) {\n autoUpdates = {\n cssUrls: autoUpdatesCssUrls,\n imports: autoUpdatesImports,\n vendor: await resolveVendorBuildConfig({cwd: workDir, isApp: true}),\n }\n }\n\n try {\n timer.start('bundleStudio')\n\n const bundle = await buildStaticFiles({\n appTitle: options.appTitle,\n autoUpdates,\n basePath,\n cwd: workDir,\n entry: options.entry,\n exposes: options.exposes,\n isApp: true,\n isBlueprints: options.isBlueprints,\n isWorkbenchApp: options.isWorkbenchApp,\n minify: options.minify,\n outputDir,\n reactCompiler: options.reactCompiler,\n schemaExtraction: options.schemaExtraction,\n sourceMap: options.sourceMap,\n vite: options.vite,\n workbenchAppId: options.workbenchAppId,\n })\n const mfManifest = options.isWorkbenchApp ? await readBuiltManifest(outputDir) : undefined\n\n trace.log({\n outputSize: bundle.chunks\n .flatMap((chunk) => chunk.modules.flatMap((mod) => mod.renderedLength))\n .reduce((sum, n) => sum + n, 0),\n })\n const buildDuration = timer.end('bundleStudio')\n\n spin.text = `Build Sanity application (${buildDuration.toFixed(0)}ms)`\n spin.succeed()\n\n if (options.stats) {\n output.log('\\nLargest module files:')\n output.log(formatModuleSizes(sortModulesBySize(bundle.chunks).slice(0, 15)))\n }\n\n trace.complete()\n return {mfManifest}\n } catch (error) {\n spin.fail()\n trace.error(error)\n const message = error instanceof Error ? error.message : String(error)\n buildDebug(`Failed to build Sanity application`, {error})\n output.error(`Failed to build Sanity application: ${message}`, {exit: exitCodes.RUNTIME_ERROR})\n return {mfManifest: undefined}\n }\n}\n"],"names":["rm","path","styleText","exitCodes","getLocalPackageVersion","getCliTelemetry","isInteractive","confirm","getTimer","logSymbols","spinner","readBuiltManifest","parse","semverParse","AppBuildTrace","formatModuleSizes","sortModulesBySize","buildDebug","buildStaticFiles","getAutoUpdatesCssUrls","getAutoUpdatesImportMap","getAppEnvironmentVariables","handlePrereleaseVersions","resolveVendorBuildConfig","buildApp","options","appId","determineBasePath","eventListener","outDir","output","workDir","autoUpdatesEnabled","unattendedMode","timer","defaultOutputDir","resolve","join","outputDir","installedSdkVersion","installedSanityVersion","isMediaLibraryConfigBuild","exposes","config","appType","error","exit","RUNTIME_ERROR","mfManifest","undefined","autoUpdatesImports","autoUpdatesCssUrls","cleanSDKVersion","version","cleanSanityVersion","autoUpdatedPackages","name","cssFile","log","info","checkAppId","mismatched","unresolvedPrerelease","compareDependencyVersions","length","onPreReleaseInInteractiveAutoUpdate","onPreReleaseInNonInteractiveAutoUpdate","versionMismatchWarning","map","mod","pkg","installed","remote","shouldContinue","default","message","warn","envVarKeys","Object","keys","key","shouldClean","basePath","spin","start","force","recursive","cleanDuration","end","text","toFixed","succeed","trace","autoUpdates","isWorkbenchApp","cssUrls","imports","vendor","cwd","isApp","bundle","appTitle","entry","isBlueprints","minify","reactCompiler","schemaExtraction","sourceMap","vite","workbenchAppId","outputSize","chunks","flatMap","chunk","modules","renderedLength","reduce","sum","n","buildDuration","stats","slice","complete","fail","Error","String"],"mappings":"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"}
|
|
@@ -3,19 +3,18 @@ import { decorateIndexWithBridgeScript } from '../decorateIndexWithBridgeScript.
|
|
|
3
3
|
import { decorateIndexWithStagingScript } from '../decorateIndexWithStagingScript.js';
|
|
4
4
|
import { renderDocument } from '../renderDocument.js';
|
|
5
5
|
const entryChunkId = '.sanity/runtime/app.js';
|
|
6
|
+
/**
|
|
7
|
+
* Logical name Vite gives the single CSS asset emitted when
|
|
8
|
+
* `build.cssCodeSplit` is false. `assetFileNames` can change the file written
|
|
9
|
+
* to disk; `names` still carries this value.
|
|
10
|
+
*/ const CSS_BUNDLE_NAME = 'style.css';
|
|
6
11
|
export function sanityBuildEntries(options) {
|
|
7
12
|
const { autoUpdates, basePath, bridge = true, cwd, isApp } = options;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
id: entryChunkId,
|
|
14
|
-
name: 'sanity',
|
|
15
|
-
type: 'chunk'
|
|
16
|
-
});
|
|
17
|
-
},
|
|
18
|
-
async generateBundle (_options, outputBundle) {
|
|
13
|
+
// Vite's default. `configResolved` replaces this with the resolved value,
|
|
14
|
+
// including a userland `vite` config that sets `build.cssCodeSplit: false`.
|
|
15
|
+
let cssCodeSplit = true;
|
|
16
|
+
const generateBundle = {
|
|
17
|
+
async handler (_options, outputBundle) {
|
|
19
18
|
const bundle = outputBundle;
|
|
20
19
|
const entryFile = Object.values(bundle).find((file)=>file.type === 'chunk' && file.name === 'sanity' && file.facadeModuleId?.endsWith(entryChunkId));
|
|
21
20
|
if (!entryFile) {
|
|
@@ -29,23 +28,7 @@ export function sanityBuildEntries(options) {
|
|
|
29
28
|
basePath.replace(/\/+$/, ''),
|
|
30
29
|
entryFileName
|
|
31
30
|
].join('/');
|
|
32
|
-
|
|
33
|
-
if (entryFile.viteMetadata?.importedCss) {
|
|
34
|
-
// Check all the top-level imports of the entryPoint to see if they have
|
|
35
|
-
// static CSS assets that need loading
|
|
36
|
-
css = [
|
|
37
|
-
...entryFile.viteMetadata.importedCss
|
|
38
|
-
];
|
|
39
|
-
for (const key of entryFile.imports){
|
|
40
|
-
// Traverse all CSS assets that isn't loaded by the runtime and
|
|
41
|
-
// need <link> tags in the HTML template
|
|
42
|
-
const entry = bundle[key];
|
|
43
|
-
const importedCss = entry && entry.type === 'chunk' ? entry.viteMetadata.importedCss : undefined;
|
|
44
|
-
if (importedCss) {
|
|
45
|
-
css.push(...importedCss);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
31
|
+
const css = collectStylesheets(entryFile, bundle, cssCodeSplit);
|
|
49
32
|
// For auto-updating studios/apps the import map combines the vendor
|
|
50
33
|
// chunks emitted by this very build (hashed filenames, resolved from the
|
|
51
34
|
// bundle) with the module-CDN imports for auto-updated packages.
|
|
@@ -73,6 +56,69 @@ export function sanityBuildEntries(options) {
|
|
|
73
56
|
});
|
|
74
57
|
}
|
|
75
58
|
};
|
|
59
|
+
return {
|
|
60
|
+
apply: 'build',
|
|
61
|
+
name: 'sanity/server/build-entries',
|
|
62
|
+
configResolved (resolved) {
|
|
63
|
+
cssCodeSplit = resolved.build.cssCodeSplit;
|
|
64
|
+
// `vite:css-post` emits the combined stylesheet during its own unordered
|
|
65
|
+
// `generateBundle`, so with `cssCodeSplit: false` this hook has to run
|
|
66
|
+
// after it. Default builds keep the normal order so user plugins with an
|
|
67
|
+
// unordered `generateBundle` (HTML minifiers, SRI) still see `index.html`.
|
|
68
|
+
generateBundle.order = cssCodeSplit ? undefined : 'post';
|
|
69
|
+
},
|
|
70
|
+
buildStart () {
|
|
71
|
+
this.emitFile({
|
|
72
|
+
id: entryChunkId,
|
|
73
|
+
name: 'sanity',
|
|
74
|
+
type: 'chunk'
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
generateBundle
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Stylesheets the document should link.
|
|
82
|
+
*
|
|
83
|
+
* With CSS code splitting, Vite records each chunk's styles on
|
|
84
|
+
* `viteMetadata.importedCss` (including the chunks the entry statically
|
|
85
|
+
* imports). With `cssCodeSplit: false`, Vite emits one combined asset instead
|
|
86
|
+
* and never adds it to `importedCss`. `vite:build-html` finds that asset by
|
|
87
|
+
* its bundle name (`style.css`); mirror that. Other CSS assets (e.g. `?url`
|
|
88
|
+
* imports) are not stylesheets for the document and must not be linked.
|
|
89
|
+
*/ function collectStylesheets(entryFile, bundle, cssCodeSplit) {
|
|
90
|
+
const css = collectImportedCss(entryFile, bundle);
|
|
91
|
+
if (cssCodeSplit) return css;
|
|
92
|
+
const seen = new Set(css);
|
|
93
|
+
for (const fileName of collectCombinedStylesheets(bundle)){
|
|
94
|
+
if (seen.has(fileName)) continue;
|
|
95
|
+
seen.add(fileName);
|
|
96
|
+
css.push(fileName);
|
|
97
|
+
}
|
|
98
|
+
return css;
|
|
99
|
+
}
|
|
100
|
+
function collectImportedCss(entryFile, bundle) {
|
|
101
|
+
const css = cssFilesFromChunk(entryFile);
|
|
102
|
+
for (const key of entryFile.imports){
|
|
103
|
+
const imported = bundle[key];
|
|
104
|
+
if (imported?.type === 'chunk') css.push(...cssFilesFromChunk(imported));
|
|
105
|
+
}
|
|
106
|
+
return css;
|
|
107
|
+
}
|
|
108
|
+
function cssFilesFromChunk(chunk) {
|
|
109
|
+
const imported = chunk.viteMetadata?.importedCss;
|
|
110
|
+
if (!imported) return [];
|
|
111
|
+
return [
|
|
112
|
+
...imported
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
function collectCombinedStylesheets(bundle) {
|
|
116
|
+
return Object.values(bundle).flatMap((file)=>file.type === 'asset' && file.fileName && isCombinedCssBundle(file) ? [
|
|
117
|
+
file.fileName
|
|
118
|
+
] : []);
|
|
119
|
+
}
|
|
120
|
+
function isCombinedCssBundle(asset) {
|
|
121
|
+
return asset.names ? asset.names.includes(CSS_BUNDLE_NAME) : asset.name === CSS_BUNDLE_NAME;
|
|
76
122
|
}
|
|
77
123
|
|
|
78
124
|
//# sourceMappingURL=plugin-sanity-build-entries.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/actions/build/vite/plugin-sanity-build-entries.ts"],"sourcesContent":["import {type ChunkMetadata, type Plugin} from 'vite'\n\nimport {type AutoUpdatesBuildConfig} from '../autoUpdates.js'\nimport {createVendorImportMapFromBundle} from '../createVendorImportMapFromBundle.js'\nimport {decorateIndexWithBridgeScript} from '../decorateIndexWithBridgeScript.js'\nimport {decorateIndexWithStagingScript} from '../decorateIndexWithStagingScript.js'\nimport {renderDocument} from '../renderDocument.js'\n\ninterface ViteOutputBundle {\n [fileName: string]: ViteRenderedAsset | ViteRenderedChunk\n}\n\ninterface ViteRenderedAsset {\n type: 'asset'\n}\n\ninterface ViteRenderedChunk {\n code: string\n facadeModuleId: string | null\n fileName: string\n imports: string[]\n isEntry: boolean\n name: string\n type: 'chunk'\n viteMetadata
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/build/vite/plugin-sanity-build-entries.ts"],"sourcesContent":["import {type ChunkMetadata, type Plugin} from 'vite'\n\nimport {type AutoUpdatesBuildConfig} from '../autoUpdates.js'\nimport {createVendorImportMapFromBundle} from '../createVendorImportMapFromBundle.js'\nimport {decorateIndexWithBridgeScript} from '../decorateIndexWithBridgeScript.js'\nimport {decorateIndexWithStagingScript} from '../decorateIndexWithStagingScript.js'\nimport {renderDocument} from '../renderDocument.js'\n\ninterface ViteOutputBundle {\n [fileName: string]: ViteRenderedAsset | ViteRenderedChunk\n}\n\ninterface ViteRenderedAsset {\n type: 'asset'\n\n fileName?: string\n name?: string | null\n names?: string[]\n}\n\ninterface ViteRenderedChunk {\n code: string\n facadeModuleId: string | null\n fileName: string\n imports: string[]\n isEntry: boolean\n name: string\n type: 'chunk'\n\n /**\n * Populated by Vite when `build.cssCodeSplit` is true. Rolldown-based Vite\n * (Vite 7/8 and `rolldown-vite`) may omit it, or leave `importedCss` empty,\n * for the single stylesheet emitted when code splitting is disabled.\n */\n viteMetadata?: ChunkMetadata\n}\n\nconst entryChunkId = '.sanity/runtime/app.js'\n\n/**\n * Logical name Vite gives the single CSS asset emitted when\n * `build.cssCodeSplit` is false. `assetFileNames` can change the file written\n * to disk; `names` still carries this value.\n */\nconst CSS_BUNDLE_NAME = 'style.css'\n\nexport function sanityBuildEntries(options: {\n autoUpdates?: AutoUpdatesBuildConfig\n basePath: string\n /**\n * Injects the core-ui bridge script into the emitted `index.html`. Defaults to\n * `true`. Workbench remotes serve themselves standalone and pass `false`.\n */\n bridge?: boolean\n cwd: string\n isApp?: boolean\n}): Plugin {\n const {autoUpdates, basePath, bridge = true, cwd, isApp} = options\n // Vite's default. `configResolved` replaces this with the resolved value,\n // including a userland `vite` config that sets `build.cssCodeSplit: false`.\n let cssCodeSplit = true\n\n const generateBundle: Extract<Plugin['generateBundle'], {handler: unknown}> = {\n async handler(_options, outputBundle) {\n const bundle = outputBundle as unknown as ViteOutputBundle\n const entryFile = Object.values(bundle).find(\n (file) =>\n file.type === 'chunk' &&\n file.name === 'sanity' &&\n file.facadeModuleId?.endsWith(entryChunkId),\n )\n\n if (!entryFile) {\n throw new Error(`Failed to find entry file in bundle (${entryChunkId})`)\n }\n\n if (entryFile.type !== 'chunk') {\n throw new Error('Entry file is not a chunk')\n }\n\n const entryFileName = entryFile.fileName\n const entryPath = [basePath.replace(/\\/+$/, ''), entryFileName].join('/')\n const css = collectStylesheets(entryFile, bundle, cssCodeSplit)\n\n // For auto-updating studios/apps the import map combines the vendor\n // chunks emitted by this very build (hashed filenames, resolved from the\n // bundle) with the module-CDN imports for auto-updated packages.\n const importMap = autoUpdates\n ? {\n imports: {\n ...createVendorImportMapFromBundle(\n bundle,\n autoUpdates.vendor.specifiersByChunkName,\n basePath,\n ),\n ...autoUpdates.imports,\n },\n }\n : undefined\n\n const html = await renderDocument({\n autoUpdatesCssUrls: autoUpdates?.cssUrls,\n importMap,\n isApp,\n props: {\n basePath,\n css,\n entryPath,\n },\n studioRootPath: cwd,\n })\n\n this.emitFile({\n fileName: 'index.html',\n source: decorateIndexWithStagingScript(bridge ? decorateIndexWithBridgeScript(html) : html),\n type: 'asset',\n })\n },\n }\n\n return {\n apply: 'build',\n name: 'sanity/server/build-entries',\n\n configResolved(resolved) {\n cssCodeSplit = resolved.build.cssCodeSplit\n // `vite:css-post` emits the combined stylesheet during its own unordered\n // `generateBundle`, so with `cssCodeSplit: false` this hook has to run\n // after it. Default builds keep the normal order so user plugins with an\n // unordered `generateBundle` (HTML minifiers, SRI) still see `index.html`.\n generateBundle.order = cssCodeSplit ? undefined : 'post'\n },\n\n buildStart() {\n this.emitFile({\n id: entryChunkId,\n name: 'sanity',\n type: 'chunk',\n })\n },\n\n generateBundle,\n }\n}\n\n/**\n * Stylesheets the document should link.\n *\n * With CSS code splitting, Vite records each chunk's styles on\n * `viteMetadata.importedCss` (including the chunks the entry statically\n * imports). With `cssCodeSplit: false`, Vite emits one combined asset instead\n * and never adds it to `importedCss`. `vite:build-html` finds that asset by\n * its bundle name (`style.css`); mirror that. Other CSS assets (e.g. `?url`\n * imports) are not stylesheets for the document and must not be linked.\n */\nfunction collectStylesheets(\n entryFile: ViteRenderedChunk,\n bundle: ViteOutputBundle,\n cssCodeSplit: boolean,\n): string[] {\n const css = collectImportedCss(entryFile, bundle)\n if (cssCodeSplit) return css\n\n const seen = new Set(css)\n for (const fileName of collectCombinedStylesheets(bundle)) {\n if (seen.has(fileName)) continue\n seen.add(fileName)\n css.push(fileName)\n }\n return css\n}\n\nfunction collectImportedCss(entryFile: ViteRenderedChunk, bundle: ViteOutputBundle): string[] {\n const css = cssFilesFromChunk(entryFile)\n for (const key of entryFile.imports) {\n const imported = bundle[key]\n if (imported?.type === 'chunk') css.push(...cssFilesFromChunk(imported))\n }\n return css\n}\n\nfunction cssFilesFromChunk(chunk: ViteRenderedChunk): string[] {\n const imported = chunk.viteMetadata?.importedCss\n if (!imported) return []\n return [...imported]\n}\n\nfunction collectCombinedStylesheets(bundle: ViteOutputBundle): string[] {\n return Object.values(bundle).flatMap((file) =>\n file.type === 'asset' && file.fileName && isCombinedCssBundle(file) ? [file.fileName] : [],\n )\n}\n\nfunction isCombinedCssBundle(asset: ViteRenderedAsset): boolean {\n return asset.names ? asset.names.includes(CSS_BUNDLE_NAME) : asset.name === CSS_BUNDLE_NAME\n}\n"],"names":["createVendorImportMapFromBundle","decorateIndexWithBridgeScript","decorateIndexWithStagingScript","renderDocument","entryChunkId","CSS_BUNDLE_NAME","sanityBuildEntries","options","autoUpdates","basePath","bridge","cwd","isApp","cssCodeSplit","generateBundle","handler","_options","outputBundle","bundle","entryFile","Object","values","find","file","type","name","facadeModuleId","endsWith","Error","entryFileName","fileName","entryPath","replace","join","css","collectStylesheets","importMap","imports","vendor","specifiersByChunkName","undefined","html","autoUpdatesCssUrls","cssUrls","props","studioRootPath","emitFile","source","apply","configResolved","resolved","build","order","buildStart","id","collectImportedCss","seen","Set","collectCombinedStylesheets","has","add","push","cssFilesFromChunk","key","imported","chunk","viteMetadata","importedCss","flatMap","isCombinedCssBundle","asset","names","includes"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/cli-build",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.2",
|
|
4
4
|
"description": "Internal Sanity package for building studios and apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -52,12 +52,12 @@
|
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@oclif/core": "^4.11.14",
|
|
54
54
|
"@rolldown/plugin-babel": "^0.2.4",
|
|
55
|
-
"@sanity/cli-core": "^3.
|
|
55
|
+
"@sanity/cli-core": "^3.12.0",
|
|
56
56
|
"@sanity/generate-help-url": "^4.0.0",
|
|
57
57
|
"@sanity/schema": "^6.17.0",
|
|
58
58
|
"@sanity/telemetry": "^1.1.0",
|
|
59
59
|
"@sanity/types": "^6.17.0",
|
|
60
|
-
"@sanity/workbench-cli": "^2.
|
|
60
|
+
"@sanity/workbench-cli": "^2.14.0",
|
|
61
61
|
"@vitejs/plugin-react": "^6.1.2",
|
|
62
62
|
"chokidar": "^5.0.0",
|
|
63
63
|
"cjs-module-lexer": "^2.2.1",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"@eslint/compat": "^2.1.0",
|
|
80
80
|
"@repo/package.config": "0.0.1",
|
|
81
81
|
"@repo/tsconfig": "3.70.0",
|
|
82
|
-
"@sanity/cli-test": "
|
|
82
|
+
"@sanity/cli-test": "22.0.0",
|
|
83
83
|
"@sanity/eslint-config-cli": "^1.1.3",
|
|
84
84
|
"@sanity/pkg-utils": "^12.3.4",
|
|
85
85
|
"@sanity/ui": "^4.3.1",
|