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 相关文章推荐
jQuery 数据缓存模块进化史详细介绍
Nov 19 Javascript
javascript object array方法使用详解
Dec 03 Javascript
jquery.form.js用法之清空form的方法
Mar 07 Javascript
vue双向绑定的简单实现
Dec 22 Javascript
Bootstrap导航条鼠标悬停下拉菜单
Jan 04 Javascript
Javascript 详解封装from表单数据为json串进行ajax提交
Mar 29 Javascript
jQuery获取复选框选中的当前行的某个字段的值
Sep 15 jQuery
JavaScript基于面向对象实现的猜拳游戏
Jan 03 Javascript
浅谈SpringMVC中post checkbox 多选框value的值(隐藏域方式)
Jan 08 Javascript
elementui的默认样式修改方法
Feb 23 Javascript
Angular angular-file-upload文件上传的示例代码
Aug 23 Javascript
layui将table转化表单显示的方法(即table.render转为表单展示)
Sep 24 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
对于ThinkPHP框架早期版本的一个SQL注入漏洞详细分析
2014/07/04 PHP
php计算到指定日期还有多少天的方法
2015/04/14 PHP
Yii框架表单模型和验证用法
2016/05/20 PHP
[原创]php实现子字符串位置相互对调互换的方法
2016/06/02 PHP
Yii2.0预定义的别名功能小结
2016/07/04 PHP
详解PHP安装mysql.so扩展的方法
2016/12/31 PHP
PHP模糊查询技术实例分析【附源码下载】
2019/03/07 PHP
给moz-firefox下添加IE方法和属性
2007/04/10 Javascript
firefox 和 ie 事件处理的细节,研究,再研究 书写同时兼容ie和ff的事件处理代码
2007/04/12 Javascript
jquery 学习之二 属性 文本与值(text,val)
2010/11/25 Javascript
javascript模拟select,jselect的方法实现
2012/11/08 Javascript
from 表单提交返回值用post或者是get方法实现
2013/08/21 Javascript
JS更改select内option属性的方法
2015/10/14 Javascript
jQuery操作dom实现弹出页面遮罩层(web端和移动端阻止遮罩层的滑动)
2016/08/25 Javascript
jQuery实现为LI列表前3行设置样式的方法【2种方法】
2016/09/04 Javascript
jQuery ajax实现省市县三级联动
2021/03/07 Javascript
移动端web滚动分页的实现方法
2017/05/05 Javascript
bootstrap里bootstrap动态加载下拉框的实例讲解
2018/08/10 Javascript
vue项目实现表单登录页保存账号和密码到cookie功能
2018/08/31 Javascript
简单了解Javscript中兄弟ifream的方法调用
2019/06/17 Javascript
浅谈Vue3.0之前你必须知道的TypeScript实战技巧
2019/09/11 Javascript
Python实现字典依据value排序
2016/02/24 Python
Linux下通过python访问MySQL、Oracle、SQL Server数据库的方法
2016/04/23 Python
python3.0 模拟用户登录,三次错误锁定的实例
2017/11/02 Python
解决python通过cx_Oracle模块连接Oracle乱码的问题
2018/10/18 Python
tensorflow 利用expand_dims和squeeze扩展和压缩tensor维度方式
2020/02/07 Python
Django-xadmin后台导入json数据及后台显示信息图标和主题更改方式
2020/03/11 Python
JavaScript+Canvas实现自定义画板的示例代码
2019/05/13 HTML / CSS
英国领先的葡萄酒专家:Majestic Wine
2017/05/30 全球购物
GEOX鞋美国官方网站:意大利会呼吸的鞋
2017/07/12 全球购物
Richards网上商店:当代时尚,遍布巴西
2019/11/03 全球购物
新学期决心书
2014/03/11 职场文书
文体活动实施方案
2014/03/27 职场文书
李白故里导游词
2015/02/12 职场文书
文员岗位职责范本
2015/04/16 职场文书
SQL Server数据库备份和恢复数据库的全过程
2022/06/14 SQL Server