11

[新手坑] 02.Vue开发环境和生产环境样式不一致的问题

上次提到作用域问题, 导致样是不生效, 这次讲的是我之前遇到的一个小坑, 稍不留神就完蛋.

前阵子做的一个小项目, 引入了Vant的UI库, 外加自己写的很多样式, 在开发环境下测试完美, 直接就build出来上正式环境, 发现竟然有多处样式未生效的问题! 还好是新项目, 尚未推广, 因此除了内部同事测试发现, 没有造成恶劣影响, 不过以后还是要注意下, 开发环境看着没问题, 但是生产环境一定还是要再过一遍.

那么为什么会出现这个问题呢? 我下面来做些小的测试观察一下.

问题现象

在开发环境下, 每个不同块的style都会被单独提取插入到页面的head区域, 而生产出来的的文件是会被合并成一个文件, 在开发环境下, 这些style块的顺序又和生产环境编译出来的css文件内的顺序有差别, 导致我们在开发环境中, 使用了相同的优先级, 覆盖原Vant的UI样式看起来正常, 而在生产后, 顺序错误导致失效了!

为了更加方便测试, 我在vue-cli-mobile-study项目创建了一个分支02-build-css-order, 有兴趣可以看看~

本来想在不同块的css中添加注释以便于更明显的观察顺序变化, 结果发现生产环境中的注释被自动忽略了, 尝试去掉cssnano插件执行, 发现还是有部分注释没有展示出来, 因为不是很重要, 所以没有去纠结这块.

开发环境中的head区域有效的style有5个. 分别是

  1. index.html中的css样式
  2. vant的base.css内容
  3. 路径为./vue-cli-mobile-study/src/assets/styles/_uireset.css内容
  4. App.vue的css内容
  5. HelloWorld.vue的css内容

而生产出来的却和这个不同, 因为被合并为1个css文件了, 因此我们观察单个css文件的上面4块的顺序

  1. index.html中的css样式
  2. App.vue的css内容
  3. HelloWorld.vue的css内容
  4. vant的base.css内容
  5. 路径为./vue-cli-mobile-study/src/assets/styles/_uireset.css内容

当然, 其实在有作用域的组件中所包含的样式顺序对项目是没有影响的, 所以我们需要关注的是全局引入的样式顺序, 从上面的现象中可以看出, 除了核心文件index.html, 开发环境下, Vant样式默认在最前面(Vant实际上是Babel那边导入了), 而其他样式则似乎根据main.js入口的顺序, 以及渲染顺序来添加到html头部的; 而生产环境下, 相对诡异.

2018年4月21日补充

今天因为考虑到Vant的中部分reset样式并没有较好的对页面进行样式统一, 因此引入normalize.css, 于是基于上面的测试, 现在拥有6style. 而normalize.css在两种环境下的区别还是有的~

我将normalize.css直接写入main.js的顶部进行import, 发现可以很好的将normalize.css内的样式放在除了不可控制index.html内样式之后的首位. 这样就很棒棒了, 通常我们会将normalize.cssreset.css优先加载.

问题原因

我有在GitHub查阅过相关Issues, 也找过StackOverflow相关内容, 不过没有什么收获, 外加Webpack的高级配置方面也不是很熟悉, 因此也就没有研究出来, 如果有大神能指点一二欢迎留言.

解决方案

在需要覆盖第三方组件的默认样式是, 尽量使用高于第三方组件优先级的css样式, 以免出现开发环境和生产环境效果不同的情况.

在自己的组件样式编写中, 除了有公共的组件在不同页面的样式控制下可能需要全局样式外, 尽量写上作用域! 并且一定不要在自己写的组件内使用全局样式, 很容易出现顺序问题导致开发和生产结果不一致的情况!


whidy
984 声望79 粉丝

喜欢玩游戏听歌写东西 ฅʕ•̫͡•ʔฅ