在我的应用程序中,我有多个主题样式(您可以将它们视为不同的单独的CSS样式文件)。我想开始使用CSS模块,但我甚至不知道如何import
我的第一个文件。
让我们假设以下(简单)目录结构:
layouts/
themeA/
myComponent.css
themeB/
myComponent.css
themeC/
myComponent.css
components/
myComponent.js
根据用户设置,我想选择一个不同的CSS。这在浏览器(或服务器)上很容易实现。但是如何将myComponent.css包含到myComponent.js中呢?
根据CSS模块,我应该import
我正在使用的文件。所以import styles from 'theme/myComponent.css
。问题在于我没有一个真正的主题,而是3个不同的平行主题。
import styles from '' // <<<< from what?
return `<div class=${styles.caption></div>`
使用CSS模块时,是否可以使用多个布局/主题?
答案 0 :(得分:1)
您可以通过以下方式使用commonjs语法动态导入模块。
config.js:
export default function(key){
var themes = ['themea','themeb','themec'];
return themes[key] || theme[0];
}
main.js:
import getConfig from './config.js';
var styles = require('../css/' + getConfig(2) + '.css');
请务必使用babel-loader和style-loader / css-loader
我想出了以下动态文件加载代码
var even = 0;
var themes = ['themea', 'themeb', 'themec'];
var currentConfig = 'themea';
require.context("../css", true, /.css$/)
var cache = Object.assign({}, require.cache);
require('../css/themea.css');
$('#small-button').click(function(){
setConfig(themes[even]);
even = (even+1) % 3;
});
function setConfig(config) {
var modulename = '../css/' + currentConfig + '.css';
Object.keys(require.cache).forEach(function(cacheKey) {
Object.keys(cache).indexOf(cacheKey) < 0 ? delete require.cache[cacheKey] : null;
});
currentConfig = config;
cache = Object.assign({}, require.cache);
require('../css/' + currentConfig + '.css');
}
答案 1 :(得分:1)
If you bundle all 3 themes in one file. You can easily pick one of them and render component with it. You must have the same schema for all .css
themes, for example:
.wrapper {
// example content
}
.image {
// example content
}
In myComponent.js
you will import all themes and assign to object (it will be easier to pick one of them):
import themeA from './themeA.css';
import themeB from './themeB.css';
import themeC from './themeC.css';
const themes = {
light: themeA,
dark: themeB,
pink: themeC
}
Your themes will look something like this:
{
light: {
wrapper: "themeA---wrapper---2IVWH",
image: "themeA---image---3omJ7"
},
dark: {
wrapper: "themeB---wrapper---fHfAZ",
image: "themeB---image---17erf"
},
pink: {
wrapper: "themeC---wrapper---2i9L2",
image: "themeC---image---3OKIG"
}
}
Since css-modules are simple object with pointer to new class names you can dynamically pick one of them:
const render = themeName => {
const theme = themes[themeName];
return $(`
<div class="${theme.wrapper}">
<img
class="${theme.image}"
src="http://exmoorpet.com/wp-content/uploads/2012/08/cat.png"
/>
<p>Lorem ipsum </p>
</div>
`);
};
I used jQuery only for simplicity of mockups. You can see all working code here: webpackbin
If you use require.ensure
(great explanation here) you can download style in runtime.
Change myComponent.js
to async require:
import $ from 'jquery';
const render = (wrapper, theme) => {
const template = $(`
<div class="${theme.wrapper}">
<img
class="${theme.image}"
src="http://exmoorpet.com/wp-content/uploads/2012/08/cat.png"
/>
<p>Lorem ipsum </p>
</div>
`);
wrapper.html(template);
};
export default (wrapper, themeName) => {
switch(themeName) { // this will produce 3 chunks with styles
case 'light':
require.ensure([], () => {
render(wrapper, require('./themeA.css'));
});
break;
case 'dark':
require.ensure([], () => {
render(wrapper, require('./themeB.css'));
});
break;
case 'pink':
require.ensure([], () => {
render(wrapper, require('./themeC.css'));
});
break;
}
};
Webpack will produce this chunks (1 main and 3 with styles):
chunk {0} main.js (main) 267 kB [rendered]
[0] ./src/main.js 827 bytes {0} [built]
[1] ./~/jquery/dist/jquery.js 264 kB {0} [built]
[2] ./src/select.js 440 bytes {0} [built]
[3] ./src/myComponent.js 1.82 kB {0} [built]
chunk {1} 1.1.js 10.2 kB {0} [rendered]
[4] ./src/themeA.css 1.08 kB {1} [built]
[5] ./~/css-loader?modules&localIdentName=[name]---[local]---[hash:base64:5]!./src/themeA.css 428 bytes {1} [built]
[6] ./~/css-loader/lib/css-base.js 1.51 kB {1} {2} {3} [built]
[7] ./~/style-loader/addStyles.js 7.21 kB {1} {2} {3} [built]
chunk {2} 2.2.js 10.2 kB {0} [rendered]
[6] ./~/css-loader/lib/css-base.js 1.51 kB {1} {2} {3} [built]
[7] ./~/style-loader/addStyles.js 7.21 kB {1} {2} {3} [built]
[8] ./src/themeB.css 1.08 kB {2} [built]
[9] ./~/css-loader?modules&localIdentName=[name]---[local]---[hash:base64:5]!./src/themeB.css 429 bytes {2} [built]
chunk {3} 3.3.js 10.2 kB {0} [rendered]
[6] ./~/css-loader/lib/css-base.js 1.51 kB {1} {2} {3} [built]
[7] ./~/style-loader/addStyles.js 7.21 kB {1} {2} {3} [built]
[10] ./src/themeC.css 1.08 kB {3} [built]
[11] ./~/css-loader?modules&localIdentName=[name]---[local]---[hash:base64:5]!./src/themeC.css 432 bytes {3} [built]
I will prove that 3 chunks with styles contain your theme styles.
For example chunk 1
contains this code inside (I'm showing only important part of it):
/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {
exports = module.exports = __webpack_require__(6)();
// imports
// module
exports.push([module.id, ".themeA---wrapper---shnYu {\n background-color: #eee;\n color: #333;\n padding: 20px;\n}\n\n.themeA---image---18Mgb {\n float: left;\n height: 100px;\n margin: 20px;\n}\n", ""]);
// exports
exports.locals = {
"wrapper": "themeA---wrapper---shnYu",
"image": "themeA---image---18Mgb"
};
How it looks in runtime
Here you can check new code it will even show ajax download chunks - you can try in console.
答案 2 :(得分:-2)
如果您想在JavaScript中执行此操作,则可以执行if / else或switch语句。
var node = document.createElement("link").setAttribute("rel", "stylesheet") setAttribute("type", "text/css");
if (setting === 'A') {
node.setAttribute("href", "layouts/themeA/myComponent.css");
} else if (setting === 'B') {
node.setAttribute("href", "layouts/themeB/myComponent.css");
} else if (setting === 'C') {
node.setAttribute("href", "layouts/themeC/myComponent.css");
}
document.getElementsByTagName('head').appendChild(node);
或者在jQuery中:
var href;
if (setting === 'A') {
href = "layouts/themeA/myComponent.css";
} else if (setting === 'B') {
href = "layouts/themeB/myComponent.css";
} else if (setting === 'C') {
href = "layouts/themeC/myComponent.css";
}
$('head').append('<link href="' + href +'" rel="stylesheet" type="text/css" />');