发现问题
看到 vue-cli3 和 framework7 都升级到3.0了,团队打算用新版本做些新东西.
有 https://github.com/framework7... 和 vue-cli3 中文文档的加成, 开始还算顺利, npm run serve
也能把项目跑起来. 但是 npm run build
打包的时候发生问题了. 报错如下:
ERROR Error: CSS minification error: Parse error on line 1:
8px + constant(safe-area-i
------^
Expecting ‘SUB‘, ‘LPAREN‘, ‘NESTED_CALC‘, ‘NUMBER‘, ‘CSS_VAR‘, ‘LENGTH‘, ‘ANGLE‘, ‘TIME‘, ‘FREQ‘, ‘RES‘, ‘EMS‘, ‘EXS‘, ‘CHS‘, ‘REMS‘, ‘VHS‘, ‘VWS‘, ‘VMINS‘, ‘VMAXS‘, ‘PERCENTAGE‘, got ‘PREFIX‘. File: chunk-vendors.842c282c.css
Error: CSS minification error: Parse error on line 1:
8px + constant(safe-area-i
------^
Expecting ‘SUB‘, ‘LPAREN‘, ‘NESTED_CALC‘, ‘NUMBER‘, ‘CSS_VAR‘, ‘LENGTH‘, ‘ANGLE‘, ‘TIME‘, ‘FREQ‘, ‘RES‘, ‘EMS‘, ‘EXS‘, ‘CHS‘, ‘REMS‘, ‘VHS‘, ‘VWS‘, ‘VMINS‘, ‘VMAXS‘, ‘PERCENTAGE‘, got ‘PREFIX‘. File: chunk-vendors.842c282c.css
at D:\work\mobile3\node_modules\@intervolga\optimize-cssnano-plugin\index.js:106:21
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! mobile3@0.1.0 build: `vue-cli-service build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the mobile3@0.1.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\zz\AppData\Roaming\npm-cache\_logs\2018-08-16T05_07_51_763Z-debug.log
分析问题
首先观察这是一个 CSS minification 的报错, 说是 calc 函数没有收到正确的值.
再以报错信息 8px + constant(safe-area-i
搜索 f7 的 css 文件 发现很多这样的代码:
padding-left: calc(8px + constant(safe-area-inset-right));
padding-left: calc(8px + env(safe-area-inset-right));
然后搜索 safe-area-inset-right
, 发现这是一个 iPhone X (有文章: http://www.css88.com/archives... )的属性, 作用是用来解决iPhone X 额头的凹槽带来的问题.
再以 constant
为关键字去搜索 vue-cli3 的issue.
https://github.com/vuejs/vue-... 尤大表示是 cssnano 的问题
https://github.com/framework7... framework7 的作者表示这是 ios 必须的, 不是我的错, 请向 cssnano 提出问题.
https://github.com/cssnano/cs... cssnano 说 safe-area-inset-right 这个属性是非标准的, 是苹果 iPhone x 私有的, 而且也不是我的锅, 你看看 reduce-css-calc 吧
https://github.com/MoOx/reduc... reduce-css-calc 表示知道,但没有解决
总结一下, f7 使用了一个iPhone x 专用的非标准 css 属性, 导致 cssnano 中一个处理 calc 的小插件标错.
解决问题
取消使用calc插件 (失败)
首先想到的是取消 cssnano 中这个小插件的使用, 首先尝试修改 node_modules/@vue/cli-service/lib/config/css.js
中的 cli 配置文件将下面一段全部注释掉
webpackConfig
.plugin(‘optimize-css‘)
.use(require(‘@intervolga/optimize-cssnano-plugin‘), [{
sourceMap: options.productionSourceMap && sourceMap,
cssnanoOptions: cssProcessorOptions
}])
尝试注释掉整个 cssnano, 发现 npm run build
可以通过, css未压缩.
然后看能不能只取消 calc 插件的使用, 看 https://cssnano.co/ cssnano 官网, npm, github, 愣是没找到完整的参数配置说明, 只有 https://cssnano.co/guides/pre... 中的简单介绍和示例, 在 cli 的配置文件中尝试设置 calc:false
也没有用,这个方法失败.
用复制文件的方法临时解决 (成功)
取消使用行不通只能等 cssnano 的大神再看看了,毕竟iPhone用户那么多,总会解决的.但是项目不等人,考虑到即便这个插件更新了也还要等 vue-cli 更新,打算先找个临时解决方法.
考虑了一下, 官方示例是在 main.js
中引用 css文件的, 所以css 要经过优化处理. 但是 f7 官方其实提供了 framework7.min.css
这样的文件, 完全可以不经过我们的优化处理直接使用,所以尝试直接在 index.html
中引用 css 文件.首先考虑直接把 css 文件拿出来放到 public 目录, 但是觉得不妥, 一方面这个 css 文件放入版本管理有些不必要, 另一方面每次 f7 更新都要记得自己去更新这个文件很麻烦, 所以参考官方文档 https://cli.vuejs.org/zh/config/#chainwebpack
的语法修改 webpack 配置,用 copy 插件把文件拷贝出来
代码如下:
// vue.config.js
const path = require(‘path‘);
module.exports = {
chainWebpack: config => {
config
.plugin(‘copy-f7-css‘)
.use(require(‘copy-webpack-plugin‘), [[{
from: path.resolve(__dirname,‘./node_modules/framework7/css/framework7.min.css‘),
to: path.resolve(__dirname,‘./dist/css‘),
}]])
}
}
同时把 main.js
里的 f7 的 css 引用注释掉.
执行 npm run build
问题解决.
只是以后我们自己想使用 safe-area-inset-
这样的属性还会造成错误的, 所以不算正真地解决了这个问题, 不过只能先这样解决了.