@ decocms/ tanstack (英语)
Deco CMS 用于 TanStack 启动 在Cloudflare工人的工地上, 部署德克部署他们的方式。 有观点认为:一个工人进入 有一些选择,一个逃出舱门 为你自己的路线, 和每个Deco TanStack网站应该有的行为, 总是在.
端点 : @decocms/blocks (同一个版本), @tanstack/react-start, (中文(简体) ), @tanstack/react-router, (中文(简体) ), react,以及 vite 页:1 /vite。 。 。 .
那个工人
// src/worker-entry.ts (wrangler.jsonc "main"), without a page cache
import { createDecoWorker } from "@decocms/tanstack/worker";
import handler, { createServerEntry } from "@tanstack/react-start/server-entry";
import { cms } from "./cms";
export default createDecoWorker({
serverEntry: createServerEntry({ fetch: handler.fetch }),
cms,
dev: import.meta.env.DEV,
});
总是在: /deco/_liveness; 404 用于 v7 的管理员路径; Studio 可能设定站点(frame-ancestors,没有 X-Frame-Options和安全头; 草稿(CMS的预览主机, Cookie 草稿, 仅以低于 500 的回复设置; 任何请求带有 ?__draft=, (中文(简体) ), off 包含,或 cookie 草稿为预览: 它从未到达 pageCache 准确回答 Cache-Control: max-age=0, no-cache, must-revalidate, (中文(简体) ), Vary: Cookie 财务报告和审定财务报表 noindex,一个除指纹外的资产; 与无法读取的草稿的链接使得发布, 过期的饼干和显示 DecoPreview冷静的注意,永远不要500;CMS重定向;一 Set-Cookie 每块饼干; x-page-status· ; CDN-Cache-Control: no-store (a) 在每一份答复中均不提及 http.server.request.duration 在CMS的遥测中 recordServerRequest 从 @decocms/blocks/metrics (没有 token 或一个 endpoint标签 http.route (内容的页面模板, redirect 每一次CMS重定向,一个固定的如: /_serverFn/* 或者说 /assets/*,否则 unmatched, (中文(简体) ), http.request.method, (中文(简体) ), status_class, (中文(简体) ), cache (单位:千美元)DRAFT 预览; 否则 X-Cache pageCache 回答说, HIT 页:1 HIT, (中文(简体) ), STALE-HIT 财务报告和审定财务报表 STALE-ERROR, (中文(简体) ), MISS,则 BYPASS和 device。 。 。 .
选项,每个值一个站点需要更改: csp, (中文(简体) ), pageCache, (中文(简体) ), preload 财务报告和审定财务报表 routes。 。 。 .
工人缓存没有页面:页面缓存是网站的,如Next.js. 无 pageCache 每一个请求都要求. 页面缓存 下面连接一个完整的工人条目和一个.
草稿主机
链接草案( A)?__draft=在 CMS 允许的主机上进行预览,其中 cms.readVersion 检查: 地址 Studio 写入当前发行的元数据 (previewHosts 内 latest.json这样 createCMS 需要网站的 site 给他们的)加 createCMS({ preview: { hosts } })。网站没有列出其他内容。 没有列表, 每个主机都会预览: 没有的网站 latest.json 尚未在CDN上发布,或者在 Studio 撰稿前发布 previewHosts (它下一次出版时会写列表),内容没有 site 除非 preview.hosts 列出主机( 如 ["localhost"]) (中文(简体) ). 若为 latest.json 无法读取( 网络错误, 5xx, 错误的文件) , 预览会保持关闭 preview.hosts,直到读取成功。 任何其它主机上的链接都会获得发布,永远不会出错. 同样的链接可以携带已公布的发行承诺SHA而不是草稿(Studio's "Preview this version"),其中任何一个可以携带预览时间(SHA)__at测试和运动开启或关闭(__test, (中文(简体) ), __campaign页:1 cms.readVersion 读作客户端的 date, (中文(简体) ), experiments 财务报告和审定财务报表 campaigns;所有这一切都通过同一个主机检查,所以现场的访客从不选择一个版本. 工人们将接受的版本 单独传送到应用程序 x-deco-version 请求标题( e)requestVersion(request) 读在一 routes 处理者)。 请求草案检查一次最新发布(cms.checkRelease():主机检查,工人阅读了草稿,其重定向和任务以及页面 contentClient 都等着那张支票 工友的身份证 x-deco-release-check (删除从外部发送的任何副本),所以一个预览请求会获取 latest.json 一次,并显示 发布片前一分钟.
访客、任务和客户
工人按要求在边缘决定一次。 在每一个页面和服务器功能请求中,它读取访问者 readVisitor 从 @decocms/blocks/experiments (单位:千美元) deco_segment 饼干,或者新访客, 然后每次测试和运动 上或下: readAssignments(cms, { visitor, ...version }),它解决了保存 experiments 财务报告和审定财务报表 campaigns 块通 cms.client({ visitor, version, date, experiments, campaigns }) 与工作室链接的版本, 瞬间和切换测试和运动。 它把访客放到应用程序上 x-deco-visitor 和决定的执行情况 x-deco-assignments,删除任何从外部发送的拷贝,以及提交网站的决定 pageCache 作为 page.assignments为了它的关键。 它只向访客发送第一次访问的饼干(没有身份证明的访客),从未从预览中发出.
contentClient(cms) 从 @decocms/tanstack/server 正在建设 cms.client({ version, experiments, campaigns }) 从头部,每个测试和运动 工人决定它, 所以页面使 精确的缓存键 和决定 不再; requestVersion(), (中文(简体) ), requestVisitor() 财务报告和审定财务报表 requestAssignments() 把它们交还给网站的密码 他们信任那些信头: createDecoWorker 他们持有工人的决定,因为它删除了从外部发送的任何副本。 在没有工人的情况下到达应用程序的请求(另一个条目,或一个不使用的应用程序) createDecoWorker)的读取方式相同,无论用什么 x-deco-version, (中文(简体) ), x-deco-visitor 财务报告和审定财务报表 x-deco-assignments 它随同而来;没有任何人,它的访客决定;没有一个人,每一次试验都停止。 要求通过工人, 和如何保护其他人, 是现场的呼声.
页面缓存
pageCache(page) 是该网站自己在应用程序周围的缓存。 工人们给每个页面和服务器功能请求都打电话 isCacheable 接受(a) GET 当前发布时没有 ?__draft= 外面没有饼干草稿 vite dev,没有 Authorization没有 /_build: 从未预览、草稿或旧版本),带有 page.request (随着应用程序得到它), page.url, (中文(简体) ), page.visitor (网页上的访客,包括第一次访问的新访问), page.assignments (每个测试和运动 或关闭,如页面使其), page.device, (中文(简体) ), env, (中文(简体) ), ctx 财务报告和审定财务报表 page.render(scope?),使页面。 从您的缓存中回复, 或者打电话 render(); 设置 X-Cache 回答请求的度量标准。 页面请求 Authorization 从来没有达到它和答案 Cache-Control: private, no-cache, no-store, must-revalidate所以没有共享缓存能保存一个呼叫器的页面.
访客的初访饼干从来不在什么 render() 返回:工人将其添加到任意 pageCache 答案,包含一个缓存副本。 所以存储的拷贝从不携带访客的饼干,从缓存服务的新访客仍然得到他们的. 永远不要存储设置其他饼干的响应.
关键需要,从 @decocms/tanstack/worker,名称与 @decocms/nextjs/proxy他们都在那里:
assignmentsKey(page.assignments): 测试和运动作为一串(x=<tests>|c=<campaigns>, (中文(简体) ),""没有,从来没有访客的身份证。 每个测试的同一边的访客共享一个条目,另一边得到自己的条目,一个运动开始或结束将每个页面移动到新条目.liveAssignmentKeys(cms)列出当前可以携带的每个活请求键(每个被保存测试的子集,有运行中的运动,没有),以进行清洗.cacheVersion(cms, buildHash, page.url)数字 :<build>.<content revision>,所以一个部署或发布的发布会立刻得到新的条目. 与 URL 相通, 修订版是页面制作的一页( 在发布之后, 前一页同时是页面的新块负载), 因此一个页面从未存储在它没有渲染的修订版下 .detectDevice(userAgent)(v7的班级:mobile, (中文(简体) ),tablet, (中文(简体) ),desktop, (中文(简体) ),segmentKey(segment)(一个部分作为一个稳定的字符串)和segmentToken(segment, version)页:1__cseg符号 。 通过它作为render({ csegToken })财务报告和审定财务报表DecoDocument出版;decoServerFnFetch在页面的导航数据上发回( p)CSEG_PARAM),而您的缓存可能会让CDN在符号与请求本身匹配时保留该响应.isCacheable(request, { version, dev }), (中文(简体) ),requestVersion(request), (中文(简体) ),isServerFnPath(pathname), (中文(简体) ),serverFnPagePath(url)(服务器功能页面载荷要求的网页,从其有效载荷)和DEGRADED_HEADER(一个装入器失败的页面:永远不存储).
一个完整的工人条目,有一个页面缓存 examples/tanstack-worker-smoke/src/worker-entry.ts: 复制给您 src/worker-entry.ts 并改变您的网站需要。 在Cloudflare Cache API上它是v7的边缘缓存,它的每一部分都是你的:
- 钥匙: 路径(跟踪参数和
__cseg),设备以及您部分自己的部件(buildSegment,v7's: 一个区域,一个销售渠道,),assignmentsKey(page.assignments)财务报告和审定财务报表cacheVersion(cms, __BUILD_HASH__, page.url)· 签字的速记loggedIn: true从buildSegment),私人反应和已退化的反应从不储存. - 简介: v7 每个 URL 的缓存配置文件 (
PROFILES),每页保持了多久新鲜,在重新验证时服务了多久;以及应用程序失败了多久. - 清洗: v7 级
POST /_cache/purge与Authorization: Bearer <PURGE_TOKEN>和一个身体{ "paths": ["/", "/shoes"] },可选择使用"segments": [{ "device": "desktop", "salesChannel": "2" }](你自己的部件). 它会减少每个精确路径(/shoes从不下降/shoes?page=2),在当前版本下,对于每个片段(正文名称为"无"的设备),每个分配密钥,作为导航和服务器函数获取,以及答案{ "purged": [...], "total": n }。缓存 API 是每个数据中心的,所以清理可以到达服务它的数据中心的副本.
__BUILD_HASH__ 是构建 id decoTanstack() 定义(声明一次: declare const __BUILD_HASH__: string;),以及 PURGE_TOKEN a 工人秘密。 举例来说,该档案是作为工人的条目,并附有其测试结果worker-entry.test.ts ) (中文(简体).
名称和工作室的起源
根出口持有什么工人, /server 财务报告和审定财务报表 DecoDocument 共享,对于一个站点自己的代码: 草稿名称(DRAFT_PARAM __draft, (中文(简体) ), DRAFT_COOKIE __deco_draft),标题为工人手持应用程序(VERSION_HEADER x-deco-version, (中文(简体) ), VISITOR_HEADER x-deco-visitor, (中文(简体) ), ASSIGNMENTS_HEADER x-deco-assignments, (中文(简体) ), draftResponseHeaders(preview) (单位:千美元)max-age=0, no-cache, must-revalidate, (中文(简体) ), Vary: Cookie, (中文(简体) ), noindex;通过版本,或 true 以及工作室的起源: STUDIO_ORIGINS, (中文(简体) ), STUDIO_FRAME_ANCESTORS (工人的吗? ) frame-ancestors 从)和 isStudioOrigin; Studio频道的确切列表, DEFAULT_STUDIO_ORIGINS 财务报告和审定财务报表 studioOrigins(option?); 和 : withStudioCsp(directives)工人对现场所做的 csp (Studio的起源于 script-src 财务报告和审定财务报表 frame-ancestors),对于一项政策,网站发送一些其他方式.
import { STUDIO_ORIGINS, VERSION_HEADER } from "@decocms/tanstack";
应用程序
// vite.config.ts
plugins: [cloudflare({ viteEnvironment: { name: "ssr" } }), tanstackStart(), react(),
decoTanstack({ buildHash: process.env.WORKERS_CI_COMMIT_SHA })]
// src/router.tsx
export const getRouter = () => createDecoRouter({ routeTree });
// src/start.ts
export const startInstance = createStart(() => ({ serverFns: { fetch: decoServerFnFetch } }));
// src/routes/__root.tsx
export const Route = createRootRoute({ component: () => <DecoDocument site="my-store" /> });
DecoDocument mangs v7's "." 编辑快捷键, Studio频道和草稿徽章. 它只是v8:v7的被框处理器(scrollToComponent, (中文(简体) ), editor::rerender)已消失,所以页面上没有任何脚本可以比较窗口和 top 或者说 parent,以及重写"帧-破坏"代码(Cypress's modifyObstructiveCode)服务于字节的页面字节. 工作室频道在每一页上,制作内容包括:一个小的内线脚本(约0.7 kB gziped),工作室通过它将自己的编辑码(一保存后的部分线框,页面互换)加载到页面中. 这是工作室在页面中运行代码的唯一方式:桥面评价没有脚本工作室发送. 该页面信任一份准确工作室起源列表: studioOrigins 道具当给, 否则 DECO_STUDIO_ORIGIN 环境变量,逗号分隔(在服务器上读取;本地工作室,例如 http://localhost:3000)),其他工作室的出品和出品起源(出品人DEFAULT_STUDIO_ORIGINS) (中文(简体) ). 框架, 页面帖 { type: "deco:ready" } 每一个都作为目标来源(只有其中之一的家长收到),并且只有在工作室的回答时,才会导入一个模块, { type: "deco:load", url },来自其中之一,并在该消息的来由上命名一个URL;不是由任何其他来源设定,也不是由其他来源设定,它什么都不做。 工人在HTML响应的CSP中添加了同样的列表: frame-ancestors,然后 script-src (或 script-src-elem; 只对脚本进行限制的政策 default-src 获得一个 script-src 与它的源 加上工作室的。 一个设置 studioOrigins 打开 DecoDocument 设置工人的 studioOrigins 选项; DECO_STUDIO_ORIGIN 都设置好了 内线剧本取自网站 nonce。信件和模块类型在 @decocms/blocks/protocol返回页面路由 pathTemplate (页面块的 path,作为 matchRoute 与它匹配)在其加载器数据中,所以""在存储页面打开该页面在工作室编辑器中. 保存自己文档的站点( 跳过链接 ) <main>说) <DecoPreview site="my-store" /> 联合国 <body> 取而代之的是:捷径,通道,徽章和他们所读的草稿.
图像
// src/imageUrl.ts: the site's image URLs (@decocms/blocks/image plus its platform's helpers)
import { createImageUrl, decoCdn } from "@decocms/blocks/image";
import { vtexCatalog } from "@decocms/apps-vtex/image"; // a VTEX store
import { shopifyCdn } from "@decocms/apps-shopify/image"; // a Shopify store
export const imageUrl = createImageUrl({
providers: [vtexCatalog(), shopifyCdn(), decoCdn({ quality: "high", sources: "all" })],
});
// src/router.tsx: around every page
createDecoRouter({ routeTree, Wrap: ({ children }) => <ImageUrlProvider value={imageUrl}>{children}</ImageUrlProvider> });
// any component
<Image src={src} width={400} height={300} preload={isLcp} />
Image, (中文(简体) ), Picture 财务报告和审定财务报表 Source 从 /react 使用 v7 的道具并渲染 v7 的标记, 因此一个迁移的呼叫站点只改变其导入 。 这个软件包不知道商业平台:v7的组件调整了这些平台主机上的VTEX目录和Shopify图像的大小,一个网站通过在之前列出平台的助手来保存这些 URL decoCdn 如上(v7's URL,字节为字节,并带有 decoCdn 选择 :. stripAssetHosts: "leading" 从7.71.4:v7到v8的迁移技能列出了他们). 一个 Image 或者说 Source 无宽度写 v7's width=NaN 候选人,就像v7一样。 没有 ImageUrlProvider 每个来源都经过 assets.decocms.com (单位:千美元)DECO_IMAGE_URL) (中文(简体) ).
examples/tanstack-worker-smoke 在寄存器中是一个完整的应用程序.