文章目录
项目场景
三年前,基于icejs 1.x+react16+ antd mobile 2.x 的脚手架开发移动端项目,此前为了兼容旧版项目,在使用antd mobile 5.x时都是使用的别名安装凡是,但最近发现icejs已经升级到2.0版,所以干脆在升级为ice2.0的同时也将antd-mobile直接升级为5.x,于是在着手改造期间遇到一些问题,此处记录下来~
一、编译报错及解决方案
1.编译启动报错:antd-mobile 对应样式文件找不到
原因分析
其实是由于同时升级了antd-mobile组件库,由原来的2.x升级到5.x, 原先的2.x样式是在对应组件的css文件夹下,升级到5.x后,组件样式是与组件同名同级的css后缀文件,需要修改对应插件配置
解决方案
找到
buide.json
文件中的plugins
配置,修改对应插件配置
原先的配置:
"plugins": [
[
"build-plugin-antd",
{
"importOptions": {
"libraryName": "antd-mobile",
"libraryDirectory": "es",
"style": "css"
}
}
],
// 其他插件...
]
新的配置:
"plugins": [
[
"build-plugin-antd",
{
"importOptions": {
"libraryName": "antd-mobile",
"libraryDirectory": "es/components",
"style": false
}
}
],
// 其他插件...
]
或者 直接将这个配置删除即可,此处可查看antd-mobile5.x的官方文档,注意加粗文本:
我的项目中是直接删除了这个插件的配置,样式文件找不到的报错就没有了。
2.编译启动报错:Invalid options object. PostCSS Loader has been initialized using an options object that does not match the API schema.
原因分析
在网上查找各种资料后发现都是说这个报错是因为postcss-loader
这个插件与webpack
不兼容的问题,再看报错提示下还有一段:
options has an unknown property 'plugins'. These properties are valid:
object { postcssOptions?, execute?, sourceMap?, implementation? } ....
大致意思就是:插件的属性中最多只能有postcssOptions?, execute?, sourceMap?, implementation
这四个配置,没有plugins
这个属性,此时找到项目中postcss-loader
的配置中查看:
module.exports = ({ onGetWebpackConfig }) => {
onGetWebpackConfig((config) => {
// 按需选择需要生效的规则
[
'scss',
'scss-module',
'css',
'css-module',
'less',
'less-module',
].forEach(rule => {
if (config.module.rules.get(rule)) {
config.module
.rule(rule)
.use('postcss-loader')
.tap(() => ({
plugins: [
// icejs 内置 autoprefixer 规则
autoprefixer({
overrideBrowserslist: [
'iOS >= 8',
'Android >= 4',
],
}),
// 此处添加其他自定义规则
px2rem({ remUnit: 37.5 })
]
})
);
}
});
});
};
解决方案
既然没有plugins
这个属性配置,那么就按照新的组件要求,将plugins
放置到postcssOptions
这个属性中,即改为:
config.module
.rule(rule)
.use('postcss-loader')
.tap(() => ({
// 增加 postcssOptions 属性包裹 plugins
postcssOptions: {
plugins: [
// icejs 内置 autoprefixer 规则
autoprefixer({
overrideBrowserslist: [
'iOS >= 8',
'Android >= 4',
],
}),
// 此处添加其他自定义规则
px2rem({ remUnit: 37.5 })
]
}
})
);
3. e.getIterator is not a function 报错
当上述两个问题都解决后,编译的报错变为 e.getIterator is not a function
原因分析
查找资料后发现,是由于使用了 postcss-px2rem
或 postcss-px2rem-exclude
导致的(项目使用的 react 是16.x 版本),可以改为使用 postcss-pxtorem
组件替换。
解决方案
首先,卸载 postcss-px2rem
或 postcss-px2rem-exclude
组件,安装postcss-pxtorem
组件。
其次,修改插件配置信息,还是在问题2的配置代码位置:
原先完整的配置如下:
const autoprefixer = require("autoprefixer");
// 原先此处使用了 postcss-px2rem-exclude
const px2rem = require("postcss-px2rem-exclude");
module.exports = ({ onGetWebpackConfig }) => {
onGetWebpackConfig((config) => {
// 按需选择需要生效的规则
[
'scss',
'scss-module',
'css',
'css-module',
'less',
'less-module',
].forEach(rule => {
if (config.module.rules.get(rule)) {
config.module
.rule(rule)
.use('postcss-loader')
.tap(() => ({
plugins: [
// icejs 内置 autoprefixer 规则
autoprefixer({
overrideBrowserslist: [
'iOS >= 8',
'Android >= 4',
],
}),
// postcss-px2rem-exclude 的相关配置
px2rem({ remUnit: 37.5 })
]
}));
}
});
});
};
修改后完整的配置如下:
const autoprefixer = require("autoprefixer");
// 改为使用 postcss-pxtorem 组件
const pxToRem = require("postcss-pxtorem");
module.exports = ({ onGetWebpackConfig }) => {
onGetWebpackConfig((config) => {
// 按需选择需要生效的规则
[
'scss',
'scss-module',
'css',
'css-module',
'less',
'less-module',
].forEach(rule => {
if (config.module.rules.get(rule)) {
config.module
.rule(rule)
.use('postcss-loader')
.tap(() => ({
postcssOptions: {
plugins: [
// icejs 内置 autoprefixer 规则
autoprefixer({
overrideBrowserslist: [
'iOS >= 8',
'Android >= 4',
],
}),
// postcss-pxtorem 组件相关配置
pxToRem({
rootValue: 37.5,
selectorBlackList: [], //过滤
propList: ['*'],
exclude: /node_modules/i // 过滤掉node_modules 文件夹下面的样式
}),
]
}
}));
}
});
});
};
到此处已经能正常编译启动。