我正试图在我的角度4应用程序中找到支持主题样式的最佳方式。 我正在使用SASS变量,主题设置依赖于4个SASS变量:主要和次要颜色,背景图像和黑暗/浅色主题切换。
现在,我想从应用程序动态更改主题。我现在有这个:
我正在使用sass-vars-loader库(https://github.com/epegzz/sass-vars-loader),并在应用构建期间将sass变量从JSON文件加载到我的_vars.scss中。当我从组件中更改这些变量时,我将新值写入JSON文件并触发应用程序重新编译,因为我正在监视该文件的更改。
这是在开发过程中成功重新编译并将新变量加载到_vars.scss中,但我的问题是如何在生产中支持它。
为了能够配置webpack,我用$ng eject
弹出了webpack.config.js,因此不再使用angular-cli命令了。
// webpack.config.js
...
{
"test": /\.scss$|\.sass$/,
"use": [
"style-loader",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "sass-loader",
"options": {
"sourceMap": false,
"precision": 8,
"includePaths": []
}
},
// Reads Sass vars from JSON
{ loader: "@epegzz/sass-vars-loader", options: {
files: [
path.resolve(__dirname, 'src/theme.json')
]
}
}
]
},
...
"devServer": {
setup: function(app) {
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.post("/theme", function(req, res) {
var payload = req.body,
theme;
fs.writeFileSync('src/theme.json', JSON.stringify(payload, null, 3));
res.send("Success");
});
},
}
我想我需要创建自定义node.js服务器,它将为我的应用程序提供服务并监视更改,就像webpack-dev-server在开发过程中所做的那样。
感谢任何帮助,谢谢。
答案 0 :(得分:0)
我建议您重新考虑使用构建工具的策略,但我不相信您需要构建服务器来实现您想要的结果。
也许您可以编译所有主题,并在运行时“交换”它们。 Replacing css file on the fly (and apply the new style to the page)
如果主题没有修复,即你可以有任何组合,也许你可以在主html页面中嵌入'主题'css并根据需要交换这些值。 Change CSS rule at runtime
---编辑---
我完全理解,在您的应用程序生命周期中必须对此进行重大设计更改是令人生畏的,但我非常确定您当前的方法会让您显得更加头疼。
Angular,SCSS,节点等不适合并且不适合您所描述的场景。
您是否意识到在您描述的场景中;如果任何用户触发“主题更改”,网站将在重新编译时“脱机”,并且使用该网站的所有人都可以看到应用的结果css主题,而不仅仅是触发它的用户?
此外,浏览器没有使用你的scss文件,它使用你所有SCSS文件的编译输出,我相信ng4的情况,是一个嵌入了CSS的JS文件。
为了做你正在提议的重新编译角度,(这将需要大量额外的后端服务器工作,并可能导致更复杂/可靠性问题),你需要获取并填充你的vars.SCSS文件,将它与所有其他SCSS文件结合起来,以某种方式复制角度CLI如何生成CSS嵌入式JS文件,然后将其加载到您的浏览器中,替换初始的...并且您需要从javascript / typescript中完成所有这些操作在浏览器中运行。
重新设计你的应用程序,创建一个css'overlay'文件,并在运行时交换值并将其加载到DOM中以更改主题。 我相信其他人也会在这里权衡,但我相信这是一个更好的方向,可以尽快得到你想要的结果。