npm package: @seer-bigdata/taro-plugin-mutli-app
Description: taro插件-一套代码生成多产物小程序
Latest version: 0.0.2

# @seer-bigdata/taro-plugin-mutli-app

> 详情说明：https://seerbigdata.feishu.cn/wiki/IHHwwgeCbi1njUkyECocvfjVnss

taro插件-一套代码生成多个小程序产物

:::warning
当前插件只支持 taro webpack 的构建方式，vite 构建暂未支持
:::

通过 `process.env.TARO_APP_NAME` 环境变量来区分不同的APP ，实现差异构建

## 基本使用

### 1. 接入插件

```ts title="config/index.ts"
import { handleAppNameEnv } from '@seer-bigdata/taro-plugin-mutli-app';

// 前置调用，确保环境变量信息符合预期
handleAppNameEnv();

export default defineConfig({
  // ... 其他配置保持不变
  plugins: [
    '@seer-bigdata/taro-plugin-mutli-app',
    {
      dirReplaceList: [],
    },
  ],
  // 修改 outputRoot 为 `dist/{TARO_APP_NAME}`，确保多个app产物的构建结果分别在不同目录下
  outputRoot: `dist/${process.env.TARO_APP_NAME || 'default'}`,
});
```

### 2. 命令调用方法

指定环境变量`TARO_APP_NAME` 构建

```bash
TARO_APP_NAME=appA taro build --type weapp --watch
```

## 环境变量差异配置

通过 `.env.{APP_NAME}` 文件定义不同APP的环境变量差异（小程序ID `TARO_APP_ID` 必须包含在内）

- 支持 `.env.{APP_NAME}.development` 配置指定开发环境的差异
- 内部会默认合并 `.env` 文件的内容

## 支持的定制化处理方式

### 1. 文件内定制处理

- 基于 `ifelse` 语句实现文件内定制化处理，可以在代码中基于 `process.env.TARO_APP_NAME` 来定制化处理

  ```ts title="index.tsx"
  if (process.env.TARO_APP_NAME === 'appA') {
    // appA的定制处理逻辑
  } else if (process.env.TARO_APP_NAME === 'appB') {
    // appB的定制处理逻辑
  } else {
    // 如appC、appD 的处理逻辑
    // 默认处理逻辑
  }
  ```

### 2. 通过文件名定制处理

可以新增定制的文件或目录（如 `index.{TARO_APP_NAME}.tsx`），给特定的App使用

:::tip
这个方法也适用于 **页面的入口文件**，用于修改 `index.config.ts` 或 `index.tsx` 文件

如只有`index.config.ts`文件不一致时，可添加 `index.config.{TARO_APP_NAME}.ts` 文件

但如果`index.tsx` 也定制化处理，**必须新增 `index.{TARO_APP_NAME}.config.tsx` 文件**，否则`index.{TARO_APP_NAME}.tsx` 无法正确读取 `index.config.ts` 的配置
:::

**当前的目录结构为**

```
compoments
    scrollView
        index.tsx
        index.appA.tsx
assets
    images
        bg-img.png
        bg-img.appA.png
        bg-img.appB.png
```

**当前的源码使用**

```ts title="源码" {2-3}
// 源码
import ScrollView from '@/compoments/scrollView';
import bgImg from '@/assets/images/bg-img.png';
import './index.less';
```

**各APP的构建结果**

1. appA 的构建结果

```
# 存在 index.{TARO_APP_NAME}.tsx 格式的文件，则 @/compoments/scrollView 被解析为 compoments/scrollView/index.appA.tsx
ScrollView -> compoments/scrollView/index.appA.tsx
bgImg  -> assets/images/bg-img.appA.png
```

2. appB 的构建结果

```
# 不存在 index.{TARO_APP_NAME}.tsx 格式的文件，则 @/compoments/scrollView 被解析为 compoments/scrollView/index.tsx
ScrollView -> compoments/scrollView/index.tsx
# 存在 xx.{TARO_APP_NAME}.xx 格式的文件，则 @/assets/images/bg-img 被解析为 assets/images/bg-img.appB.png
bgImg  -> assets/images/bg-img.appB.png
```

3. appC 的构建结果

```
ScrollView -> compoments/scrollView/index.tsx
bgImg  -> assets/images/bg-img.png
```

### 3. 目录定制处理

如存在很多内容都需要定制，但不想给文件加appName 后缀的话，可直接新建一个定制目录，并给插件传入对应的定制目录参数dirReplaceList，实现在单个目录中定制处理

```
如配置了 dirReplaceList = ["./src/compoments"]

/** 当前的目录结构
compoments
    compomentsA
    compomentsB
    compomentsC
compoments-appA
    compomentsC
compoments-appB
    compomentsB
    compomentC

/** appA 的构建结果**/
compomentsA -> compoments/compomentsA
compomentsB -> compoments/compomentsB
compomentsC -> compoments-appA/compomentC

/** appB 的构建结果**/
compomentsA -> compoments/compomentsA
compomentsB -> compoments-appB/compomentsB
compomentsC -> compoments-appB/compomentsC

/** appC 的构建结果**/
compomentsA -> compoments/compomentsA
compomentsB -> compoments/compomentsB
compomentsC -> compoments/compomentsC
```

## 额外说明

### 文件加载优先级说明

目录定制处理的优先级 > 文件定制处理！！

`common-appA/index.appA.ts` > `common-appA/index.ts` > `common/index.appA.ts` > `common/index.ts`

### env环境变量加载优先级说明

:::warning
请确保 `handleAppNameEnv()` 函数已经被前置调用
:::

以下的顺序都是逐一覆盖模式

1. `mode===production` 情况

   > .local 是因为Taro 本身会读取local （合理性存疑）

   `.env.appA.production` > `env.appA` > `.env.production.local` > `.env.local` > `.env.production` > `.env`

2. `mode!==production` 情况
   `.env.appA.{mode}.local` > `.env.appA.local` > `.env.{mode}.local` > `.env.local` > `.env.{mode}` > `.env`

### log 信息查看

插件会将相关的替换文件逻辑写到本地文件，可基于输出的文件路径，校验是否正确