面向uni-app微信小程序的优化和填坑(持续更新)

5,642 阅读2分钟

前言

大家好,我是啊肥,事情是这样的,在开发小程序中遇到了很多问题,虽然对日常开发没有过大的影响,但是遇到问题还是希望能够自我解决,这是一个不错的学习机会,于是就有了这篇文章,关键用于记录自己遇到的问题(我怕我忘了)

小程序使用uni-app进行开发

第一个问题:更换环境的坑

咋肥事

uni-app写微信小程序中多数两条默认命令

"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch",
"build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",

我们也会通过NODE_ENV去判断是否development or production,使用贵公司的测试域名或者生产域名,曾经我遇到了一个情况,想要在dev的时候使用生产域名或者在build的时候使用测试域名,为什么会这样呢,有时候发布到体验版给测试同学测试需要使用测试域名,但是发版需要build。这时候有个方法就是手动注释切换,但是这似乎不够智能。

怎么做

于是我想到了一个办法,就是增加两条命令,dev时使用NODE_ENV=production,build时使用NODE_ENV=development。

"dev-pro": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize",
"build-dev": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build",

跑起来.........

出了个问题,但我dev-pro的时候,执行了production环境,运行的项目跑到dist/build/mp-weixin,build-dev的时候,项目跑到了dist/dev/mp-weixin,这样就乱了,我们当然不希望打包的文件跑了,原来uni-app根据这个去判断了,意味着我们不能用NODE_ENV去判断了。

只能从别的地方想办法,不过既然存在NODE_ENV,那是不是可以自己定义变量,于是我在命令储定义了API_ENV,使用这个去判断环境,但是这时候发现config捕捉不到这个,但是却能捕捉到NODE_ENV,证明webpack做了define处理,那么我们也要处理一下

找到vue.config.js

const path = require('path');
const webpack = require('webpack');
const vars = path.resolve(__dirname, 'src/style/variable.less');
const { API_ENV } = process.env;

module.exports = {
  css: {
    loaderOptions: {
      less: {
        javascriptEnabled: true,
        globalVars: {
          hack: `true; @import "${vars}"`,
        },
      },
    },
  },
  chainWebpack: config => {
    config.plugin('define').tap(args => {
      args[0]['process.env'].API_ENV = JSON.stringify(API_ENV);
      return args;
    });
  },
};

添加chainWebpack配置,把API_ENV暴露出来,这样就可以获取了,然后可以在自己的config文件里判断环境也不会影响打包了,多加几个命令就好,换着用

"dev": "cross-env NODE_ENV=development API_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize",
"dev-pro": "cross-env NODE_ENV=development API_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize",
"build-dev": "cross-env NODE_ENV=production API_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
"build": "cross-env NODE_ENV=production API_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",

第二个问题:打包代码上传的优化

咋肥事

众所周知,小程序上传代码以及提升需要在开发中工具点击上传或者使用CI,或许可以参考我写的文章,小程序CI打包。还有一种情况是使用多端框架,uni-app或者taro,这时候上传代码需要进行打包。那么问题来了,uni-app打包后会生成dist/build/mp-weixin文件夹,如何进行上传呢,会使用开发者工具打开此并运行,然后按照正常流程上传代码。说到这里,会存在一个问题,同学们在开发的时候也会开着一个开发者工具,打开的文件是dist/dev/mp-weixin,相信有不少同学不愿意关掉这个,毕竟黑可以继续开发,更重要的是公司的电脑很卡吧😁,这时候我就想着怎么不打开多一个工具去上传

怎么做

根据上文,我的解决想法是想用一个工具去完成所有事情。我思考了一下发现代码上传的是dist/build/mp-weixin这个文件夹,而跑代码热更新一般用的是dev的命令,工具里跑的是dist/dev/mp-weixin这个文件夹,所以我们build的时候如果可以把build成功的mp-weixin文件夹复制到dev下的mp-weixin下,这样就可以解决了打开多个工具了,打包完甚至可以直接上传代码

这就可以写一个简单的脚本了,目的是把一个文件夹复制到另一个文件夹,很简单,就不需要多讲啦

const fs = require('fs');
const { stat } = fs;

const copy = (src, dst) => {
  // 读取目录
  fs.readdir(src, (err, paths) => {
    console.log(paths);
    if (err) {
      throw err;
    }
    paths.forEach(path => {
      // eslint-disable-next-line no-underscore-dangle
      const _src = `${src}/${path}`;
      // eslint-disable-next-line no-underscore-dangle
      const _dst = `${dst}/${path}`;
      let readable;
      let writable;
      stat(_src, (err, st) => {
        if (err) {
          throw err;
        }

        if (st.isFile()) {
          readable = fs.createReadStream(_src); // 创建读取流
          writable = fs.createWriteStream(_dst); // 创建写入流
          readable.pipe(writable);
        } else if (st.isDirectory()) {
          exists(_src, _dst, copy);
        }
      });
    });
  });
};

const exists = (src, dst, callback) => {
  // 测试某个路径下文件是否存在
  fs.exists(dst, exists => {
    if (exists) {
      // 不存在
      callback(src, dst);
    } else {
      // 存在
      fs.mkdir(dst, () => {
        // 创建目录
        callback(src, dst);
      });
    }
  });
};

exists('./dist/build/mp-weixin', './dist/dev/mp-weixin', copy);

接下来把更改以下命令,build成功跑脚本就好拉

"build-dev": "cross-env NODE_ENV=production API_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build && node buildScript.js",
"build": "cross-env NODE_ENV=production API_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build && node buildScript.js",