Angular 15 SSR中如何预加载带哈希后缀的styles.css文件
Angular SSR 预加载带哈希后缀的styles.css解决方案
针对生产构建后styles文件带随机哈希后缀的问题,以下是两种可靠的实现方式:
一、将preload标签插入HTML头部
步骤1:获取哈希后的styles文件名
在SSR服务端文件(如server.ts)中,通过读取构建生成的index.html或asset manifest文件提取正确的文件名:
- 方式A:读取index.html提取
import { readFileSync } from 'fs'; import { join } from 'path'; // 读取browser目录下的生产环境index.html const indexHtml = readFileSync(join(process.cwd(), 'dist/your-project/browser/index.html'), 'utf-8'); // 正则匹配提取带哈希的styles文件名 const styleMatch = indexHtml.match(/<link rel="stylesheet" href="(styles\.[a-f0-9]+\.css)">/); const styleHref = styleMatch ? styleMatch[1] : 'styles.css'; // 降级处理
- 方式B:通过webpack manifest文件提取(更可靠)
先在自定义webpack配置中添加WebpackManifestPlugin生成资源清单:
// webpack.server.config.js const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); module.exports = { plugins: [ new WebpackManifestPlugin({ fileName: 'asset-manifest.json', publicPath: '/' }) ] };
然后在服务端读取清单:
const manifest = require(join(process.cwd(), 'dist/your-project/browser/asset-manifest.json')); const styleHref = manifest['styles.css'] || 'styles.css';
步骤2:插入preload标签到HTML
使用renderModule渲染应用时,直接修改生成的HTML内容:
import { renderModule } from '@angular/platform-server'; import { AppServerModule } from './src/main.server'; async function handleRequest(req, res) { let html = await renderModule(AppServerModule, { document: indexHtml, url: req.url }); // 在head标签结束前插入preload标签 const preloadTag = `<link rel="preload" href="/${styleHref}" as="style" />`; html = html.replace('</head>', `${preloadTag}</head>`); res.send(html); }
二、添加到Link响应头
在SSR服务端的请求处理逻辑中,直接设置HTTP响应头,无需修改HTML内容:
async function handleRequest(req, res) { // 先通过上述方式获取styleHref // 设置Link响应头 res.setHeader('Link', `</${styleHref}>; rel=preload; as=style`); // 渲染并返回应用HTML const html = await renderModule(AppServerModule, { document: indexHtml, url: req.url }); res.send(html); }
注意:两种方式都不会导致重复下载资源,浏览器会自动复用预加载的styles文件给后续的<link rel="stylesheet">标签使用。
内容的提问来源于stack exchange,提问作者ciekals11
相关产品推荐
相关产品推荐

