美文网首页
web端换肤功能-方案1

web端换肤功能-方案1

作者: 828a8863cef9 | 来源:发表于2020-06-03 10:19 被阅读0次

    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');
      ……
    })
    

    相关文章

      网友评论

          本文标题:web端换肤功能-方案1

          本文链接:https://www.haomeiwen.com/subject/kjepzhtx.html