CSS 模块和多个布局/主题?

标签 css gruntjs gulp webpack css-modules

在我的应用程序中,我有多种主题样式(您可以将它们视为不同的、单独的 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 模块时甚至可以使用多个布局/主题吗?

最佳答案

如果您将所有 3 个主题捆绑在一个文件中。您可以轻松地选择其中一个并使用它渲染组件。所有 .css 必须具有相同的架构主题,例如:

.wrapper {
  // example content
}

.image {
  // example content
} 

myComponent.js您将导入所有主题并分配给对象(选择其中一个会更容易):
import themeA from './themeA.css';
import themeB from './themeB.css';
import themeC from './themeC.css';

const themes = {
  light: themeA,
  dark: themeB,
  pink: themeC
}

您的主题将如下所示:
{ 
    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"
    }
}

由于 css-modules 是带有指向新类名的指针的简单对象,因此您可以动态选择其中之一:
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>
  `);
};

我使用 jQuery 只是为了简化模型。
您可以在此处查看所有工作代码:webpackbin

在运行时异步加载样式(编辑)

如果您使用 require.ensure (很好的解释 here )您可以在运行时下载样式。
更改myComponent.js异步要求:
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 将生成这些 block (1 个主 block 和 3 个带样式):
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]

我将证明 3 个带有样式的 block 包含您的主题样式。
例如 chunk 1里面包含这段代码(我只展示了它的重要部分):
/***/ },
/* 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"
    };

它在运行时的样子

styles in runtime example

Here you can check new code它甚至会显示 ajax 下载 block - 你可以在控制台中尝试。

关于CSS 模块和多个布局/主题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38270362/

相关文章:

gruntjs - 咕噜声丑化。如何缩小并用结果替换原始文件?

gulp - 如何在 Visual Studio Code 中启用智能感知?

server - 在本地服务器上与团队一起使用 gulp。错误 : EPERM: operation not permitted,

javascript - grunt 新手 - 警告 : task "concat, uglify" not found

jasmine - 使用 Jasmine 2、Protractor 和 Gulp 显示规范文本

CSS div 问题

javascript - 遍历数据并从 csv 文件加载数据

javascript - 如何根据数字改变颜色

左上角第二行的 CSS 下拉菜单

twitter-bootstrap - 将自定义 Bootstrap 构建合并到项目 grunt 任务中