让你的小程序支持多环境打包

41次阅读

共计 3951 个字符,预计需要花费 10 分钟才能阅读完成。

开发小程序时,最麻烦的事情莫过于在上线前需要反复切换测试和正式环境接口地址。

本文介绍一种小程序工程化改造的思路,基于这个我们能够实现小程序自动根据多环境打包。

参考项目

https://github.com/mecoepcoo/miniprogram-boilerplate

准备工作

阅读本文,你需要有对以下内容的基本认知:

  • gulp
  • 环境变量

工程化改造

原生的小程序只有一个简单的启动脚手架,不支持 less、sass 等样式预处理器,对 npm 的支持也不是太好,我们自己做一个简单的构建工具,来增强小程序的功能。本节起一个抛砖引玉的作用,基于这个思路,可以改造出更多更强大的功能。

目录结构

  • dist 输出 / 发布目录,在微信开发者工具中打开这个目录

    • project.config.json 配置文件,这个文件与 src 中的配置无关
  • src

    • miniprogram

      • assets 静态资源目录,放图片之类的东西
      • components 组件目录
      • pages 小程序页面目录
      • app.js 小程序入口
      • app.json 小程序全局配置
      • app.less
      • sitemap.json
      • project.config.json 配置文件样板,这个文件不会被编译到 dist 中

安装 gulp

本文写作时,gulp 的版本是v4,api 与之前的版本有一些变化。

创建一个空目录后,先安装依赖:

$ npm init
$ npm i -D gulp gulp-plumber gulp-rename del

在根目录新建 gulpfile.js 文件,引入依赖:

const gulp = require('gulp');
const plumber = require('gulp-plumber'); // 发生错误时阻止 gulp 退出并输出日志
const rename = require('gulp-rename'); // 输出时重命名文件
const del = require('del');

支持 less

用 less 等预处理器书写样式,可能会更方便,安装依赖:

$ npm i -D gulp-less gulp-cssnano

假设我们的源码放在 /src/miniprogram 目录下,输出到 /dist 目录下。

现在让 gulp 支持 less 编译:

const less = require('gulp-less'); // 处理 less
const cssnano = require('gulp-cssnano'); // 压缩代码
// 编译样式
gulp.task('build:style', () => {
  return gulp.src([ // 千万不要漏掉 return,否则 gulp 不知道这个任务何时完成
    'src/miniprogram/pages/**/*.less', 
    'src/miniprogram/components/**/*.less',
    'src/miniprogram/spreadpack/**/*.less',
    'src/miniprogram/app.less'
  ], {base: 'src/miniprogram'})
    .pipe(plumber())
    .pipe(less())
    .pipe(
      cssnano({
        zindex: false,
        autoprefixer: false,
        discardComments: {removeAll: true}
      })
    )
    .pipe(
      rename(path => {path.extname = '.wxss'; // 我们用 less 做后缀名,但小程序只支持 wxss,所以需要修改输出的后缀})
    )
    .pipe(gulp.dest('dist')); // 写入到 dist 文件夹中
});

处理脚本、模板和配置文件

本文只做简单的思路介绍,所以我们还是按照原来的方法编写小程序的 js 和模板。

这里只是把 js,wxml 和 json 复制到输出目录:

// 编译示例
gulp.task('build:main', gulp.series('build:style', () => {
  return gulp.src([
    'src/miniprogram/**/*',
    '!src/miniprogram/**/*.less', // 排除 less 后缀文件
    '!src/project.config.json', // 配置文件不写入到 dist 文件夹,开发时需手动拷贝到 dist 文件夹中 !!!
  ], {base: 'src/miniprogram', allowEmpty: true})
    .pipe(plumber())
    .pipe(gulp.dest('dist'));
}));

清理输出目录

在发布前,我们需要删除掉多余的文件,这里新增一个工作流用来清理输出目录:

gulp.task('clean', cb => {
  return del([
    'dist/**/*',
    '!dist/project.config.json'
  ], cb);
});

配置开发环境启动命令和构建命令

最后我们补全功能,首先增加一个开发环境启动配置:

gulp.task('build', gulp.series('build:main'));
// 监听文件(若文件修改则执行相关的任务)
function watch() {let watcher = gulp.watch('src/**', cb => cb());
  watcher.on('all', (event, path, stats) => {console.log('File' + path + 'was' + event + ', running tasks...');
  });
  return watcher;
}

gulp.task('default', gulp.series(watch));

package.json 中增加脚本:

"scripts": {
  "start": "npm run clean && npm run build",
  "dev": "gulp",
  "build": "gulp build",
  "watch": "gulp watch",
  "clean": "gulp clean",
}

现在执行 npm start 或者npm run dev,用小程序开发工具打开 dist 目录,就能看到效果了。

注入环境变量

有了 gulp,一切关于构建的问题都简单了。使用 gulp-preprocess 来支持环境变量。

gulp-preprocess 的用法见官方文档。

安装依赖:

$ npm i -D cross-env gulp-preprocess

修改构建配置

由于操作系统之间设置环境变量命令的差异,引入 cross-env 来解决,先修改package.json

"scripts": {
  "start": "cross-env NODE_ENV=prod npm run clean && npm run build",
  "dev": "cross-env NODE_ENV=dev gulp",
  "build": "cross-env NODE_ENV=prod gulp build",
  "watch": "cross-env NODE_ENV=dev gulp watch",
  "clean": "gulp clean",
}

这里增加了一个名为 NODE_ENV 的环境变量,并设置了 devprod两个值,这样开发时会取 dev 变量,打包发布时会取 prod 变量。

然后增加 gulp 配置:

const preprocess = require('gulp-preprocess'); // 注入环境变量

gulp.task('build:main', gulp.series('build:style', () => {
  return gulp.src([
    'src/miniprogram/**/*',
    '!src/miniprogram/assets/**/*', // 新增配置在这里
    '!src/miniprogram/**/*.less',
    '!src/project.config.json',
  ], {base: 'src/miniprogram', allowEmpty: true})
    .pipe(plumber())
    .pipe(preprocess()) // 新增配置在这里
    .pipe(gulp.dest('dist'));
}));

// 由于 preprocess 这个插件会影响静态资源,所以需要把静态资源的打包拿出去
/* 处理静态资源 */
gulp.task('build:assets', () => {
  return gulp.src(["src/miniprogram/assets/**/*"], {base: 'src/miniprogram', allowEmpty: true})
    .pipe(plumber())
    .pipe(gulp.dest('dist'));
});

// 修改构建配置
gulp.task('build', gulp.parallel('build:main', 'build:assets'));
function watch() {let watcher = gulp.watch('src/**', gulp.parallel('build:main', 'build:assets'), cb => cb());
  watcher.on('all', (event, path, stats) => {console.log('File' + path + 'was' + event + ', running tasks...');
  });
  return watcher;
}

代码示例

用这种方法注入环境变量:

let env = '/* @echo NODE_ENV */';
let apiRoot = '';
switch (env) {
  case 'dev':
    apiRoot = 'http://dev-api.tianzhen.tech';
    break;
  case 'prod':
    apiRoot = 'http://api.tianzhen.tech';
    break;
}

写一个 demo,运行 npm start 试试吧!

正文完
 0