
Remix 模板项目实战指南最小化全栈应用的目录结构、核心模块与开发命令【免费下载链接】remixThe fully-stacked web framework项目地址: https://gitcode.com/GitHub_Trending/re/remix本指南围绕本仓库template/目录下的官方 Starter 模板展开系统讲解一个最小 Remix 应用从目录骨架、路由契约、资产管线到开发命令的完整形态。读者学完后将掌握如何基于该模板快速起步一个全栈应用、如何按官方约定组织app/actions/与app/router.ts、如何配置服务端资产管线以及npm run dev、npm run hmr、npm run start等命令背后的真实行为。模板定位一个可立即运行的最小 Remix 应用template/README.md开篇即点明模板本质——A minimal Remix application starter with a home page即一个自带首页的最小 Remix 应用 Starter。它不是为了展示全部功能而是给出官方认可的最小目录骨架与文件职责划分让新项目以此为基础生长Growing The App。模板根目录结构如下template/ ├── app/ │ ├── actions/ │ │ ├── public/ # 浏览器运行时入口与交互组件 │ │ │ ├── entry.ts │ │ │ └── prompt-button.tsx │ │ ├── controller.tsx # 顶层路由 actions 的归属地 │ │ ├── document.tsx # HTML 文档壳head、字体、入口脚本 │ │ └── home-page.tsx # 路由自带的首页 UI │ ├── assets.ts # 服务端资产管线编译、HMR、预加载 │ ├── router.ts # 路由→处理器绑定 中间件装配 │ └── routes.ts # 共享路由契约类型安全 href ├── public/ │ └── favicon.svg # 静态文件原样从应用根路径提供 ├── hmr.ts # 独立 HMR 代理进程入口 ├── server.ts # Node HTTP 服务入口 ├── package.json └── tsconfig.json模板的全部文件均可在仓库的 template/ 目录中逐一查看其中 template/README.md 是本文所述约定的原始出处。Starter Shape每个文件各司其职README 用 7 条清单概括了模板的标准形态逐条对照源码展开如下。1.app/actions/controller.tsx顶层路由 actions 的归属地README 指明该文件 owns the top-level route actions。其真实实现是// template/app/actions/controller.tsx import { createController } from remix/router import { assets } from ../assets.ts import { routes } from ../routes.ts import { HomePage } from ./home-page.tsx export default createController(routes, { actions: { async assets(context) { return (await assets.fetch(context.request)) ?? new Response(Not Found, { status: 404 }) }, home(context) { return context.render(HomePage /) }, }, })createController的职责在 packages/fetch-router/src/lib/controller.ts 中有明确注释它把路由树的叶子节点映射到 action同时保留每个 action 的 params 与 request-context 类型契约。也就是说routes里定义了哪些路由controller 的actions就必须恰好覆盖哪些键——类型系统会在编译期兜底。这里home直接调用context.render(HomePage /)完成服务端渲染。2.app/actions/home-page.tsx与app/actions/document.tsx路由自带的 UIhome-page.tsx是首页 UI文件头注释写着 Delete this file and put your own home page in app/actions/controller.tsx即官方明确允许、甚至鼓励你删除它把首页替换成自己的实现。document.tsx导出Document组件负责 HTML 壳html、meta、favicon、title默认值来自模板占位符%%RMX_APP_DISPLAY_NAME_URI_COMPONENT%%未被替换时回退为 Remix App、字体 preconnect以及关键的入口脚本注入{entryPreloads.map((href) ( link key{href} relmodulepreload href{href} / ))} script typemodule src{entryHref}/scriptentryHref与entryPreloads均来自app/assets.ts即浏览器入口的 URL 与预加载清单由服务端资产管线统一产出。3.app/actions/public/浏览器运行时入口与交互组件该目录是浏览器端专属代码的约定位置包含两个文件entry.ts调用remix/ui的run()启动浏览器运行时并在import.meta.hot存在时订阅server:update事件收到服务端更新后重新加载顶层 frame。prompt-button.tsx一个**独立水合clientEntry**的复制提示词到剪贴板按钮组件头注释点明 This component hydrates independently; the rest of the page stays static HTML——页面的其余部分保持静态 HTML只有这个交互按钮被单独激活这也是 Remix 逐组件水合思路的落地示例。4.app/routes.ts共享路由契约与类型安全 href// template/app/routes.ts import { get, route } from remix/routes export const routes route({ assets: get(/assets/*path), home: /, })README 强调它 defines the shared route contract used by server and browser modules for type-safe hrefs。因为服务端与浏览器模块都从同一份routes.ts导入路由名与路径模式是单一事实来源拼写错误会在编译期暴露。5.app/router.ts路由→处理器绑定与标准渲染中间件// template/app/router.ts import { createRouter, type MiddlewareContext } from remix/router import { render } from remix/middleware/render import { staticFiles } from remix/middleware/static import controller from ./actions/controller.tsx import { assets } from ./assets.ts import { routes } from ./routes.ts const renderMiddleware render({ assets }) type AppContext MiddlewareContext[typeof renderMiddleware] declare module remix/router { interface RouterTypes { context: AppContext } } export const router createRouterAppContext({ middleware: [staticFiles(./public, { index: false }), renderMiddleware], }) router.map(routes, controller)这里演示了两个官方推荐的标准中间件staticFiles(./public, { index: false })将public/目录下的静态文件原样服务index: false表示不做目录索引对应 README 第 7 条 Rootpublic/contains static files served unchanged from the app root。render({ assets })标准 Remix UI 渲染器把context.render()的结果渲染成完整 HTMLMiddlewareContext[typeof renderMiddleware]把渲染中间件追加的上下文类型化再通过declare module注入全局RouterTypes.context让所有 action 的context.render拥有类型。6.app/assets.ts服务端资产管线// template/app/assets.ts import { createAssetServer } from remix/assets import { uiHmr } from remix/ui-hmr/assets const rootDir process.cwd() const nodeEnv process.env.NODE_ENV ?? development const isDevelopment nodeEnv development const isHmr Boolean(isDevelopment process.env.REMIX_NODE_HMR) export const assets createAssetServer({ basePath: /assets, rootDir, allowFiles: [app/routes.ts, app/**/public/**], allowPackages: [remix], denyFiles: [app/**/*.test.*], sourceMaps: isDevelopment ? external : undefined, minify: !isDevelopment, watch: isDevelopment, hmr: isHmr ? async () (await import(remix/node-hmr/runtime)).createBrowserHmrChannel() : undefined, scripts: { loaders: isHmr ? [uiHmr()] : undefined }, }) const entry app/actions/public/entry.ts export const entryHref await assets.getHref(entry) export const entryPreloads await assets.getPreloads(entry)关键配置项一览createAssetServer定义于 packages/assets/src/lib/asset-server.ts配置项模板取值含义basePath/assets资产统一挂载的 URL 前缀rootDirprocess.cwd()资产编译的工作根目录allowFiles[app/routes.ts, app/**/public/**]允许被服务/编译的文件白名单浏览器端代码约定放public/子目录allowPackages[remix]允许被引用的包白名单denyFiles[app/**/*.test.*]测试文件禁止进入浏览器产物sourceMaps开发环境external仅开发时产出外部 source mapminify生产环境为true仅生产时压缩watch开发环境为true开发时监听文件变更hmr/scripts.loaders仅 HMR 模式启用注入浏览器 HMR 通道与uiHmr()loader7.public/静态文件原样服务public/favicon.svg是模板唯一静态资源document.tsx中以/favicon.svg引用由staticFiles中间件原样提供。Growing The App官方推荐的生长路径README 的 Growing The App 一节给出了四条可操作的扩展约定这是模板最有实战价值的部分顶层路由 actions 放app/actions/controller.tsx——新路由的处理器继续追加到现有 controller 的actions中。嵌套路由地图需要自己的 actions 或中间件时新建app/actions/route-key/controller.tsx——即按路由键划分子目录每个子 controller 可声明自己的middleware与actions。确实需要时才新增目录如app/data/、test/——模板刻意不预置避免空目录噪音仓库中其他 demo 目录如 demos/bookstore/、demos/timeboxer/正是按此约定生长后的完整样例。共享 UI 超过一个路由需要时才提升到app/ui/——保持就近维护避免过早抽象。入口与服务server.ts 与 hmr.ts标准服务进程server.tstemplate/server.ts 使用node:httpcreateRequestListener把 Remix router 暴露为 HTTP 服务端口默认44100可用环境变量PORT覆盖HMR 场景下还支持HMR_PROXY_PORT。请求处理直接router.fetch(request)异常时返回 500SIGINT/SIGTERM触发优雅关闭server.closecloseAllConnections。开发期 HMR 代理hmr.tstemplate/hmr.ts 是一个独立 HMR 代理进程端口分配如下端口来源默认值用途PORT代理44100HMR 代理对外端口HMR_PORT代理端口 1浏览器 HMR 事件通道APP_PORT事件端口 1实际应用进程端口它用run(server.ts, ...)以额外参数--import remix/node-tsx、--import remix/ui-hmr/node拉起应用进程再通过createFetchProxy转发请求并注入xForwardedHeaders配合createHmrReadyFetch实现服务就绪前排队、就绪后转发从而获得完整的服务端 浏览器端热更新体验。命令速查package.json 的六个脚本README 的 Commands 一节给出的命令在 template/package.json 中有完整定义逐条解析其真实行为npm i # 安装依赖本仓库为 pnpm workspace安装时执行 workspace 协议解析 npm run dev # NODE_ENVdevelopment node --watch --import remix/node-tsx server.ts # → node --watch 监听改动自动重启node-tsx 提供 TS 直接执行 npm run hmr # NODE_ENVdevelopment node hmr.ts # → 启动 HMR 代理进程获得浏览器/服务端热更新 npm run start # NODE_ENVproduction node --import remix/node-tsx server.ts # → 生产模式启动无 --watch资产管线自动开启 minify npm test # NODE_ENVtest node --import remix/node-tsx --test # → 使用 Node 内置 test runner 执行测试 npm run typecheck # tsc --noEmit → 全量类型检查strict 模式几点实操要点Node 版本要求package.json的engines声明node 24.3.0这是模板的硬性前提依赖node --watch、内置 test runner 与较新的--import链。唯一运行时依赖dependencies仅remix一个包workspace 协议workspace:^TypeScript 与types/node走 devDependencies 的catalog:版本目录。dev 与 hmr 的取舍dev简单可靠进程级热重启hmr体验更好但多一个代理进程二选一即可。类型安全基础template/tsconfig.json 采用strict: true、module/moduleResolution: NodeNext、jsx: react-jsxjsxImportSource: remix/ui、allowImportingTsExtensionsrewriteRelativeImportExtensions这解释了模板源码里随处可见的import ... from ../assets.ts带.ts后缀的导入写法能被正常编译。从模板到真实项目可复制的三条路径本地快速起步把template/复制为你的应用根目录按npm i npm run dev启动浏览器访问http://localhost:44100即可看到首页之后按 Growing The App 约定替换home-page.tsx、扩展routes.ts与 controller。对照成熟样例学习增长路径仓库 demos/ 下多个 demo 展示了模板约定的放大形态——demos/bookstore/ 有完整的数据层与中间件、demos/timeboxer/ 有数据库迁移与安全测试、demos/social-auth/ 有认证流程可作为模板长大后长什么样的参照。理解底层机制controller 的类型约束见 packages/fetch-router/src/lib/controller.ts资产管线的配置语义见 packages/assets/src/lib/asset-server.ts渲染中间件见 packages/render-middleware/src。小结template/README.md虽短却浓缩了 Remix 项目官方约定的最小骨架app/actions/承载路由处理器、app/routes.ts提供类型安全路由契约、app/router.ts装配中间件、app/assets.ts统一管理浏览器资产外加一套覆盖开发、HMR、生产、测试与类型检查的命令体系。以它为起点配合 Growing The App 的生长约定即可稳健地把最小应用扩展成完整全栈项目。【免费下载链接】remixThe fully-stacked web framework项目地址: https://gitcode.com/GitHub_Trending/re/remix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考