vue-cli2打包前和打包后的css前缀不一致的问题解决


Posted in Javascript onAugust 24, 2018

??乱还?/strong>

最近基于vue-cli2 学习webpack,将vue-cli2的webpack配置强撸了一遍,感觉身体已被掏空。。。但还是收获不少的,起码掌握了webpack的一些基本套路、开发环境和生产环境的概念、根据不同的环境写不同的webpack配置、和一些常用插件的用法等。

问题来了

基于vue-cli不用自己配置webpack开撸项目是十分爽的,但当我在撸得正爽的时候发现一个问题,就是项目打包前和打包后的css前缀不一致的,如下(浏览器:Chrome):

--给app.vue下的img添加样式

img{
 display: flex;
 transform: translateX(200px)
}

--打包前(即开发环境)img的样式

vue-cli2打包前和打包后的css前缀不一致的问题解决

--打包后(即生产环境)img的样式

vue-cli2打包前和打包后的css前缀不一致的问题解决

根据上面可看出打包前和打包后元素所带的css前缀不一致了。当我们给一个元素设置css3属性时,是希望它带有浏览器前缀来兼容的。vue-cli也给我们搭建这样的功能(是通过配置postcss的autoprefixer实现的)

--postcss配置写在.postcssrc.js,

module.exports = {
 "plugins": {
  "postcss-import": {},
  "postcss-url": {},
  // to edit target browsers: use "browserslist" field in package.json
  "autoprefixer": {}
 }
}

--浏览器规则则写在package.json上,

"browserslist": [
  "> 1%",
  "last 2 versions",
  "not ie <= 8"
 ]

--开发环境(build/webpack.dev.conf.js)样式相关的loader

module: {
  rules: utils.styleLoaders({ 
   sourceMap: config.dev.cssSourceMap, 
   usePostCSS: true })
 },

--生产环境(build/webpack.prod.conf.js)样式相关的loader

module: {
  rules: utils.styleLoaders({
   sourceMap: config.build.productionSourceMap,
   extract: true,
   usePostCSS: true
  })
 },

从上面可以看出,vue-cli的开发环境和生产环境都是使用了postcss的,并且配置是一样的,那么为什么打包前和打包后元素所带的css前缀不一致呢,

锁定问题

我们可以分析对比下build/webpack.dev.conf.js和build/webpack.prod.conf.js这两个文件,影响css的无非就module里处理样式的loader和处理css的插件plugin,从上面可以看出影响前缀的postcss的loader在两个环节中是一致的,那么就可以知道问题出在处理css的插件上了。

经过排查发现,webpack.prod.conf.js配置里是多了两个css处理插件的,如下

vue-cli2打包前和打包后的css前缀不一致的问题解决

ExtractTextPlugin这是提取分离css文件,不会影响css前缀,排除,那么问题就锁定到OptimizeCSSPlugin插件身上。再进一步,当我们把OptimizeCSSPlugin插件注释掉,然后打包测试,居然发现这时开发环境和生产环境的css前缀一致了,就是它了!!!

我们打开到npm官网搜一下这家伙https://www.npmjs.com/package/optimize-css-assets-webpack-plugin,这是一个优化压缩css代码的插件,但很失望,文档说明很少

但我们注意到有一句话很关键:

vue-cli2打包前和打包后的css前缀不一致的问题解决

什么鬼,这货里面依赖了cssnano,这插件也是用来优化处理css格式、前缀什么的。同时也有个autoprefixer配置参数,直接到它官网(这个好像需要番墙) https://cssnano.co/ 找到autoprefixer(比较难找得借助翻译):

vue-cli2打包前和打包后的css前缀不一致的问题解决

这里的翻译是:根据browsers选项删除不必要的前缀。请注意,默认情况下,它不会向CSS文件添加新前缀,这就可以解析清除我们的问题了,原来这插件的autoprefixer(默认应该是为true)把它认为不必要的前缀删掉了,而postcss的autoprefixer是将我们设定的浏览器范围的前缀加上,因此完美冲突了

解决问题

最后在github上找到解决方案(忘了复制找不回那地址了,具体为啥这样设置没说,这得深入这个插件的源码了),在build/webpack.prod.conf.js文件中OptimizeCSSPlugin插件的属性cssProcessorOptions加上autoprefixer:false来禁用它,避免冲突

vue-cli2打包前和打包后的css前缀不一致的问题解决

上代码:

new OptimizeCSSPlugin({
   cssProcessorOptions: config.build.productionSourceMap
    ? { safe: true, map: false,autoprefixer:false }
    : { safe: true, autoprefixer: false}
  }),

结论

最后,看看我们dev和build出来的css前缀,应该就一致的了:

问题原因就是:OptimizeCSSPlugin里面依赖了cssnano,而cssnano里面也有一个autoprefixer配置参数,它的作用是删除不必要的前缀(会误删在某些浏览器必要的前缀),这与postcss的autoprefixer效果冲突了,因此禁用它。

现在打包出来的与我们设定的浏览器范围对应的前缀一致,感觉整篇文章有点??铝耍??馐俏医饩稣馕适碧獾难?罚??锹家幌掳桑?缬蟹治霾欢缘穆榉持赋觯?恍唬?/p>

 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js中查找最近的共有祖先元素的实现代码
Dec 30 Javascript
将list转换为json失败的原因
Dec 17 Javascript
jQuery实现单击按钮遮罩弹出对话框(仿天猫的删除对话框)
Apr 10 Javascript
jquery制作漂亮的弹出层提示消息特效
Dec 23 Javascript
学习AngularJs:Directive指令用法(完整版)
Apr 26 Javascript
简单谈谈ES6的六个小特性
Nov 18 Javascript
VueJs路由跳转——vue-router的使用详解
Jan 10 Javascript
微信小程序 开发之顶部导航栏实例代码
Feb 23 Javascript
JavaScript+Html5实现按钮复制文字到剪切板功能(手机网页兼容)
Mar 30 Javascript
vue2.0之多页面的开发的示例
Jan 30 Javascript
javascript中关于类型判断的一些疑惑小结
Oct 14 Javascript
JavaScript 预解析的4种实现方法解析
Sep 03 Javascript
解决vue2.0 element-ui中el-upload的before-upload方法返回false时submit()不生效问题
Aug 24 #Javascript
AngularJS自定义表单验证功能实例详解
Aug 24 #Javascript
Vue源码解读之Component组件注册的实现
Aug 24 #Javascript
element-ui 关于获取select 的label值方法
Aug 24 #Javascript
微信小程序用户信息encryptedData详解
Aug 24 #Javascript
element-ui 中的table的列隐藏问题解决
Aug 24 #Javascript
实例详解ztree在vue项目中使用并且带有搜索功能
Aug 24 #Javascript
You might like
PHP中使用unset销毁变量并内存释放问题
2012/07/05 PHP
使用Linux五年积累的一些经验技巧
2013/06/20 PHP
使用PHP连接多种数据库的实现代码(mysql,access,sqlserver,Oracle)
2016/12/21 PHP
PHP基于递归实现的约瑟夫环算法示例
2017/08/27 PHP
解决html按钮切换绑定不同函数后点击时执行多次函数问题
2014/05/14 Javascript
js获取url中&quot;?&quot;后面的字串方法
2014/05/15 Javascript
Node.js实现在目录中查找某个字符串及所在文件
2014/09/03 Javascript
Node.js node-schedule定时任务隔多少分钟执行一次的方法
2015/02/10 Javascript
javascript如何操作HTML下拉列表标签
2015/08/20 Javascript
jquery选择器简述
2015/08/31 Javascript
jquery判断当前浏览器的实现代码
2015/11/07 Javascript
100多个基础常用JS函数和语法集合大全
2017/02/16 Javascript
JQuery判断radio单选框是否选中并获取值的方法
2019/01/17 jQuery
通过实例了解JS执行上下文运行原理
2020/06/17 Javascript
[55:45]DOTA2上海特级锦标赛D组败者赛 Liquid VS COL第一局
2016/02/28 DOTA
[01:07:20]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第二场 2月2日
2021/03/11 DOTA
详解Python的Twisted框架中reactor事件管理器的用法
2016/05/25 Python
Python中django学习心得
2017/12/06 Python
python实现m3u8格式转换为mp4视频格式
2018/02/28 Python
Python读取视频的两种方法(imageio和cv2)
2018/04/15 Python
python list元素为tuple时的排序方法
2018/04/18 Python
Python字典中的键映射多个值的方法(列表或者集合)
2018/10/17 Python
Python 单元测试(unittest)的使用小结
2018/11/14 Python
python日期相关操作实例小结
2019/06/24 Python
Python 获取ftp服务器文件时间的方法
2019/07/02 Python
python numpy实现rolling滚动案例
2020/06/08 Python
欧舒丹比利时官网:L’OCCITANE比利时
2017/04/25 全球购物
学期研究性学习个人的自我评价
2014/01/09 职场文书
护理学应聘自荐书范文
2014/02/05 职场文书
供应链金融服务方案
2014/05/25 职场文书
班主任寄语2015
2015/02/26 职场文书
通讯稿范文
2015/07/22 职场文书
情侣餐厅的创业计划书范本!
2019/07/26 职场文书
幽默口才训练经典句子(48句)
2019/08/19 职场文书
Nginx开启Brotli压缩算法实现过程详解
2021/03/31 Servers
idea编译器vue缩进报错问题场景分析
2021/07/04 Vue.js