Skip to content

[RFC] app.json 多端差异化配置 #867

Open
@wjq990112

Description

背景

需求 1:已有 target 分端构建

web 和小程序中 app.json 相关的配置存在差异性,比如 tarbbar 或者 title

需求 2:阿里小程序分端构建

阿里小程序 target 均为 miniapp,以业务同时需要构建淘宝小程序、支付宝小程序为例,目前的设计每次构建都只能使用同一份 app.json,但实际上可能存在 tabbar 等配置不同的情况

需求 3:移除 Document 之后自定义脚本插入问题

在移除 document/index.jsx 之后,如果存在 <script> var a = 1 </script> 这种类似需要插入的脚本,现有的 json 文件难以承载

方案

方案一(改进后)

app.json 允许端差异化配置,比如:

{
  "window": {
    "title": "Rax App"
  },
  "miniapp": {
    "window": {
      "title": "Rax MiniApp"
    }
  }
}

用户在根对象下设置基础配置,对应不同端的配置采用深合并的方式实现,例如:

{
  "routes": [
    {
      "path": "/",
      "name": "home",
      "source": "pages/Home/index"
    },
    {
      "path": "/about",
      "name": "about",
      "source": "pages/About/index"
    }
  ],
  "miniapp": {
    "routes": [
      {},
      {
        "source": "page/MiniAppAbout/index"
      }
    ]
  }
}

在构建时生成差异化的 app.json 以实现差异化构建。

优势

  • 现有架构无需过多改动
  • 相关配置依然收敛到 app.json 这个文件中,不会有新增实体的认知

劣势

  • 无法满足需求2、3
  • app.json 可能会变得非常庞大难以维护

方案二(改进后)

通过后缀名区分不同端的 app.json,比如:

app.json:

{
  "window": {
    "title": "Rax App"
  }
}

app.miniapp.json:

{
  "window": {
    "title": "Rax MiniApp"
  }
}

与方案一一致,在 app.json 中仅设置基础配置,在不同端的 app.json 中配置差异化的配置,最终进行深合并,例如:

app.json

{
  "routes": [
    {
      "path": "/",
      "name": "home",
      "source": "pages/Home/index"
    },
    {
      "path": "/about",
      "name": "about",
      "source": "pages/About/index"
    }
  ],
}

app.miniapp.json

{
  "routes": [
    {},
    {
      "source": "page/MiniAppAbout/index"
    }
  ]
}

优势

  • 仍然保留 json 的配置形式,分文件的形式可以让配置信息维护起来更容易
  • 改动量适中

劣势

  • 存在大量冗余配置,差异化配置时需要查看基础配置
  • 无法满足需求2、3
  • 新增实体,有一定的认知成本

方案三

新增 app.config.js 概念,在 node 端执行,传入当前构建的 target,可以使用 process.env 根据启动的环境变量动态获取值,比如:

module.exports = target => {
  return {
    title: target === 'miniapp' && process.env.IS_TAO_BAO ? 'Rax TaoBao MiniApp' : 'Rax App'
  }
}

优势

  • 更加灵活的配置形式
  • 代码更加简洁
  • 能够同时满足已列出的需求

劣势

  • 新增实体,有一定的认知成本
  • 有一定的改造成本

遗留问题

  • 方案一和方案二中,route 里目前的 targets 字段是不是没有意义了?

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions