在 react 应用中,css 文件无法直接访问 `process.env`,因此不能在 `@import url(...)` 中拼接环境变量。本文介绍一种安全、标准且无需重复维护多份 css 的方案:通过 html `data-*` 属性注入环境信息,并结合 javascript 动态加载对应 cdn 样式表。
CSS 本身是静态资源,不支持运行时变量插值或环境判断,@import url('https://...' + process.env.REACT_APP_ENV) 这类写法在浏览器中完全无效——因为 process.env 是 Webpack 构建时注入的 Node.js 环境变量,仅在 JS 模块编译阶段可用,不会出现在最终生成的 .css 文件中,更无法被 CSS 解析器识别。
✅ 正确做法:由 JavaScript 控制动态加载逻辑,将环境标识提前注入 HTML 文档,再按需加载对应 URL 的样式表。
在 public/index.html 的 或 标签中注入环境标识
修改 public/index.html,利用 react-scripts 支持的 env 替换能力(需确保 REACT_APP_ENV 已在 .env 文件中定义):
⚠️ 注意:%REACT_APP_ENV% 是 react-scripts@5+ 支持的 HTML 模板变量语法(构建时自动替换),不是运行时 JS 表达式。确保 .env 文件包含如 REACT_APP_ENV=dev。
在入口 JS(如 src/index.js)中读取并动态加载 CSS
移除原 index.css 中的硬编码 @import,改用 JS 动态创建 标签:
// src/index.js(在 ReactDOM.render 之前执行)
const getCssUrl = () => {
const env = document.documentElement.dataset.env || 'dev';
const domainMap = {
dev: 'externalurldev01.blob.core.windows.net',
qa: 'externalurltest01.blob.core.windows
.net',
prod: 'externalurlprod01.blob.core.windows.net'
};
return `https://${domainMap[env]}/XXX/index.css`;
};
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = getCssUrl();
document.head.appendChild(link);(可选)增强健壮性:添加加载失败回退与去重
const loadExternalCss = (url) => {
if (document.querySelector(`link[href="${url}"]`)) return; // 避免重复加载
return new Promise((resolve, reject) => {
const link = Object.assign(document.createElement('link'), {
rel: 'stylesheet',
href: url,
onload: () => resolve(),
onerror: () => reject(new Error(`Failed to load CSS: ${url}`))
});
document.head.appendChild(link);
});
};
loadExternalCss(getCssUrl())
.catch(err => console.warn('External CSS load failed:', err));此方案已在生产级 React 应用中广泛验证,兼顾简洁性、可维护性与性能。