Lerna5 开发脚手架

项目创建

  • npm i lerna
  • lerna init
  • 创建主目录:commands、cli(core)、modles、utils
  • 创建主包:@xx/commands、@xx/core、@xx/modles、@xx/utils
  • 修改主包:各包主入口改为index.js
  • 移动主包 至 主目录
  • 创建README.md
  • 创建 .gitignore
// cli(core)> package.json
// 配置环境变量中的名词,执行命令名称
"bin": {
  "lhtt": "lib/index.js"
},
// .gitignore 文件
.vscode
.idea
node_modules
core/**/node_modules
utils/**/node_modules
models/**/node_modules
commands/**/node_modules
packages/**/node_modules
core/**/package-lock.json
utils/**/package-lock.json
models/**/package-lock.json
commands/**/package-lock.json
packages/**/package-lock.json
lerna-debug.log
// core/cli/lib/index.js
#! /usr/bin/env node
const commands = require('@lhtt/commands')
console.log('Welcome to lhtt!')

发布上线

  • 提交:git add . git commit -m 'init'
  • 登录:git
  • 登录:npm login
  • 仓库:
    • git remote add origin https://gitee.com/dragonliuhu/lhtt.git
    • git remote add origin https://gitee.com/dragonliuhu/lhtt.git
    • git push -u origin "master"
    • git push
  • 发布:lerna publish

链接本地脚手架

  • cd self-cli-dir
  • npm link

链接本地库文件

  • cd self-lib-dir
  • npm link
  • cd self-cli-dir
  • npm link self-lib

取消链接本地库文件

  • cd self-lib-dir
  • npm unlink
  • cd self-cli-dir
  • npm unlink self-lib

1、core 核心模块

1.1、命令执行流程

// core/cli/bin/index.js
#! /usr/bin/env node

const log = require('@lhtt/log')
const importLocal = require('import-local')
if (importLocal(__filename)) {
    log('info', 'lhtt', '正在使用lhtt-cli 本地版本')
} else {
    require('../lib')(process.argv.slice(2))
}

1.1.1、命令准备阶段

1.1.1.1. 检查版本号
// 在cli/lib/index.js
const pkg = require('../package.json')
function checkVersion() {
    log('success', '版本', pkg.version, ' lhtt ')
}
1.1.1.2. 检查node版本
// 在cli/lib/index.js
const CONST = require('./const')
function checkNodeVersion() {
    let c_v = process.version // 当前版本
    let l_v = CONST.LOWER_NODE_VERSION // 最低版本
    if (!semver.gte(c_v, l_v)) {
        throw new Error(colors.red(`${Object.keys(pkg.bin)[0]} 需要安装 v${CONST.LOWER_NODE_VERSION} 以上版本node.`))
    }
}
1.1.1.3. 检查root启动
// 在cli/lib/index.js
function checkRoot() {
    // v1.0.0
    const rootCheck = require('root-check')
    rootCheck()
}
1.1.1.4. 检查用户目录
// 在cli/lib/index.js
function checkUserHome() {
    if (!userHome || !pathExist(userHome)) {
        throw new Error(colors.red('当前登录用户主目录不存在'))
    }
}
1.1.1.5. 检查入参
// 在cli/lib/index.js
function checkParams() {
    let argv = minimist(process.argv.slice(2))
    process.env.LOG_LEVEL = argv.debug ? 'verbose' : 'info'
    log.setLevel(process.env.LOG_LEVEL) // 这里是自己封装的log
}
  • 封装的log
// 基于npmlog封装的log
module.exports = log;
const npmlog = require('npmlog')
/**
 * @param {string} level = // 看上面   // 日志类型
 * @param {string} title = '' // 日志标题
 * @param {string} color = '' // 日志内容
 * @param {string} content = '' // 日志颜色
 */

npmlog.level = process.env.LOG_LEVLE || 'info'

function log(level, title, content, appName='') {
    npmlog.heading = appName
    npmlog.headingStyle = { fg: 'black', bg: 'white'}
    npmlog[level](title, content)
}

log.setLevel = (level) => {
    npmlog.level= level
}
  • 自定义样式
npmlog.addLevel('silly', -Infinity, { inverse: true }, '全部')
npmlog.addLevel('verbose', 1000, { fg: 'cyan', bg: '' }, '测试')
npmlog.addLevel('info', 2000, { fg: 'blue' }, '消息')
npmlog.addLevel('timing', 2500, { fg: 'green', bg: '' }, '运行')
npmlog.addLevel('http', 3000, { fg: 'green', bg: '' }, '请求')
npmlog.addLevel('notice', 3500, { fg: 'cyan', bg: '' }, '通知')
npmlog.addLevel('warn', 4000, { fg: 'yellow', bg: '' }, '警告')
npmlog.addLevel('error', 5000, { fg: 'red', bg: '' }, '错误')
npmlog.addLevel('silent', Infinity)
npmlog.addLevel('success', 2000, { fg: 'green', bg: '' }, '成功')
1.1.1.6. 检查环境变量
const path = require('path')
// 检查环境变量
function checkEnv() {
    const dotenv = require('dotenv')
    const dotenvPath = path.resolve(userHome, '.env')
    // 用户主目录下存在则用
    if (pathExist(dotenvPath)) {
        dotenv.config({
            path: dotenvPath
        })
    }
    createDefaultConfig()
    log('verbose', '脚手架路径', process.env.LHTT_CLI_HOME_PATH)
}
// cli配置路径
function createDefaultConfig() {
    let cliHome = ''
    if (process.env.CLI_HOME) {
        cliHome = path.join(userHome, process.env.CLI_HOME)
    } else {
        cliHome = path.join(userHome, CONST.DEFAULT_CLI_HOME)
    }
    process.env.LHTT_CLI_HOME_PATH = cliHome
}
1.1.1.7. 检查是否最新版本
async function checkUpdate() {
    const version = pkg.version
    const npmName = pkg.name
    const axios = require('axios')
    const urlJoin = require('url-join')
    const argv = minimist(process.argv.slice(2))
    const registryUrl = argv.taobaoNpm ? 'https://registry.npm.taobao.org' : 'https://registry.npmjs.org' 
    const npmInfoUrl = urlJoin(registryUrl, npmName)
    await axios.get(npmInfoUrl).then(res => {
        // 如果成功执行下面,则比较,否则不用比较
        try {
            if (Object.keys(res.data.versions).length > 1) {
                // 满足条件的不版本号
                const satisfiesVersion = Object.keys(res.data.versions).filter(v => semver.gt(v, version)).sort((a, b) => semver.gt(b, a))
                if (satisfiesVersion.length > 0) {
                    log('warn', '更新提示', colors.yellow(`当前版本:v${version},最新版本:v${satisfiesVersion.reverse()[0]}`))
                }
            } else {
                // 抛出异常,线上找不到发布过的脚手架
                // throw new Error('')
            }
        } catch (e) {
            log('warn', '', '线上版本不存在!')
        }
    }).catch(err => {
        log('error', '', '检查版本不成功!')
    })
}

1.1.2、命令注册阶段

1.1.2.1. 注册init
1.1.2.2. 注册publish
1.1.2.3. 注册clean
1.1.2.4. 支持debug

1.1.3、命令执行阶段

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容