如何使用Angular Universal单次预渲染单个路由
单路由预渲染+复用已有静态资源实现方案
1. 配置单路由预渲染脚本
首先修改项目的预渲染配置,支持通过命令行指定单个路由进行预渲染:
第一步:新增npm脚本
在package.json中添加专门的单路由预渲染命令:
"scripts": { "prerender": "prerender-spa-plugin", "prerender:single": "node scripts/prerender-single.js" }
第二步:编写自定义预渲染脚本
创建scripts/prerender-single.js文件,实现仅渲染指定路由的逻辑:
const Prerenderer = require('@prerenderer/prerenderer'); const PuppeteerRenderer = require('@prerenderer/renderer-puppeteer'); const path = require('path'); const fs = require('fs'); // 从命令行获取目标路由,执行格式:npm run prerender:single -- /product/123 const targetRoute = process.argv[2]; if (!targetRoute) { console.error('请指定预渲染路由,示例:npm run prerender:single -- /article/456'); process.exit(1); } const prerenderer = new Prerenderer({ staticDir: path.join(__dirname, '../dist'), // 你的SPA构建产物目录 renderer: new PuppeteerRenderer({ renderAfterDocumentEvent: 'render-event', // 和全量预渲染保持一致的渲染触发时机 routes: [targetRoute] // 仅渲染指定路由 }) }); prerenderer.initialize() .then(() => prerenderer.renderRoutes()) .then(renderedRoutes => { renderedRoutes.forEach(route => { // 生成对应路由的文件路径(如/product/123.html) const outputPath = path.join(__dirname, '../browser', route.route.slice(1) || 'index.html'); // 自动创建目录(如product文件夹) const dir = path.dirname(outputPath); if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); // 写入预渲染的HTML文件 fs.writeFileSync(outputPath, route.html); console.log(`路由 ${route.route} 预渲染完成,输出路径:${outputPath}`); }); }) .catch(err => { console.error('预渲染失败:', err); prerenderer.destroy(); process.exit(1); });
2. 保证静态资源复用性
要让新生成的HTML自动复用服务器上已有的JS/CSS,需注意两点:
- 静态资源命名规则:如果用Webpack等工具给资源加哈希(如
main.abc123.js),需确保未修改的JS/CSS哈希值不变,这样新预渲染的HTML会自动引用旧的哈希资源; - 复用旧构建产物:单路由预渲染时,不要重新构建整个SPA,直接复用之前全量预渲染时生成的
dist目录下的JS/CSS文件,确保资源引用路径完全匹配。
3. 部署单个文件
预渲染完成后,只需要将生成的单个HTML文件(如browser/product/123.html)上传到服务器对应的目录,不需要覆盖已有的JS/CSS文件,新页面会自动复用服务器上的旧资源。
4. 优化建议
- 给服务器上的JS/CSS设置长缓存(如Nginx配置
Cache-Control: max-age=31536000),减少浏览器重复请求; - 后续更新全局JS/CSS时,先上传带新哈希的资源文件,再批量重新预渲染所有路由页面,实现渐进式更新。
内容的提问来源于stack exchange,提问作者Martinator
相关产品推荐
相关产品推荐

