diff --git a/.changeset/console-bundle-own-client.md b/.changeset/console-bundle-own-client.md new file mode 100644 index 0000000000..382947ff4a --- /dev/null +++ b/.changeset/console-bundle-own-client.md @@ -0,0 +1,5 @@ +--- +'@objectstack/console': patch +--- + +修复 console 产物打包旧版 @objectstack/client 的问题:`build-console.sh` 现在通过 `OBJECTSTACK_CLIENT_DIST` 把本仓库、本版本的 client 注入 console bundle(此前由 objectui lockfile 决定,11.5.0 因此发布了新导入 UI + client 11.2.0,运行时报 "does not support async import jobs")。构建拆为 deps(turbo)+ console 本体(直跑,避开 turbo strict env 剥离环境变量),并新增产物 canary 断言防止旧 client 再次静默发布。 diff --git a/scripts/build-console.sh b/scripts/build-console.sh index 35ae388b1e..f185f616c7 100755 --- a/scripts/build-console.sh +++ b/scripts/build-console.sh @@ -19,9 +19,11 @@ # scripts/build-console.sh # # Env: -# OBJECTUI_ROOT override path to objectui checkout -# OBJECTUI_REPO_URL override clone URL (default: https://github.com/objectstack-ai/objectui.git) -# OBJECTUI_BUILD_CMD override build command (default: pnpm exec turbo run build --filter=@object-ui/console) +# OBJECTUI_ROOT override path to objectui checkout +# OBJECTUI_REPO_URL override clone URL (default: https://github.com/objectstack-ai/objectui.git) +# OBJECTUI_DEPS_BUILD_CMD override deps build (default: pnpm exec turbo run build --filter=@object-ui/console^...) +# OBJECTUI_BUILD_CMD override console build (default: pnpm --filter @object-ui/console run build) +# CONSOLE_BUNDLE_CANARY literal asserted in the built assets (default: import/jobs) set -euo pipefail @@ -40,7 +42,18 @@ if [[ -z "$PINNED_SHA" ]]; then fi REPO_URL="${OBJECTUI_REPO_URL:-https://github.com/objectstack-ai/objectui.git}" -BUILD_CMD="${OBJECTUI_BUILD_CMD:-pnpm exec turbo run build --filter=@object-ui/console}" +# The console app itself must NOT build through turbo: turbo v2 runs tasks in +# strict env mode and strips undeclared vars, so OBJECTSTACK_CLIENT_DIST +# (exported below) never reaches vite unless the pinned objectui SHA happens +# to declare it in turbo.json. Build the workspace deps through turbo +# (cacheable, env-independent), then invoke the console's own build script +# directly so the env survives. +DEPS_BUILD_CMD="${OBJECTUI_DEPS_BUILD_CMD:-pnpm exec turbo run build --filter=@object-ui/console^...}" +BUILD_CMD="${OBJECTUI_BUILD_CMD:-pnpm --filter @object-ui/console run build}" +# Post-build canary: a literal that only exists in an up-to-date bundled +# client. Guards against any future mechanism (turbo env stripping, a removed +# vite hook, chunking changes) silently shipping a stale client again. +BUNDLE_CANARY="${CONSOLE_BUNDLE_CANARY:-import/jobs}" # Resolve a source checkout of objectui. SOURCE_ROOT="" @@ -101,6 +114,32 @@ if [[ "$ACTUAL" != "$PINNED_SHA" ]]; then fi echo "→ Building @object-ui/console at ${PINNED_SHA:0:12}..." + +# ── Bundle THIS framework's client ─────────────────────────────────── +# The console SPA inlines @objectstack/client. Left to itself, the objectui +# build resolves the client from objectui's own lockfile — which lags the +# framework whenever a release adds new client APIs (the lockfile can't point +# at a client that isn't published yet). That shipped 11.5.0 with the new +# import UI bundled against client 11.2.0, so the console threw "does not +# support async import jobs" at runtime. Alias the build to the client in +# THIS tree instead: the bundled client then always matches the framework +# release being published, with no objectui pin-bump round-trip. +# objectui honors OBJECTSTACK_CLIENT_DIST in apps/console/vite.config.ts; +# fail hard if the pinned SHA predates that hook rather than silently drift. +CLIENT_PKG="${FRAMEWORK_ROOT}/packages/client" +if ! grep -q "OBJECTSTACK_CLIENT_DIST" "${BUILD_ROOT}/apps/console/vite.config.ts"; then + echo "✗ objectui@${PINNED_SHA:0:12} has no OBJECTSTACK_CLIENT_DIST hook in apps/console/vite.config.ts —" + echo " the bundled client would come from objectui's lockfile, not this framework." + echo " Bump .objectui-sha to a commit that includes the hook." + exit 1 +fi +if [[ ! -f "${CLIENT_PKG}/dist/index.mjs" ]]; then + echo "→ @objectstack/client dist missing — building it first..." + (cd "$CLIENT_PKG" && pnpm build) +fi +export OBJECTSTACK_CLIENT_DIST="$CLIENT_PKG" +echo "→ Console will bundle @objectstack/client from ${CLIENT_PKG}" + pushd "$BUILD_ROOT" > /dev/null # objectui's root package.json may pin packages that aren't available on @@ -109,7 +148,9 @@ NPM_CONFIG_REGISTRY_OVERRIDE="${OBJECTUI_NPM_REGISTRY:-https://registry.npmjs.or npm_config_registry="$NPM_CONFIG_REGISTRY_OVERRIDE" \ pnpm install --frozen-lockfile --prefer-offline --prod=false -# Build only the console SPA (turbo will pull in workspace deps). +# Build the console's workspace deps via turbo, then the SPA itself directly +# (see DEPS_BUILD_CMD/BUILD_CMD above for why these are split). +eval "$DEPS_BUILD_CMD" eval "$BUILD_CMD" popd > /dev/null @@ -133,6 +174,14 @@ cp -R "$CONSOLE_DIST" "$TARGET" # cloud/objectos Docker overlay that replaces dist/ restamps it too. echo "$PINNED_SHA" > "${TARGET}/.objectui-sha" +# Assert the injected client actually landed in the bundle (see BUNDLE_CANARY). +if ! grep -rq "$BUNDLE_CANARY" "${TARGET}/assets"; then + echo "✗ Built console dist does not contain '${BUNDLE_CANARY}' — the bundled" + echo " @objectstack/client is stale (OBJECTSTACK_CLIENT_DIST injection failed)." + exit 1 +fi +echo "✓ Bundle canary '${BUNDLE_CANARY}' present — framework client is in the bundle." + BYTES="$(du -sk "$TARGET" 2>/dev/null | awk '{print $1}')" echo "✓ @objectstack/console dist ready (${BYTES} KB) from objectui@${PINNED_SHA:0:12}"