uni-app 通过后缀名区分不同渠道版本

同一套微信小程序代码根据需求要打包成两款小程序,主要逻辑页面一致,主题色不一致,部分页面布局不,逻辑不一致。

script命令

先在package.json的script新增命令,根据不同的命令生成对应的环境变量,方便后续判断当前适用的版本。

pages.json配置

查询文档发现page.js可以定制pages.json的返回。所以在根目录新增page.js,
内容如下:

/**
如果要热部署,可以引用uni-pages-hot-modules
**/
try {
    var version_a= require('./config/version_a.js');
    var version_b= require('./config/version_b.js');
    module.exports = (pagesJson, loader) => {
        console.log('------------------当前开发版本为:'+process.env.NODE_CF_ENV)
        if (process.env.NODE_CF_ENV == 'version_a') {
            return version_a
        } else if (process.env.NODE_CF_ENV == 'version_b') {
            return version_b
        }
    }

} catch (e) {
    console.log(e)
}

页面布局、代码逻辑

使用webpack loader在读取时判断读取文件, 比如有两个文件为:home.vue home.version_b.vue,在webpack执行时会根据环境变更输出不同的代码
loader配置:根目录新增 vue.config.js

module.exports = {
    chainWebpack: config => {
        // 访问到vue的规则配置,添加自己的loader相关逻辑,具体api自行参考https://github.com/neutrinojs/webpack-chain
        config.module
            .rule('vue')
            .use('./packages/platformSpecificLoader')
            .loader('./packages/platformSpecificLoader')
            .end();
        //如果不清楚最终的webpack配置,可以输出一下,根据自己的需求,通过api调整最终规则
        // console.log(config.toString());
    },
    configureWebpack: config =>{
        plugins: [
        ]
    }
}

loader代码

const path = require('path')
const utils = require('loader-utils')
const qs = require('querystring')
const loaderUtils = require('loader-utils')
var fs = require("fs")

module.exports = function(source, map) {
    try{

        const loaderContext = this;
        const platformEnv = process.env.NODE_CF_ENV;

        const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)

        const {
            target,
            request,
            minimize,
            sourceMap,
            rootContext,
            resourcePath,
            resourceQuery
        } = loaderContext

        const rawQuery = resourceQuery.slice(1)
        const inheritQuery = `&${rawQuery}`
        const incomingQuery = qs.parse(rawQuery)
        const options = loaderUtils.getOptions(loaderContext) || {}

        const isServer = target === 'node'
        const isShadow = !!options.shadowMode
        const isProduction = options.productionMode || minimize || process.env.NODE_ENV === 'production'
        const filename = path.basename(resourcePath);
        const ext = path.extname(filename);
        const context = rootContext || process.cwd()
        const sourceRoot = path.dirname(path.relative(context, resourcePath))
        
        var platformFileName = filename.replace(ext, `.${platformEnv}${ext}`);
        const fileExists = fs.existsSync(resourcePath.replace(filename,platformFileName)
                    );
        if (fileExists) {
            console.log('读取平台个性文件')
            console.log(platformFileName)
            // 同步读取
            var data = fs.readFileSync(resourcePath.replace(filename,platformFileName));
            source = data;
        }
        this.callback(null, source, map)
    }catch(e){
        console.error(e)
    }
}

尝试过使用babel plugins进行不同版本代码文件的读取,发现输出的文件还是有问题。
TODO:这种情况下热加载有问题,在修改home.version_a.vue时未监听到变更,需要修改home.vue才监听到。

主题色

定义css变量,在vue文件中使用 var(--cf-theme)读取主题色。要实现不同的版本使用不同的主题色,可以使用uni-app的条件编译,具体参照官方文档。如果代码 逻辑差异不大的也可以使用条件编译而不使用上面的后缀名来区分版本

/*  #ifdef  MP-versiona*/
body {
  --cf-theme: #fd4373;
}
/*  #endif  */
/*  #ifdef  MP-versionb*/
body {
  --cf-theme: #85d7cf;
}
/*  #endif  */
posted @ 2021-03-05 17:13  gloxing  阅读(873)  评论(0编辑  收藏  举报