webpack构建换肤功能的思路详解


Posted in Javascript onNovember 27, 2017

最近项目中要实现一个换肤的功能,大体想了下,记录一下思路

要实现换肤功能,目标就是打包生成多份皮肤文件,需要哪个就用哪个

打包生成多份皮肤文件因为项目是使用webpack构建的,要想生成多份css文件,就要在入口中配置多个入口文件,每个入口文件会提取出一个css文件

config.entry={
 app: ['./src/app.js'],
 defaultTheme: ['./src/theme.default.color.js'],
 orangeTheme:['./src/theme.orange.color.js'],
 blueTheme:['./src/theme.blue.color.js'],
}

app.js中

import "./app.styl" //整个项目的样式,在各种皮肤下都保持不变的那部分
theme.blue.color.js 蓝色皮肤js文件
import "./theme/blue.styl"

blue.styl 蓝色皮肤

@require "./css/skinTheme/var.blue" //样式变量,整体为蓝色风格的颜色值
@require "./css/skinTheme/theme.color" //提取出来的需要换肤的那部分样式如代码所示,几个主题js文件中只是单纯的

引入了相应的皮肤样式文件,这样,webpack打包后就会生成几个无用的js文件和一系列皮肤样式文件

到这一步,就得到了需要的皮肤文件,但是需要注意的是,webpack会将生成的js、css路径插入到模板html中,所以,我们打开构建后生成index.html会看到

<html>
 <head>
  <link rel="stylesheet" href="app.xxxx.css" rel="external nofollow" rel="external nofollow" >
  <link rel="stylesheet" href="defaultTheme.xxxxx.css" rel="external nofollow" >
  <link rel="stylesheet" href="orangeTheme.xxxxx.css" rel="external nofollow" >
  <link rel="stylesheet" href="blueTheme.xxxxx.css" rel="external nofollow" >
 </head>
 <body>
  <script src="app.xxxx.js"></script>
  <script src="defaultTheme.xxxx.js"></script>
  <script src="orangeTheme.xxxx.js"></script>
  <script src="blueTheme.xxxx.js"></script>
 </body>

</html>操作index.html接下来就需要操作打包后的index.html,将多余的js引用删掉,将皮肤路径提取出来,然后将皮肤引用删掉也就是要改成这样的文件

/build/index.html
<html>
 <head>
  <script>
   window.cssUrls={
    "defaultTheme":"/defaultTheme.4bdb738cdc062e7842ce.css",
    "orangeTheme":"/orangeTheme.4bdb738cdc062e7842ce.css","blueTheme":"/blueTheme.4bdb738cdc062e7842ce.css"
   }
  </script>
  <link rel="stylesheet" href="app.xxxx.css" rel="external nofollow" rel="external nofollow" >
 </head>
 <body>
  <script src="app.xxxx.js"></script>
 </body>
</html>可以写这样一个操作文件的函数
cssExtract.js
const DISTPATH = 'build/index.html'
const cheerio = require('cheerio')
const fs = require('fs')
const chalk = require('chalk')
const prefix = ['defaultTheme', 'orangeTheme', 'blueTheme']
const cssUrls = {}
function extractCss() {
 fs.readFile(DISTPATH, 'utf8', (err, data) => {
  if (err) {
   throw err
  }
  const $ = cheerio.load(data)
  /**
   * 删除所有主题css,相关链接保存在window.cssUrls中
   */
  $('link').each((index, item) => {
   const href = $(item).attr('href')
   for (const val of prefix) {
    if (href.indexOf(val) !== -1) {
     cssUrls[val] = href
     $(item).remove()
    }
   }
  })
  /**
   * 删除无用的js
   */
  $('script').each((index, item) => {
   const src = $(item).attr('src')
   for (const val of prefix) {
    if (src && src.indexOf(val) !== -1) {
     $(item).remove()
    }
   }
  })
  //插入行内js
  $('base').after(`<script>window.cssUrls=${JSON.stringify(cssUrls)}</script>`)
  fs.writeFile(DISTPATH, $.html(), err => {
   if (err) {
    throw err
   }
   console.log(chalk.cyan('extract css url complete.\n'))
  })
 })
}

extractCss()最后到这里,运行 webpack && node cssExtract.js,index.html就变成上面期望的那样,我们得要了皮肤文件的一个mapping,并保存在window.cssUrls中,接下来,通过切换按钮的方式切换皮肤还是什么其他的就可以自由发挥了.
需要说明的是,换肤功能的重点是对样式的重构,将需要换肤的所有样式提取到一起,通过变量来设置不同的主题

总结

以上所述是小编给大家介绍的webpack构建下换肤功能的实现思路详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
javascript String 的扩展方法集合
Jun 01 Javascript
用js的for循环获取radio选中的值
Oct 21 Javascript
sogou地图API用法实例教程
Sep 11 Javascript
jQuery获得子元素个数的方法
Apr 14 Javascript
jQuery实现自动输入email、时间和域名的方法
Aug 24 Javascript
Js查找字符串中出现次数最多的字符及个数实例解析
Sep 05 Javascript
详解Vue2 无限级分类(添加,删除,修改)
Mar 07 Javascript
使用vue构建一个上传图片表单
Jul 04 Javascript
jQuery实现节点的追加、替换、删除、复制功能示例
Jul 11 jQuery
基于JavaScript实现无缝滚动效果
Jul 21 Javascript
uni-app实现点赞评论功能
Nov 25 Javascript
keep-alive不能缓存多层级路由菜单问题解决
Mar 10 Javascript
vue实现商城上货组件简易版
Nov 27 #Javascript
修改UA在PC中访问只能在微信中打开的链接方法
Nov 27 #Javascript
Vue的移动端多图上传插件vue-easy-uploader的示例代码
Nov 27 #Javascript
vue实现商城购物车功能
Nov 27 #Javascript
Vim快速合并行及vim 将文件所有行合并到一行
Nov 27 #Javascript
详解利用Angular实现多团队模块化SPA开发框架
Nov 27 #Javascript
JavaScript实现修改伪类样式
Nov 27 #Javascript
You might like
解析php根据ip查询所在地区(非常有用,赶集网就用到)
2013/07/01 PHP
PHP获取当前完整URL地址的函数
2014/12/21 PHP
php实现多维数组中每个单元值(数字)翻倍的方法
2015/02/16 PHP
thinkPHP基于ajax实现的菜单与分页示例
2016/07/12 PHP
详解PHP归并排序的实现
2016/10/18 PHP
PHP并发查询MySQL的实例代码
2017/08/09 PHP
日期函数扩展类Ver0.1.1
2006/09/07 Javascript
彻底搞懂JS无缝滚动代码
2007/01/03 Javascript
JavaScript动态创建div属性和样式示例代码
2013/10/09 Javascript
JQuery调用WebServices的方法和4个实例
2014/05/06 Javascript
jQuery实现ajax调用WCF服务的方法(附带demo下载)
2015/12/04 Javascript
js replace()去除代码中空格的实例
2017/02/14 Javascript
JQuery实现图片轮播效果
2017/05/08 jQuery
在Js页面通过POST传递参数跳转到新页面详解
2017/08/25 Javascript
vue中如何动态绑定图片,vue中通过data返回图片路径的方法
2018/02/07 Javascript
解决vue中无法动态修改jqgrid组件 url地址的问题
2018/03/01 Javascript
js脚本中执行java后台代码方法解析
2019/10/11 Javascript
JS实现长图上下滚动效果
2020/03/19 Javascript
javascript 易错知识点实例小结
2020/04/25 Javascript
JS实现手写 forEach算法示例
2020/04/29 Javascript
如何利用 JS 脚本实现网页全自动秒杀抢购功能
2020/10/12 Javascript
jQuery实现购物车全功能
2021/01/11 jQuery
[01:25]2015国际邀请赛最佳短片奖——斧王《拆塔英雄:天赋异禀》
2015/09/22 DOTA
python实现分析apache和nginx日志文件并输出访客ip列表的方法
2015/04/04 Python
Python3 使用map()批量的转换数据类型,如str转float的实现
2019/11/29 Python
django orm模块中的 is_delete用法
2020/05/20 Python
浅析pandas随机排列与随机抽样
2021/01/22 Python
一套C++笔试题面试题
2012/06/06 面试题
生产部统计员岗位职责
2014/01/05 职场文书
预备党员转正思想汇报
2014/01/12 职场文书
医学生临床实习自我评价
2014/03/07 职场文书
歌唱比赛主持词
2014/03/18 职场文书
小学生田径运动会广播稿
2014/09/11 职场文书
2014年法院个人工作总结
2014/12/17 职场文书
公司股份转让协议书范本
2015/01/28 职场文书
幼儿园小班工作总结2015
2015/04/25 职场文书