阅读 178

Taro3中多端组件的项目配置bug解决方案

前段时间公司业务项目升级Taro3之后,进行跨端编译的时候出现问题了。通过控制台的编译报错发现,问题出现在项目配置上。

业务场景

事情的起因是这样的,为了满足业务的需求,解决不同端的差异性问题。虽然Taro内置了环境变量TARO_ENV可以解决跨端的问题,但是会让代码中充斥着大量的逻辑判断的代码,影响代码的可维护性,而且也让代码的可读性变得非常低。为了解决这个问题,进行业务开发的时候采用了多端组件的解决方案。

多端组件(官方文档)

开发者可以通过使用统一接口的多端文件,来解决跨端差异的功能。开发者可以通过将文件修改成 原文件名 + 端类型 的命名形式(端类型对应着 process.env.TARO_ENV 的取值),不同端的文件代码对外保持统一接口,而引用的时候仍然是 import 原文件名的文件。Taro 在编译时,会跟根据当前的编译平台类型,将加载的文件变更为带有对应端类型文件名的文件,从而达到不同的端加载对应文件的目的。

问题复现

首先展示一下项目结构,由于涉及到公司业务,所以具体代码就不展现了。

├── app.tsx 通用端的业务入口 ├── app.config.ts 通用端的项目配置 ├── app.weapp.tsx 支付宝端的入口文件 └── app.weapp.config.ts 支付宝端的项目配置 复制代码

进行 npm run build:alipay 的时候,编译正常,而进行 npm run build:weapp 的时候,就进行编译报错。报错信息如下:

企业微信截图_16452531025715.png

解决历程


报错初步分析

通过报错信息,发现报错原因来源于 @tarojs/mini-runner 插件的 src/plugins/MiniPlugin.ts 的901行。我进入源码查看,经过一番调试发现,原来问题是这样的:

首先,在获取 app config 配置内容的时候,生成的 this.filesConfig 内容,跟在生成小程序相关文件的获取 app config 配置内容的时候 this.filesConfig[appConfigName] 的时候 key 不匹配。

    // this.filesConfig     {       'app.config': {         content: { pages: [Array], window: [Object] },         path: '...\\src\\app.weapp.config.ts'       },       ...     }     // appConfigName     app.weapp.config 复制代码

造成这个原因的源代码:

    // 生成小程序相关文件     const appConfigPath = this.getConfigFilePath(this.appEntry);     const appConfigName = path.basename(appConfigPath).replace(path.extname(appConfigPath), '');     this.generateConfigFile(compilation, this.appEntry, this.filesConfig[appConfigName].content);     // 获取 app config 配置内容     const appName = path.basename(this.appEntry).replace(path.extname(this.appEntry), '');     const fileConfig = this.filesConfig[this.getConfigFilePath(appName)]; 复制代码

初步猜测

既然导致这个问题的原因是,获取 app config 配置的 key 和 生成 app config 配置的 key 不一致导致的,那么,我是不是有可能通过调整 config 配置文件的名称来解决呢?貌似可行哈。具体尝试方案如下:

  1. 将 app.weapp.config 删除;

  2. 在 app.config.ts 文件中,通过 process.env.TARO_ENV 来配置不同端的项目配置;

  3. 重新执行 npm run build:weapp

测试结果

很遗憾,GG了,产生了新的报错信息:

企业微信截图_16452546913745.png

问题出现在哪里呢?第一反应是,陷入死循环了,除非掉头回去使用环境变量来解决入口问题,否则就是死胡同。喝口凉水,冷静一下,发现我一开始的思路就进入了错误的方向。我正确的解决方向应该是,通过解决this.getConfigFilePath 和 appConfigName 的差距就可以了。

再次猜测

首先我分析了一下 path.basename(this.appEntry).replace(path.extname(this.appEntry), ''),path.basename 获取路径的最后一部分,path.extname 获取路径的扩展名;然后,正常编译的时候 this.appEntry 是 */src/app.tsx,对应的 appName 是 app,而进行 weapp 编译的时候,this.appEntry 是 */src/app.weapp.tsx,对应的 appName 是 app.weapp,通过this.getConfigFilePath得到的结果都是 app.config。

看完这里我就恍然明白问题所在了,原来是 getConfigFilePath 的问题。那就再深入去看一下 getConfigFilePath 的内容。

    helper_1.resolveMainFilePath(`${filePath.replace(path.extname(filePath), '')}.config`) 复制代码

真正的问题点完全浮出水面了,path.extname 处理 app.weapp 的时候,把 .weapp 当作文件的扩展名给 replace掉了

再次尝试

我通过process.env.TAR_ENV来判断path.extname获取的是端类型,还是真正的扩展名,然后做出不同的处理,具体处理代码如下:

    const extname = path.extname(filePath);     if (`.${process.env.TARO_ENV}` === extname) {         return helper_1.resolveMainFilePath(`${filePath}.config`)     }     return helper_1.resolveMainFilePath(`${filePath.replace(path.extname(filePath), '')}.config`); 复制代码

经过尝试,万事大吉,成功ko掉了。


好的,问题已经解决了,希望对大家有所帮助。欢迎大家点赞关注,在下方评论区留言交流。


作者:花开花落花中妖
链接:https://juejin.cn/post/7066328625833836574

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐