讓你的小程序支持多環境打包

開發小程序時,最麻煩的事情莫過於在上線前須要反覆切換測試和正式環境接口地址。javascript

本文介紹一種小程序工程化改造的思路,基於這個咱們可以實現小程序自動根據多環境打包。css

參考項目

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

準備工做

閱讀本文,你須要有對如下內容的基本認知:git

  • gulp
  • 環境變量

工程化改造

原生的小程序只有一個簡單的啓動腳手架,不支持less、sass等樣式預處理器,對npm的支持也不是太好,咱們本身作一個簡單的構建工具,來加強小程序的功能。本節起一個拋磚引玉的做用,基於這個思路,能夠改造出更多更強大的功能。github

目錄結構

  • dist 輸出/發佈目錄,在微信開發者工具中打開這個目錄npm

    • project.config.json 配置文件,這個文件與src中的配置無關
  • srcjson

    • miniprogramgulp

      • assets 靜態資源目錄,放圖片之類的東西
      • components 組件目錄
      • pages 小程序頁面目錄
      • app.js 小程序入口
      • app.json 小程序全局配置
      • app.less
      • sitemap.json
      • project.config.json 配置文件樣板,這個文件不會被編譯到dist中

安裝gulp

本文寫做時,gulp的版本是v4,api與以前的版本有一些變化。小程序

建立一個空目錄後,先安裝依賴: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試試吧!

相關文章
相關標籤/搜索