【造轮子】基于commander打造自己业务的脚手架

190 阅读4分钟

基于commander打造自己业务的脚手架

前言

随着业务的发展,一个公司可能有多个部门使用同一个技术迭代业务,这时候就产生了一个问题,这么多雷同的项目不能总是拷贝,打造符合自己公司的脚手架应运而生。 分享一下我自己写的一个react-native的脚手架.

效果



技术选型

  • 基于commander的命令行框架
  • 基于react-native0.55.4版本,集成了redux、typescript、react-navigation demo
  • 打包脚本
  • 代码规范eslint

架手架入口

#!/usr/bin/env node
import { Command } from 'commander'
import { init } from './command/init'
import { fix } from './command/fix'
import { bundle } from './command/bundle'
import { zipBundle } from './command/zip'
const pkg = require('../package.json')

const program = new Command('srn')
program.version(pkg.version)

program
  .command('init')
  .description('初始化react-native 项目工程')
  .option('-n, --name <name>', '项目名称')
  .action(init)

program
  .command('bundle')
  .description('react-native 打整包')
  .option('-e --entry <entry>', '入口文件')
  .option('-o --outputDir <outputDir>', 'bundle输出目录')
  .option('-p --platform <platform>', '平台(android|ios)')
  .option('-a --assetsDest <assetsDest>', '静态资源输出目录')
  .action(bundle)

program
  .command('zip')
  .description('bundle压缩')
  .option('-n --name <name>', '名称')
  .action(zipBundle)

program
  .command('fix')
  .description('修复react-native运行时问题')
  .option('-q, --question <question>', '需修复的问题')
  .action(fix)

program.parse(process.argv)

react-native项目初始化命令

export const init = async (options: {name: string}) => {
  const { name } = options
  const finalOptions = { ...options }
  if (!name) {
    const { name } = await inquirer.prompt([
      {
        type: 'input',
        name: 'name',
        message: 'project name:',
        validate: (input = '') => input.trim().length > 0
      }
    ])
    finalOptions.name = name
  }
  logger.log(banner)

  const spinner = ora(colors.green(`Setting up new React Native app in ${finalOptions.name}`))
  try {
    spinner.succeed()
    const projectDir = path.join(path.resolve(process.cwd()), finalOptions.name)
    const flag = mkdirSync(projectDir)
    if (!flag) {
      process.exit(1)
    }

    spinner.start('downloading template')
    const templatePath = path.resolve(__dirname, '../../template')
    copyProjectTemplateAndReplace(templatePath, projectDir, finalOptions.name)

    await delay((Math.random() + 0.4) * 10000)
    spinner.succeed(colors.green('download template'))

    spinner.start('creating appJson')
    addAppJson(projectDir, finalOptions.name)
    await delay(Math.random() * 4000)
    spinner.succeed(colors.green('created appJson'))

    spinner.succeed(colors.green(`successful created ${finalOptions.name}`))
  } catch (e) {
    spinner.stop()
  }
}

修复react-native 0.55.4版本运行时问题的命令

enum QuestionEnum {
  q0 = '1、[ios]MacOS 运行报错 Could not find iPhone simulator',
  q1 = '2、[ios]third-part config.h not found; Entry, ":CFBundleIdentifier", Does Not Exist',
  q2 = '3、[ios]遇到 React Native 启动报错的问题 getCurrentAppState:error 和 objectAtIndexedSubscript: 的解决方案',
  q3 = '4、[ios]Xcode12.5/报错:Cannot initialize a parameter of type ‘NSArray<id<RCTBridgeModule>> *',
  q4 = '5、[build] Error fast-image OnProgressEvent',
  q5 = '6、[android] blacklist regex syntax errors'
}

export const fix = async (options: { question: string }) => {
  const { question } = options
  const finalOptions = { ...options }

  if (!question) {
    const { question } = await inquirer.prompt([
      {
        type: 'list',
        name: 'question',
        message: '请选择修复的问题',
        choices: [QuestionEnum.q0, QuestionEnum.q1, QuestionEnum.q2, QuestionEnum.q3, QuestionEnum.q4, QuestionEnum.q5],
        default: 0
      }
    ])
    finalOptions.question = question
  }

  const spinner = ora(colors.green('问题修复中...'))
  spinner.start()

  let success: boolean = false
  switch (finalOptions.question) {
    case QuestionEnum.q0:
      success = fixQ0()
      break
    case QuestionEnum.q1:
      success = await fixQ1()
      break
    case QuestionEnum.q2:
      success = fixQ2()
      break
    case QuestionEnum.q3:
      success = fixQ3()
      break
    case QuestionEnum.q4:
      success = fixQ4()
      break
    case QuestionEnum.q5:
      success = fixQ5()
      break
  }

  if (success) spinner.succeed(colors.green('问题已修复'))
  spinner.stop()
}

总结

  • 可以封装自己的业务,集成基础服务,提升开发效率
  • 部分代码省略,如果需要源码,关注私信留下邮箱

5分钟实现微信小程序海报页

备受青睐

  • 不用安装。微信小程序是一种不需要安装即可使用的应用
  • 跨平台性。一份代码即可多个平台使用
  • 推广容易。用户扫一扫或搜一下即可打开应用

推荐使用

随着业务需求的不多发展,小程序开发必不可少,而经常遇到需要用canvas画海报,如何我们裸用canvas的api去画海报,在可读性、后期维护性方面比较差,给大家推荐一个非常好用画小程序海报的库,让canvas的api下沉下去,开发者不用关心api,专心于业务即可。

案例效果

安装依赖

1、npm i wx-canvas-2d -S

2、微信小程序开发者工具构建一下npm (工具 -> 构建 npm)

画海报

import {
  WxCanvas2d,
  Text,
  Image,
  Debugger
} from 'wx-canvas-2d'

WxCanvas2d.use(Debugger)
    const canvas = new WxCanvas2d()
    canvas.create({
      query: '.poster-canvas', // 必传,canvas元素的查询条件
      rootWidth: 750, // 参考设备宽度 (即开发时UI设计稿的宽度,默认375,可改为750)
      bgColor: '#fff', // 背景色,默认透明
      component: this, // 自定义组件内需要传 this
      radius: 16 // 海报图圆角,如果不需要可不填
    })
    canvas.draw({
      series: [{
          type: Image,
          url: '../../images/bg.png',
          x: 0,
          y: 0,
          width: 600,
          height: 900,
          mode: 'scaleToFill',
          radius: 0,
          zIndex: 0
        },
        {
          type: Text,
          text: '标题最多最长十个字符',
          x: 40,
          y: 120,
          color: '#FFFFFF',
          fontSize: 52,
          fontWeight: 'bold'
        },
        {
          type: Text,
          text: '2022.06.17~2022.08.30',
          x: 120,
          y: 230,
          color: '#FBF1CD',
          fontSize: 32,
          fontWeight: 'bold'
        },
        {
          type: Text,
          text: '南京xxxx孝陵卫店南京xxxx孝陵卫店',
          width: 320,
          x: 50,
          y: 680,
          color: '#222222',
          fontSize: 28,
          lineHeight: 42
        },
        {
          type: Image,
          url: '../../images/sun.png',
          x: 400,
          y: 680,
          width: 160,
          height: 160,
          mode: 'scaleToFill',
          radius: 0,
          zIndex: 1
        },
      ]
    })

总结

  • 提升开发效率,可维护性搞
  • 思想非常值得参考,canvas api封装在库里,开发海报只需要配置,计算坐标、大小、位置即可

结束语

  • 👀 目前专注于前端

  • ⚙️ 在react、react-native开发方面有丰富的经验

  • 🔭 最近在学习安卓,有自己的开源安卓项目,集成react-native热更新功能

  • 我❤️ 思考、学习、编码和健身

  • 如果文章对您有帮助,三连支持一下~O(∩_∩)O谢谢!