web端换肤功能-方案1

2020-06-03  本文已影响0人  828a8863cef9

1、版本

webpack: 4.42.1
html-webpack-plugin: 4.0.4
mini-css-extract-plugin: 0.9.0

2、方案

换肤分为白、黑两种风格。

(1)颜色变量定义

白色风格新增颜色变量文件/src/style/skin/white/white.less,文件内容定义需要换肤的颜色变量:

@body-background-color:#000;
@boder-color: #aaa;

同理黑色风格新增颜色变量文件/src/style/skin/black/black.less。

(2)样式文件定义

新增样式文件/src/style/components/home.less:

.page{
  background-color: @body-background-color;
}

(3)样式整合

白色风格样式整合,新增文件/src/style/skin/white/index.less:

@import './white.less';
@import '../components/home.less';

同理黑色风格样式整合/src/style/skin/black/index.less。

(4)entry入口增加css

entry: {
  'bundle': './src/index.js',
  'white.css': './src/style/skin/white/index.less',
  'black.css': './src/style/skin/black/index.less'
}

(5)使用插件mini-css-extract-plugin抽取css样式

plugins: [
  new MiniCssExtractPlugin({
    filename: '[name]',
    chunkFilename: '[id]'
  })
],
module: {
  rules: [
    {
      test: /\.less$/,
      use: [
        MiniCssExtractPlugin.loader,
        'css-loader',
        'less-loader'
      ]
    }
  ]
}

打包后生成white.css、black.css文件,并自动插入到<head>中的<link>标签中。入口文件打包后都会生成.js文件,使用插件mini-css-extract-plugin后,还是会有white.css.js、black.css.js文件,这两个文件又被插入到<script>标签中,所以要将white.css.js、black.css.js这两个文件删除,并且将对应的<script>标签中删除。

(6)自定义插件css-entry-plugin

const RE_CSS = /\.css$/i;
const RE_JS_MAP = /\.js(|map)$/i;
const HtmlWebpackPlugin = require('html-webpack-plugin');

function CssEntryPlugin(options) {
  this.options = options;
}
// 删除.css.js文件
CssEntryPlugin.prototype.apply = function(compiler) {
  compiler.hooks.emit.tapAsync('CssEntryPlugin', (compilation, callback) => {
    compilation.chunks.filter(chunk => {
      return RE_CSS.test(chunk.name);
    }).forEach(chunk => {
      chunk.files.forEach(file => {
        if(RE_JS_MAP.test(file)) {
          delete compilation.assets[file];
        }
      })
    })
  })
  // 删除script标签
  compiler.hooks.compilation.tag('CssEntryPlugin', (compilation, callback) => {
    HtmlWebpackPlugin.getHooks(compilation).alterAssetTags.tapAsync('CssEntryPlugin', (data, callback) => {
      let scripts = data.assetTags.scripts;
      if(Array.isArray(scripts)) {
        let newScripts = [];
        for(let i = 0; i < scripts.length; i++) {
          let src = scripts[i].attributes.src;
          src = src.substr(0, src.length - 3);
          if(!RE_CSS.test(src)) {
            newScripts.push(scripts[i]);
          }
        }
        data.assetsTags.scripts = newScripts;
      }
      callback(null, data);
    })
  })
}
module.exports = CssEntryPlugin

(7)换肤控制

两种风格的css都被加载到<link>标签上,通过改变<link>的disabled属性进行换肤。

let allLinks = document.querySelectorAll('link');
allLinlks.forEach(item => {
  ……
  item.setAttribute('disabled', 'disabled');
  ……
  item.removeAttribute('disabled');
  ……
})
上一篇下一篇

猜你喜欢

热点阅读