uni-app扩展自定义编译平台(一)

612 阅读4分钟

以小程序产品为基础,进行个性化定制,给不同公司使用,是近来面临的问题。以b小程序为代表,经过半年多生产环境的考验,功能逐渐成熟,现将b小程序改造成可通用代码,方便给其他公司发布使用。UNI-APP中 条件编译为改造提供了方便,由于小程序都在运行在微信平台,因此需要自定义条件编译平台。

自定义条件编译平台

uni-app 通过在package.json文件中增加uni-app扩展节点,可实现自定义条件编译平台。

扩展新的平台后,有3点影响:

  1. 可以在代码里编写自定义的条件编译,为这个新平台编写专用代码
  2. 运行时可以执行面向新平台的编译运行
  3. 发行时可以执行面向新平台的编译发行

package.json扩展配置用法:

{
    /**
     * package.json其它原有配置 
     * 拷贝代码后请去掉注释!
     */
    "uni-app": {// 扩展配置
        "scripts": {
            "custom-platform": { //自定义编译平台配置,可通过cli方式调用
                "title":"自定义扩展名称", // 在HBuilderX中会显示在 运行/发行 菜单中
                "browser":"",  //运行到的目标浏览器,仅当UNI_PLATFORM为h5时有效
                "env": {//环境变量
                    "UNI_PLATFORM": "",  //基准平台
                    "MY_TEST": "", // ... 其他自定义环境变量
                 },
                "define": { //自定义条件编译
                    "CUSTOM-CONST": true //自定义条件编译常量,建议为大写
                }
            }
        }    
    }
}
扩展A平台

在package.json中配置如下代码:

// 添加运行,打包命令
// 本地运行
"aDev": "cross-env NODE_ENV=development A_NAME=a uniapp-cli custom mp-a",
// 打包
"aPro": "cross-env NODE_ENV=production A_NAME=a uniapp-cli custom mp-a",// 添加平台
"mp-a": {
    "title": "a小程序",
    "env": {
        "UNI_PLATFORM": "mp-weixin",
        "A_NAME": "a" // 添加环境变量,标识是哪个平台
    },
    "define": {
        "MP-A": true
    }
}

那么就可以在代码中使用自定义平台编译了:#ifdef MP-A ... #endif

配置项条件编译

配置项在config.ts中,新建一个文件夹./config/qwhs,用来存放琦王花生的配置,目前放置config.ts,color.scss。分别是各个环境项目配置和颜色配置,详情见项目代码。

在入口配置文件config.ts中通过条件编译的方式,引入各个平台下的配置。代码如下:

// 默认引入B的配置
let appConfig = require('@/config/b/config')
​
// #ifdef MP-B
appConfig = require('@/config/b/config')
// #endif
​
// #ifdef MP-A
appConfig = require('@/config/a/config')
// #endif
const { devConfig, uatConfig, productConfig, ossBaseUrl } = appConfig

这样,运行哪个平台,就会引入哪项配置,基本符合要求。

个性化颜色和图片

由于各个平台布局一致,颜色不同,图片不同,因此需要将原先代码中写死的颜色和图片抽处理一下。这是个巨大的工作,由于之前颜色全部写死,现在需要将主色,类主色等全部提取来,做成公共颜色文件。提取完成后,写在配置文件夹下color.scss,利用sass特性,引入全局,完成颜色换肤这项功能。

原项目代码中预留了./style./color.scss文件来定义主题色,只不过没有使用,现在尝试利用起来。运行起来发现条件不宜在这里使用,color.scss文件中:

@import "@/config/b/color.scss";
/* #ifdef MP-A */
@import "@/config/a/color.scss";
/* #endif */

这么导入样试文件是行不通的,没有起作用,那么这条路行不通了,继续尝试其他方法。

将样式注入全局,似乎是可行的,于是在vue.config.js文件中添加如下代码:

css: {
    loaderOptions: {
      scss: {
        prependData: process.env.A_NAME === 'a' ? `@import "./src/config/a/color.scss";`
          : process.env.A_NAME === 'c' ? `@import "./src/config/c/color.scss";`
            : `@import "./src/config/b/color.scss";`
      }
    }
  }

自定编译平台添加的A_NAME环境变量在这派上了用场,根据不同的环境,注入不同的样式文件,至此,换颜色的工作基本完成了。

由于图片之前抽取过,网络服务器获取,这项工作的工作量只在于复制一份一模一样的图片文件,根据UI替换切图,图片名称改成一样的,传到同一服务下,用文件夹来区分图片资源。具体代码如下:

// A
const ossBaseUrl = 'https://baidu.com/static_a/'
// B
const ossBaseUrl = 'https://baidu.com/static_b/'

ossBaseUrl这个常量存在各个项目配置中,引入config.ts时可使用。由于图片的名字和存放文件夹是一至的,也可以放到不同的服务器上,均能正常访问图片。

进行初步的改造后,项目的运行,换肤功能基本完成,还有其他的个性化配置均保存在配置中,如:公司全称,简称,客服热线,广告语等。