# 【方案】-基于tina + gulp4 + webpack的小程序构建方案

# 前言

随着业务越来越庞大, 往往会从一个负责主要业务的小程序中分离出另外多个小程序, 他们拥有很多共有的页面和方法,但是又有自己独特的页面, 如果按照多开小程序项目, 通过共有页面的迁移来实现维护起来太过麻烦, 相当于维护了几份一致的代码。由于项目的小程序是基于 tina 进行开发的, 所以我们采用了 tina + gulp4 + webpack 来实现一套构建方案来解决这个问题。

# 关于tina

tina官网

总结来说, tina是一款可以让我们使用vue语法开发小程序的框架, 但是它不同于taro、mpvue这类型的框架, taro、mpvue这些框架从上层react、vue语法的代码转换成下层小程序语法的代码的过程中经过了非常多处理, 太重了, 如果我们需要对框架进行一些包装等太过于麻烦。而tina的源码非常简单, 对于我们业务来说非常的可控,这也是为什么最终选型tina的原因了。

# tina的基本打包流程

使用脚手架初始化项目




 


npm i -g sao
sao mina my-app
cd my-app
npm i --save @tinajs/tina
npm start

我们来看下生成的项目结构

An image

我们可以发现项目src当中存在我们小程序的主要内容, 如pages、components、app.mina等, 其外还有一些webpack等常规配置。然后我们执行以下 npm start 看下会打包出来什么

An image

打包之后会生成一个dist目录, 这也是tina内置的webpack经过打包构建之后生成的小程序源码。

# 方案

了解了tina大致的打包思路之后, 我们发现可以在webpack打包之前做一些事情, 然后再调用tina内置的webpack打包是可以实现多个小程序共存于一个项目, 通过不同的命令打出不同的小程序包, 大致思路如下

An image

这样的话我们需要对项目的结构进行改造, 让项目支持多个小程序

An image

  • pages-apages-bpages-common 三个目录,分别对应着小程序a的界面文件、小程序b的界面文件、a和b两个小程序共有的页面文件。

  • app-a.minaapp-b.mina分别是小程序a和b的入口文件

  • project.config.a.jsonproject.config.b.json 分别是小程序a和小程序b的配置文件

其实核心逻辑就是将原有的只能支持一套小程序代码的目录结构, 修改成支持多套代码的目录结构, 接下来我们看下package.json 中的命令配置




 


    "cleancache": "rm -rf node_modules/.cache",
    "dev:a": "npm run cleancache && gulp dev --app_type a",
    "dev:b": "npm run cleancache && gulp dev --app_type b",
    "build:a": "npm run cleancache && gulp build --app_type a",
    "build:b": "npm run cleancache && gulp build --app_type b"

在原有的配置上我们新增了一些命令,如清除缓存, 通过 dev:a 构建小程序a的dist包等

我们先把引入gulp 之后tina的打包逻辑跑通(gulpfile.js)

An image

我们可以看到, 当我们执行"dev:a": "npm run cleancache && gulp dev --app_type a"的时候, 我们会得到一个appType, 也就是当前执行的小程序标识, 然后执行tina内置webpack进行打包

然后现在我们需要加上一些我们的逻辑了

An image

  • 根据appType的不同, 定义了不同的路径, 如生成temp包的路径、生成dist包的路径、打包的入口等等

  • 重写tina内置webpack配置的contextentry, 因为我们不在希望webpack作用于src目录和输出dist目录, 以小程序a为例子, 我们希望webpack作用于temp-a 目录和输出dist-a目录

  • delDist 删除对应小程序的dist包

  • delTemp 删除对应小程序的temp包

  • copyConfig 复制当前小程序的project.config.js, 写入到temp文件夹里面

  • copySource 将src下面的全部文件除了pages文件以外全部拷贝到temp目录下

  • copyPages 拿到pages-common 以及 对应的小程序pages包,打包到temp文件夹的pages中

  • copyApp 拿到当前小程序对应的入口文件, 如app-a.mina, 将其改名为app.mina, 然后复制到temp

  • 通过glup串行或者并行的执行, 最终生成小程序对应的temp-x包,然后通过webpack打包出dist-x

An image

# 总结

其实这个方案有点类似于中间件, 在webpack执行之前用gulp搞一点事情, 然后达到我们所期望的效果, 但是还存在一些性能优化的问题需要解决, 如项目庞大之后构建速度变慢等等。