webpack插件 - css主題顏色提取-主題切換

css-color-extract-plugin


Install

npm install css-color-extract-plugin
yarn add css-color-extract-plugin
  • 該插件主要用於提取主題顏色
  • 提取到的css數據會掛載到window下
  • 經過顏色替換再插入到<style>,可達到動態修改主題的目的

演示圖

Usagecss


// webpack.config.jshtml

const CssColorExtractPlugin = require('css-color-extract-plugin').default;
const PRIMARY_COLOR = '#1890ff';
module.exports = {
    ...
    module: {
        rules: [
          {
            test: /\.css$/,
            exclude: '/\.module\.css$/',
            use: [
                "style-loader", 
                "css-loader", 
                {
                  loader: CssColorExtractPlugin.loader,
                  options: {
                    colors: [ PRIMARY_COLOR ]
                  }
              },
           ]
        },
        {
            test:  /\.module\.css$/,
            use: [
                "style-loader", 
                 {
                   loader: "css-loader", 
                   options: {
                     modules: true,
                     localIdentName: '[path][name]__[local]',
                   }
                                },
                {
                    loader: CssColorExtractPlugin.loader,
                    options: {
                    colors: [ PRIMARY_COLOR ],
                    modules: true,
                    localIdentName: '[path][name]__[local]',
                  }
               },
            ]
        }
      ]
    }
   ...
       plugins: [
      ...
      new CssColorExtractPlugin({ fileName: 'theme' }),
     ]
};

編譯後會在html中插入theme.js,其內容相似如下

window.CSS_EXTRACT_COLOR_PLUGIN = [
  {"source":".src-App-module__example {  background: #1890ff;}","fileName":"App.module.scss","matchColors":["#1890ff"]},
  {"source":".src-controller-blog-components-Header-Header-module__theme {  color: #067785;}.src-controller-blog-components-Header-Header-module__pc_header {  background: #1890ff;}.src-controller-blog-components-Header-Header-module__mb_header {  background: #1890ff;}.src-controller-blog-components-Header-Header-module__mb_header .src-controller-blog-components-Header-Header-module__mb_nav {  background: #1890ff;}","fileName":"Header.module.scss","matchColors":["#1890ff"]}
];

接着只要使用簡單的正則便可替換主題色

import React, { Component } from 'react';
import styles from './App.module.scss';
import { SketchPicker } from 'react-color';

function replaceColor(source, color, replaceColor) {
    return source.replace(new RegExp(`(:.*?\\s*)(${color})(\\b.*?)(?=})`, 'mig'), (group) => {
        return group.replace(new RegExp(`${color}`, 'mig'), replaceColor);
    });
}

const PRIMARY_COLOR = '#1890ff';

class App extends Component {
    
    async setColor(color) {
        const styleData = window.CSS_EXTRACT_COLOR_PLUGIN || [];
        const cssText = styleData.map((item) => item.source).join('');
        const styleText = replaceColor(cssText, PRIMARY_COLOR, color);
        const style = document.createElement('style');
        style.innerHTML = styleText;
        document.body.appendChild(style);
    }
    render() {
        return (
            <div className={styles['example']}>
                <SketchPicker onChangeComplete={(colorResult) => this.setColor(colorResult.hex)} />
            </div>
        );
    }
}

export default App;

loader Options

{
    colors: string[]; // 匹配的顏色數組,若是出現顏色層次錯誤覆蓋的狀況,須要選上被覆蓋的顏色,可經過該選項在不一樣的文件提取不一樣的顏色
    only?: boolean = true; // 僅提取選中顏色規則,不然會將整個文件提取進去
    modules?: boolean = false; 
    localIdentName?: string = '';
 }

plugin Options

{
      fileName?: string; // 提取顏色的文件名,不提供則直接嵌在 script標籤中
      variableName?: string = 'CSS_EXTRACT_COLOR_PLUGIN'; // 掛載到window的變量名, 默認 
 CSS_EXTRACT_COLOR_PLUGIN
 }

examplereact

一個更復雜的例子-RyanCMS內容管理系統webpack

相關文章
相關標籤/搜索