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' }), ] };
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;
{ colors: string[]; // 匹配的顏色數組,若是出現顏色層次錯誤覆蓋的狀況,須要選上被覆蓋的顏色,可經過該選項在不一樣的文件提取不一樣的顏色 only?: boolean = true; // 僅提取選中顏色規則,不然會將整個文件提取進去 modules?: boolean = false; localIdentName?: string = ''; }
{ fileName?: string; // 提取顏色的文件名,不提供則直接嵌在 script標籤中 variableName?: string = 'CSS_EXTRACT_COLOR_PLUGIN'; // 掛載到window的變量名, 默認 CSS_EXTRACT_COLOR_PLUGIN }
examplereact
一個更復雜的例子-RyanCMS內容管理系統webpack