taro 一套代码编译多套微信小程序

360 阅读2分钟

@tarojs/cli@2.2.17 一套代码编译多套微信小程序(多品牌)

关于taro@2升级taro@3,可以用官网推荐的taro2-to-3,然后有一些api也需要调整的,如首页引入的index需移除,页面配置使用动态变量的话直接import引入,组件或页面使用了基础组件的都需在头部引入 等。

脚本

package.jsonscript中添加打包脚本:

"build:weapp:xxx": "taro build --type weapp --platform xxx",
"dev:weapp:xxx": "npm run build:weapp:xxx --watch",

其中xxx是品牌标识,而--platform xxx则指定当前打包的是哪个品牌; 后面在vscode左下角运行对应脚本即可,或者终端运行npm run build:weapp:xxx

配置各品牌信息

在项目根目录config新建platform.js,其实文件叫啥,自己定义;

// 借助命令行解析工具`minimist`:(自己手写也可,直接操作全局变量`process.argv`)
const minimist = require('minimist')
const cmdOptions = minimist(process.argv.splice(2)) // cmdOptions: { _: [], type: 'weapp', platform: 'xxx' }

// 各品牌信息 - 配置例子,具体得看自己怎么用
const PLATFORM_INFO = [
   {
      label: '',                // 简称
      key: 'xxx',               // 平台标识
      theme_color: '',          // 主题色
      app_name: '',             // 小程序名称
      app_id: '',               // 小程序id
      api_host: '',             // 小程序api_host
      output_root: 'dist_xxx',  // 打包目录名称
   },
   ...
]

const CUR_PLATFORM = PLATFORM_INFO.find(i => i.key === cmdOptions.platform) || PLATFORM_INFO[0]

module.exports = {
   CUR_PLATFORM,
}

编写编译插件

同样在config目录下新建plugins目录,进入plugins添加build.js

const path = require('path')
const chalk = require('chalk') // 终端打印插件

module.exports = (ctx, pluginOptions = {}) => {
   const { CUR_PLATFORM = {} } = pluginOptions
   const { app_name, key: app_key } = CUR_PLATFORM

   // 开始编译
   ctx.onBuildStart(() => {
      console.log(chalk.green(`\n开始编译:${app_name} ${app_key}\n`))
   })

   // 编译成功
   ctx.onBuildFinish(() => {
      const NODE_ENV = process.env.NODE_ENV
      if (NODE_ENV === 'production') {
         console.log(chalk.bgGreen(' 编译成功 '), chalk.green(`${app_name} ${app_key}\n`))
      } else if (NODE_ENV === 'development') {
         console.log(chalk.gray(`调试中:${app_name} ${app_key}`))
      }
   })

   // 修改配置文件
   // taro@3已弃用这个钩子,改为modifyBuildAssets即可
   ctx.modifyBuildTempFileContent(({ tempFiles }) => {
      const { fs } = ctx.helper
      const { appPath } = ctx.paths
      const projectConfigName = 'project.config.json'

      let distProjectConfig = fs.readJSONSync(
         path.join(appPath, projectConfigName)
      )
      Object.assign(distProjectConfig, pluginOptions.newProjectConfig)
      ctx.writeFileToDist({
         filePath: projectConfigName,
         content: JSON.stringify(distProjectConfig, null, 2),
      })
   })
}

添加环境变量及编译插件

config/index.js添加环境变量及编译插件,注意省略号...是省略的官方demo代码,只留关键逻辑;

const path = require('path')
const { CUR_PLATFORM } = require('./platform.js')

const outputRoot = CUR_PLATFORM.output_root || 'dist'
const pluginOptions = {
   CUR_PLATFORM,
   newProjectConfig: {
      projectname: CUR_PLATFORM.app_name,
      appid: CUR_PLATFORM.app_id,
   },
}

const config = {
   ...
   outputRoot,
   plugins: [
      ...
      [path.resolve(__dirname, '.', 'plugins/build'), pluginOptions],
   ],
   mini: {
      // less 直接使用变量:@THEME_COLOR
      lessLoaderOption: {
         // taro@3的话换成additionalData
         prependData: [
            `@THEME_COLOR: ${CUR_PLATFORM.theme_color}`,
            `@PLATFORM_KEY: '${CUR_PLATFORM.key}'`,
            '',
         ].join(';'),
      },
      ...
   },
   ...
}

// 添加环境变量,jsx代码里使用:process.env.PLATFORM_THEME_COLOR
// taro@3的话需生成数组放到上面config的配置defineConstants
// 例如:defineConstants: ["process.env.THEME_COLOR": JSON.stringify(CUR_PLATFORM['theme_color'])]
let customEnv = Object.keys(CUR_PLATFORM).reduce((obj, cur) => {
   /**
   * PLATFORM_LABEL: ''
   * PLATFORM_KEY: 'xxx'
   * PLATFORM_THEME_COLOR: ''
   * ...
   */
   let k = `platform_${cur}`
   obj[k.toUpperCase()] = CUR_PLATFORM[cur]
   return obj
}, {})
Object.assign(config, { env: customEnv })

module.exports = function(merge) {
   ...
}

完!如有直播组件的还需特别处理!