找回密码
 立即注册
首页 业界区 业界 管理100个小程序-很难吗

管理100个小程序-很难吗

荦绅诵 2025-6-5 10:08:16
20公里的徒步-真难

群里的伙伴发起了一场天目山20公里徒步的活动,想着14公里都轻松拿捏了,思考了30秒后,就借着春风带着老婆孩子就出发了。一开始溪流清澈见底,小桥流水没有人家;青山郁郁葱葱,枯藤老树没有乌鸦,微风习习,鸟语花香,好不惬意。大有我看青山多妩媚,料青山见我应如是的舒坦,但是,但是没多一会儿画风突变了,爬过一座山还有数不尽的山,关键还一山更比一山高。响午温度升高,加之水资源极度匮乏(因为没有人家,划重点: 徒步一定要多带水),小宝先哭为敬了。好在睡意过去后,又坚强的跑了起来,一直用他的格言激励自己:放弃很多简单,坚持很难,我要坚持。大宝一直在在前面跟着大队伍,想想也是克服了极大的困难,他一直在山顶殷切的期盼着我们,当我们出现视野里时,又高兴的喊着爸爸,妈妈,小宝加油。或许大宝还是蛮优秀的,只是有时对大宝可能过于严厉了些。最后,大家都是笑着走过了最难的路。
1.jpeg

走到16公里的地方,天已经黑了,已经到大路了,是不是20公里也不重要了,大家开心的找了家饭店,酣畅淋漓的吃喝了一顿,途中的跌倒与艰难全都成了豪爽的谈资,第二天大家都还可以自豪的说全身酸痛不已。
2.jpeg

流量来了-心动了

领略了天目山的秀丽风景,回归正题。书接上文,之前捣鼓了一个小程序,没有想到日活居然过1000了,日新增200+,活跃用户次日留存超40%...
3.png

看着这些数据,陷入了沉思,思绪竟然来到了明朝末年(估计最近读《明朝那些事儿》魔怔了吧),农民起义纷争的年代,自己化身高迎祥、李自成、张献忠,手握数万雄兵,但不知所措...思绪一阵乱飞后得到这样一个结论:一个小程序1000,100个小程序就是10万(10万日活广告费真是不得了)-  构建小程序矩阵,构建100个程序,小程序就是雄兵,去攻城略地。
这事儿只有开头简单

有了目标,一口气又注册了5个小程序,备案,各种配置,上传,提交审核,发布...一套动作下来,虽是幸苦,总算是5个小程序都上架了,但是心中总有点不得劲儿的感觉,又说不出是哪里出了问题。还没等回过劲儿,发现程序有bug, 又吭哧吭哧一个个修改,上传,提交审核,发布...这会儿明白问题在哪里了:机械重复。光明白还没用,因为又有bug了,又是全套流程要做完。更多严重的问题是:这个过程又中注册了5个新小程序...应了那句老话:万事开头难,开头后更难。看着10个小程序要机械的重复发布,我没有崩溃,也没有去重复了,去捣鼓自动化了,解放双手才是正确的路。虽然只是解决了代码上传的问题,已是一个巨大的进步。
提前在 key目录下添加小程序代码上传密钥文件格式 private.wx0d8d56e152eb16xx.key
[code]const fileExists = require('file-exists');const del = require('del');const child_process = require('child_process');const ci = require('miniprogram-ci');const gulp = require('gulp');const less = require('gulp-less');const uglify = require('gulp-uglify');const cleanCSS = require('gulp-clean-css');const rename = require('gulp-rename');const gulpif = require('gulp-if');const replace = require('gulp-replace');const alias = require('gulp-path-alias');const autoprefixer = require('gulp-autoprefixer');const pkg = require('./package.json');let projectConfig = require('./project.config.json');const buildPath = path.join(__dirname, 'dist/');const argv = require('minimist')(process.argv.slice(1));const appId = argv["appId"];if (appId){  console.log('set appId  = ',appId);  projectConfig['appid'] = appId;}const env = process.env.NODE_ENVconsole.log("evn=", env)const isPro = env === 'production';console.log("isPro=", isPro)const branchName = child_process.execSync('git symbolic-ref --short HEAD', {  encoding: 'utf8',});const paths = {  styles: {    src: ['src/**/*.less'],    dest: buildPath,  },  images: {    src: 'src/images/**/*.{png,jpg,jpeg,svg,gif}',    dest: buildPath,  },  scripts: {    src: 'src/**/*.js',    dest: buildPath,  },  copy: {    src: [      'src/**',      '!src/**/*.less',      '!src/**/*.js',      'package.json',    ],    dest: buildPath,  },};// 删除构建function clean() {  return del([buildPath]);}function log() {  const data = Array.prototype.slice.call(arguments);  console.log(data);}// 任务处理函数function styles() {  return gulp    .src(paths.styles.src, { base: 'src' })    .pipe(      alias({        paths: {          '@': path.resolve(__dirname, './src/'),        },      })    )    .pipe(less())    .pipe(autoprefixer())    .pipe(gulpif(isPro, cleanCSS()))    .pipe(rename((path) => (path.extname = '.wxss')))    .pipe(gulp.dest(paths.styles.dest));}function scripts() {  return (    gulp      .src(paths.scripts.src, { base: 'src' })      .pipe(        alias({          paths: {            '@': path.resolve(__dirname, './src/'), // src 目录          },        })      )      // .pipe(babel({ presets: ['@babel/env'], 'plugins': [] }))      .pipe(replace('%ENV%', process.env.NODE_ENV)) // 环境变量静态替换      .pipe(replace('%VERSION%', pkg.version))      .pipe(gulpif(isPro, uglify()))      .pipe(gulp.dest(paths.scripts.dest))  );}// 不需要处理的文件直接复制过去function copy() {  return gulp    .src(paths.copy.src)    .pipe(gulp.dest(paths.copy.dest));}function watchFiles() {  const w1 = gulp.watch(paths.styles.src, styles).on('unlink', function (file) {    log(file + ' is deleted');    const filePath = file.replace(/src\\/, 'dist\\');    del([filePath]);  });  const w2 = gulp    .watch(paths.scripts.src, scripts)    .on('unlink', function (file) {      log(file + ' is deleted');      const filePath = file.replace(/src\\/, 'dist\\');      del([filePath]);    });  const w3 = gulp.watch(paths.copy.src, copy).on('unlink', function (file) {    log(file + ' is deleted');    const filePath = file.replace(/src\\/, 'dist\\');    del([filePath]);  });  return Promise.all([w1, w2, w3]);}/** * 小程序ci相关函数 */let project = {};const keyFile = fileExists.sync(`./key/private.${appId}.key`);if (keyFile) {  project = new ci.Project({    appid: appId,    type: 'miniProgram',    projectPath: './dist',    privateKeyPath: `./key/private.${appId}.key`,  });}async function npmBuild() {  await ci.packNpmManually({    packageJsonPath: './package.json',    miniprogramNpmDistDir: './src/',  });}const envLabels = {  'production': '正式环境',  'development': '测试环境',  'pre': '预发环境',};// 机器人代号,有效范围[1-30]const robotMap = {  'development': 1,  'production': 2,  'pre': 3,}async function mpUpload() {  log('mpUpload appid',appId);   if (!appId) {     console.log('\x1b[35m%s\x1b[0m', `════════════════════════════════════════════════════════════════════════⚡【${envLabels[env]}】小程序打包失败,请先执行 export APPID=你的appid 命令,设置appid════════════════════════════════════════════════════════════════════════  `);    return false;  }  projectConfig['appid'] = appId;  log('projectConfig appid',projectConfig.appid);  const uploadResult = await ci.upload({    project,    version: pkg.version,    desc: `【${envLabels[env]}】${pkg.description}`,    setting: {      es7: true,      es6: true,      minifyJS: true,      minifyWXML: true,      minifyWXSS: true,      minify: true,      autoPrefixWXSS: true,    },    robot: robotMap[env],    onProgressUpdate: console.log,  });  console.log('[uploadResult:]', uploadResult);  console.log('\x1b[35m%s\x1b[0m', `════════════════════════════════════════════════════════════════════════
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册