ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Razzle 集成 Vue Router:在零配置通用应用中实现服务端渲染路由

Razzle 集成 Vue Router:在零配置通用应用中实现服务端渲染路由 前端构建工具前端构建后端【免费下载链接】razzle✨ Create server-rendered universal JavaScript applications with no configuration项目地址https://gitcode.com/gh_mirrors/ra/razzle点击查看免费下载本篇指南以 Razzle 仓库中的examples/with-vue-router示例为蓝本完整讲解如何在基于 Razzle 的通用Universal / Isomorphic应用中引入 Vue Router实现 history 模式路由、服务端渲染SSR、客户端水合Hydration与按路由代码分割。读完本文你将掌握从依赖安装、razzle.config.js插件配置到server.js/client.js双端路由协调的完整落地方法可直接照搬改造自己的 Vue 应用。快速开始一键创建并运行示例示例 READMEexamples/with-vue-router/README.md提供了由create-razzle-app脚手架生成的官方启动方式两条命令即可完成创建与启动npx create-razzle-app --example with-vue-router with-vue-router cd with-vue-router yarn startnpx create-razzle-app --example with-vue-router with-vue-router以仓库中的with-vue-router为模板在当前目录创建同名项目yarn start以开发模式启动 Razzle默认监听3000端口见 examples/with-vue-router/src/index.js端口由process.env.PORT || 3000决定并同时启用客户端与服务端 HMR。启动后访问http://localhost:3000即进入Home页面访问/about可看到About页面访问任意未匹配路径如/foo则会命中PageNotFound的 404 页面——所有路由在服务端直接渲染出完整 HTML而非由前端 JavaScript 异步接管。示例背后的改造思路从 React 模板到 Vue Router该示例的初衷是在 Razzle 默认的 React 模板基础上完整替换为 Vue Vue Router。README 中列出了九步关键改动它们共同构成了一个可复制的集成清单安装connect-history-api-fallback、eslint-plugin-vue、razzle-plugin-vue、vue-template-compiler作为 devDependenciesconnect-history-api-fallback是vue-routerhistory 模式的必备中间件用于让 Express 在开发/生产服务器上把未知路径回退到应用入口vue-template-compiler是vue-router以及vue-loader编译.vue单文件组件所依赖的模板编译器。在 razzle 的 plugins 配置中加入vue。添加自定义.eslintrc遵循vuerecommended 规则集并使用babel-eslint作为解析器。安装vue、vue-router、vue-server-renderer作为 dependencies。彻底移除react、react-dom、react-router-dom。将server/server.js改为使用vue-server-renderer的renderToString函数渲染应用启用 history 模式并加入服务端路由。更新client.js等待vue-router就绪后再将 Vue 挂载到#app并启动 HMR。新增Home.vue、About.vue、PageNotFound.vue三个页面组件。router.js导出VueRouter实例并配置全部页面路由。值得注意的是 README 中第 4 步出现了两次编号均为4.属于原文档笔误实际对应移除 React 相关依赖与改造服务端渲染两个独立步骤。此外示例的src目录中还保留了App.js导出createVueApp工厂函数与index.jsRazzle 约定的服务器入口二者是 Razzle 通用架构中的关键拼图下文会逐一解析。依赖与插件配置让 Razzle 认识 .vue 文件package.json双端依赖划分完整的依赖清单见 examples/with-vue-router/package.json核心划分如下dependencies运行时会被打包进客户端与服务端产物{ express: ^4.17.1, vue: ^2.6.11, vue-router: ^3.1.6, vue-server-renderer: ^2.6.11 }devDependencies构建期{ babel-preset-razzle: 4.2.15, connect-history-api-fallback: ^1.6.0, eslint-plugin-vue: ^6.2.2, razzle: 4.2.15, razzle-plugin-vue: 4.2.15, vue-template-compiler: ^2.6.11, webpack: ^4.44.1, webpack-dev-server: ^3.11.2 }示例同时提供了完整的 npm scriptsexamples/with-vue-router/package.jsonyarn build产出生产构建yarn start:prod以NODE_ENVproduction node build/server.js直接启动生产服务器yarn lint对src下的.js与.vue文件执行 ESLint 检查。razzle.config.js一行插件声明整个配置仅一行见 examples/with-vue-router/razzle.config.jsmodule.exports { plugins: [vue], };razzle-plugin-vue 做了什么插件vue由 monorepo 内的 packages/razzle-plugin-vue 提供其核心实现位于 packages/razzle-plugin-vue/index.js通过modifyWebpackConfig钩子对 Razzle 的 webpack 配置做了四处关键修改扩展名注册向config.resolve.extensions追加.vue使import Home from ./Home.vue这类省略扩展名的写法可用ESM 别名将vue$指向vue/dist/vue.esm.js确保拿到支持 ESM 模块互操作的 Vue 构建替换 CSS 处理链先借助WebpackConfigHelpers.makeLoaderFinder(css-loader)过滤掉 Razzle 默认的 CSS loader 规则再前置插入vue-style-loadercss-loader使.vue单文件组件内的style块能被正确提取接入 vue-loader新增test: /\.vue$/规则使用vue-loader并传入ident: razzle-vue-loader同时config.plugins.push(new VueLoaderPlugin())注册其配套插件。这就是零配置背后真实发生的 webpack 编排——你只需要声明plugins: [vue]Razzle 会自动完成上述全部改动。该插件独立的安装与配置说明同样记录在 packages/razzle-plugin-vue/README.md。路由定义history 模式与按路由代码分割路由配置位于 examples/with-vue-router/src/router.js它是整个示例的路由真相源import Vue from vue; import VueRouter from vue-router; import Home from ./Home.vue; // The () import() syntax is used for webpacks lazy loading and code splitting functionality const About () import(/* webpackChunkName: AboutPage */ ./About.vue); const PageNotFound () import(/* webpackChunkName: PageNotFound */ ./PageNotFound.vue); Vue.use(VueRouter); // Create a router in history mode // By default vue-router uses hash mode urls: localhost:3000/#/about // History mode allows regular urls: localhost:3000/about export default new VueRouter({ mode: history, routes: [ { path: /, component: Home }, { path: /about, component: About }, { path: *, component: PageNotFound }, // wildcard route match, if havent matched previous: 404 ], });这里有三个值得展开的工程要点history 模式mode: history让 URL 呈现为干净的localhost:3000/about而非默认 hash 模式的localhost:3000/#/about。代价是刷新/about这类深层路径时请求会直接打到服务器因此必须配合服务端回退见下一节connect-history-api-fallback才能避免 404。按路由懒加载Home被同步import首屏所需而About与PageNotFound使用() import()动态导入并借助webpackChunkName注释指定产物 chunk 名称AboutPage、PageNotFound。这正是 Vue Router 官方推荐的懒加载与代码分割实践在 Razzle 中同样生效。通配 404{ path: *, component: PageNotFound }作为兜底路由任何未匹配路径都会渲染PageNotFound页面。服务端渲染vue-server-renderer 与路由就绪协调应用工厂函数服务端与客户端共享同一个新建应用工厂函数 examples/with-vue-router/src/App.jsimport Vue from vue; import VueApp from ./App.vue; import router from ./router; // Export a factory function for creating a fresh app export function createVueApp() { const app new Vue({ router, render: h h(VueApp), }); return { app, router }; }每次调用都会创建全新的Vue实例避免服务端多请求间状态串扰并将共享的router注入其中。根组件 examples/with-vue-router/src/App.vue 只包含一个router-view /所有页面都由它按当前路由动态渲染。server.js服务端路由三件套服务端核心实现位于 examples/with-vue-router/src/server.js其关键链路是import express from express; import history from connect-history-api-fallback; import { createVueApp } from ./App; const renderer require(vue-server-renderer).createRenderer(); const assets require(process.env.RAZZLE_ASSETS_MANIFEST);router.push(req.originalUrl)同步服务端位置根据请求原始 URL 将路由定位到对应组件router.onReady等待异步组件由于About/PageNotFound是动态导入必须等待其解析完成router.onReady(async () {...})后再渲染这是懒加载路由在 SSR 下必须处理的时序问题renderer.renderToString(app)输出 HTML调用vue-server-renderer的createRenderer().renderToString把 Vue 实例渲染为字符串随后拼装进完整的 HTML 模板并将div idapp${vueMarkup}/div与服务端渲染标记一起返回。同时示例实现了两个基于RAZZLE_ASSETS_MANIFEST的资源注入工具函数cssLinksFromAssets生成link relstylesheetjsScriptTagsFromAssets生成script src... defer crossorigin。它们读取 Razzle 在构建期产出的资源清单把client入口的 CSS 与 JS 分别注入head与body末尾从而保证 SSR 输出的页面自带完整样式和可水合的脚本引用。Express 服务器最终按以下方式组装const server express(); server .disable(x-powered-by) .use(express.static(process.env.RAZZLE_PUBLIC_DIR)) .get(/*, async (req, res) { const { html } await renderApp(req, res); res.send(html); }); export default server;这里express.static(process.env.RAZZLE_PUBLIC_DIR)负责托管public/目录下的静态资源如favicon.ico、robots.txtget(/*)则对所有 GET 请求执行 SSR 渲染。README 中提到必须安装的connect-history-api-fallback已在此文件的 import 处引入——虽然该示例最终以get(/*)统一接管了所有路径的回退但connect-history-api-fallback正是 history 模式下深层路径刷新不 404这一需求的通用解法在自定义路由中间件或生产部署如搭配静态托管时不可或缺。客户端水合等路由就绪再挂载客户端入口 examples/with-vue-router/src/client.js 与 React 模板中直接ReactDOM.hydrate不同必须先等路由就绪import { createVueApp } from ./App; const { app, router } createVueApp(); router.onReady(() { app.$mount(#app); }); if (module.hot) { module.hot.accept(); }router.onReady(() app.$mount(#app))与server.js中的等待逻辑一一对应。路由解析完异步组件后Vue 才挂载到服务端渲染出的#app节点完成客户端水合复用服务端 DOM 并接管事件绑定module.hot.accept()声明接受 HMR 更新配合 Razzle 内置的webpackHotDevClient实现开发期热替换。服务器入口 examples/with-vue-router/src/index.js 则保持了 Razzle 模板的通用写法将 Express app 包装后监听process.env.PORT || 3000并对./server模块启用服务端 HMR修改server.js后自动重启控制台输出 HMR Reloading ./server...与✅ Server-side HMR Enabled!。页面组件router-view 与 router-link 的配合示例的四个 Vue 组件共同演示了 Vue Router 的核心用法examples/with-vue-router/src/App.vue根组件模板仅含router-view /作为所有页面的渲染出口examples/with-vue-router/src/Home.vue首页展示vue.svgLogo 与{{ greeting }}值为Hello Vue!并通过router-link to/aboutAbout/router-link提供声明式导航examples/with-vue-router/src/About.vue关于页展示About Page标题与返回首页的router-link to/Home/router-linkexamples/with-vue-router/src/PageNotFound.vue404 兜底页文案为404: Page not found.。router-link是 Vue Router 的声明式导航组件在 history 模式下会拦截点击并调用router.push做客户端过渡避免整页刷新而首次请求仍由服务端直接渲染对应页面两者结合构成了完整的通用路由体验。验证与常见问题验证清单yarn start后访问/、/about查看页面源码应能看到服务端渲染出的完整 HTML而非空#app容器直接刷新/about确认不会出现 404——这是 history 模式 SSR 的关键验收点访问/some-random-path应渲染PageNotFound的 404 页面修改Home.vue的greeting观察浏览器无需刷新即热更新修改server.js观察终端出现服务端 HMR 日志。注意事项版本前提本示例基于 Vue 2vue^2.6.11、Vue Router 3vue-router^3.1.6与vue-server-renderer^2.6.11配套razzle-plugin-vue4.2.15若迁移到 Vue 3 / Vue Router 4需要更换为对应的渲染器与插件体系不能直接照搬本示例依赖。history 模式的服务器要求一旦使用mode: history生产服务器必须把所有非静态资源请求回退到应用入口本示例用get(/*)统一接管其他场景可用connect-history-api-fallback中间件否则深层路径刷新会 404。SSR 状态隔离务必通过createVueApp()工厂函数为每个请求创建全新实例避免服务端多请求共享同一 Vue 实例导致的状态串扰。懒加载与 onReady路由包含异步组件时服务端与客户端都必须先router.onReady再渲染/挂载否则会出现 SSR 与客户端渲染内容不一致的水合警告。通过 examples/with-vue-router 这一完整示例你可以在不放弃 Razzle 零配置体验的前提下获得 Vue 2 Vue Router 3 的完整通用渲染能力history 模式 URL、SSR 首屏、按路由代码分割、客户端水合与双端 HMR 开箱即用。赞分享前端构建工具前端构建后端【免费下载链接】razzle✨ Create server-rendered universal JavaScript applications with no configuration项目地址https://gitcode.com/gh_mirrors/ra/razzle点击查看免费下载相关推荐在 Razzle 中集成 Vuerazzle-plugin-vue 插件实现服务端渲染通用应用在 Razzle 中集成 Vuerazzle plugin vue 插件实现服务端渲染通用应用 本指南以 Razzle 官方插件 razzle plugin前端构建工具前端构建后端在 Razzle 中集成 React Native Web零配置搭建服务端渲染的通用 React 应用在 Razzle 中集成 React Native Web零配置搭建服务端渲染的通用 React 应用 本指南围绕 Razzle 仓库中的 with reac前端构建工具前端构建后端Razzle 集成 Hyperapp用 hyperapp/render 打造零配置的服务端渲染SSR通用应用Razzle 集成 Hyperapp用 hyperapp/render 打造零配置的服务端渲染SSR通用应用 导读 本篇以 examples/with前端构建工具前端构建后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表