前端架构师-week3-脚手架执行准备过程实现

news2025/2/25 5:03:17

目录​​​​​​​​​​​​​​ 

脚手架框架代码拆包 + import-local应用  

检查版本号功能开发(require加载资源类型讲解 + npmlog封装)

最低Node版本检查功能开发

root 账号启动检查和自动降级功能开发

用户主目录检查功能开发

入参检查和 debug 模式开发

环境变量检查功能开发

通用 npm API 模块封装

npm 全局更新功能开发


脚手架框架代码拆包 + import-local应用  

core > cli > bin > index.js中

#! /usr/bin/env node

const importLocal = require('import-local');

if (importLocal(__filename)) {
  require('npmlog').info('cli', '正在使用 imooc-cli 本地版本');
} else {
  require('../lib')(process.argv.slice(2));
}

检查版本号功能开发(require加载资源类型讲解 + npmlog封装)

require加载资源类型讲解:

        支持三种类型:.js / .json / .node

        .js -> module.exports / exports

        .json -> JSON.parse()

        .node -> 是一个c++的插件,通过 process.dlopen 打开

        any -> 通过 js 引擎解析

可以定义一个专门的 log 类,在 utils 中定义一个 log package:

lerna create @imooc-cli-dev/log

调整 .log 目录位置,修改 log/lib/log.js 名字为 index.js(package.json中对应修改)。

lerna add npmlog utils/log/

在 core/cli 模块中调用 log package,在 core/cli/package.json 中注册:

"dependencies": {
    "@imooc-cli-dev/log": "file:../../utils/log",
    "@imooc-cli-dev/init": "file:../../commands/init",
    "import-local": "^3.0.2",
    "npmlog": "^4.1.2"
  },
cd core/cli/
npm link
// log/lib/index.js 中

'use strict';

const log = require('npmlog');

log.level = process.env.LOG_LEVEL ? process.env.LOG_LEVEL : 'info'; // 判断debug模式

log.heading = 'imooc'; // 修改前缀
log.addLevel('success', 2000, { fg: 'green', bold: true }); // 添加自定义命令

module.exports = log;

最低Node版本检查功能开发

        使用的 node api,在低版本的时候是不支持的。要设置一个最低的版本号。

semver库作用:

        用来做各种各样版本号比对的。

//用法

const semver = require('semver')

semver.valid('1.2.3') // '1.2.3'
semver.valid('a.b.c') // null
semver.clean('  =v1.2.3   ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true
semver.minVersion('>=1.0.0') // '1.0.0'
semver.valid(semver.coerce('v2')) // '2.0.0'
semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'

colors库作用:

        Get colors in your node.js console 

var colors = require('colors/safe');
 
console.log(colors.green('hello')); // outputs green text
console.log(colors.red.underline('i like cake and pies')) // outputs red underlined text
console.log(colors.inverse('inverse the color')); // inverses the color
console.log(colors.rainbow('OMG Rainbows!')); // rainbow
console.log(colors.trap('Run the trap')); // Drops the bass

引入和实现代码:

lerna add semver core/cli/
lerna add colors core/cli/
function checkNodeVersion() {
    const currentVersion = process.version;
    const lowestVersion = constant.LOWEST_NODE_VERSION;
    if (!semver.gte(currentVersion, lowestVersion)) {
        throw new Error(colors.red(`imooc-cli 需要安装 v${lowestVersion} 以上版本的 Node.js`))
    }
}

root 账号启动检查和自动降级功能开发

        需要对操作系统比较了解,才能理解。脚手架需要频繁读写文件,root 账号会导致权限频繁报错,需要进行降级处理。

判断 root 环境:

process.getuid && process.getuid() == 0

process.setuid()

process.setgid() //分组id

process.env //环境变量

process //node进程信息

root-check 库作用:

        Try to downgrade the permissions of a process with root privileges and block access if it fails

//用法

import rootCheck from 'root-check';

rootCheck();

引入和实现代码:

lerna add root-check core/cli/

        在 core/cli/ 命令行中 npm link

function checkRoot() {
  const rootCheck = require('root-check');
  rootCheck();
}

用户主目录检查功能开发

user-home库作用:

        跨操作系统获取系统主目录。已弃用。

        Deprecated. Just use import {homedir} from 'os';

//用法

const userHome = require('user-home');

console.log(userHome);
//=> '/Users/sindresorhus'

path-exists库作用:

        判断文件是否存在。 

        原理:fs.accessSync(path);

//用法

// foo.js
import {pathExists} from 'path-exists';

console.log(await pathExists('foo.js'));
//=> true

引入和实现代码:

lerna add user-home core/cli/

lerna add path-exists core/cli/

        在 core/cli/ 命令行中 npm link

function checkUserHome() {
  if (!userHome || !pathExists(userHome)) {
    throw new Error(colors.red('当前登录用户主目录不存在!'));
  }
}

入参检查和 debug 模式开发

入参检查目的:看一下是否进入调试模式。

minimist库作用:

        parse argument options

//用法

var argv = require('minimist')(process.argv.slice(2));
console.log(argv);


$ node example/parse.js -a beep -b boop
{ _: [], a: 'beep', b: 'boop' }


$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
{
	_: ['foo', 'bar', 'baz'],
	x: 3,
	y: 4,
	n: 5,
	a: true,
	b: true,
	c: true,
	beep: 'boop'
}

引入和实现代码: 

        core/cli/ 命令行中执行 npm install -S minimist 

function checkInputArgs() {
    const minimist = require('minimist')
    args = minimist(process.argv.slice(2))
    checkArgs()
}

function checkArgs() {
    if (args.debug) {
        process.env.LOG_LEVEL = 'verbose'
    } else {
        process.env.LOG_LEVEL = 'info'
    }
    log.level = process.env.LOG_LEVEL
}

环境变量检查功能开发

重要意义:可以在操作系统当中配置一些环境变量,将用户名密码等敏感信息保存在用户本地。而不用集成到代码当中,我们需要时就可以实时进行读取。同时我们还可以修改默认的配置信息。

        通过环境变量在全局进行获取,操作系统打开以后,不管哪个软件之中都可以获取的到。共享一份。

dotenv库作用:

        Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env. Storing configuration in the environment separate from code is based on The Twelve-Factor App methodology.

//用法

//Create a .env file in the root of your project:

S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"

//As early as possible in your application, import and configure dotenv:

require('dotenv').config()
console.log(process.env) // remove this after you've confirmed it is working

引入和实现代码:

         core/cli/ 命令行中执行 npm install -S dotenv

const userHome = require('user-home');

function checkEnv() {
  const dotenv = require('dotenv');
  const dotenvPath = path.resolve(userHome, '.env');
  if (pathExists(dotenvPath)) {
    dotenv.config({
      path: dotenvPath,
    });
  }
  createDefaultConfig();
}

function createDefaultConfig() {
  const cliConfig = {
    home: userHome,
  };
  if (process.env.CLI_HOME) {
    cliConfig['cliHome'] = path.join(userHome, process.env.CLI_HOME);
  } else {
    cliConfig['cliHome'] = path.join(userHome, constant.DEFAULT_CLI_HOME);
  }
  process.env.CLI_HOME_PATH = cliConfig.cliHome;
}

//最终缓存路径 /Users/sam/.imooc-cli

通用 npm API 模块封装

url-join库作用: 

        Join all arguments together and normalize the resulting URL.

//用法

import urlJoin from 'url-join';

const fullUrl = urlJoin('http://www.google.com', 'a', '/b/cd', '?foo=123');

console.log(fullUrl);

//Prints:
//'http://www.google.com/a/b/cd?foo=123'

步骤:

        1. 获取当前版本号和模块名

        2. 调用 npm API(https://registry.npmjs.org/模块名称、https://registry.npm.taobao.org/模块名称 ),获取所有版本号

        3. 提取所有版本号,比对哪些版本号是大于当前版本号

        4. 获取最新的版本号,提示用户更新到该版本 

操作:

lerna create get-npm-info ./utils/get-npm-info

        看实际情况调整 get-npm-info package 位置,lib/get-npm-info.js 改为 lib/index.js,package.json 中 main 属性相应修改。

//core/cli 的 package.json 中注册

"dependencies": {
    "@imooc-cli-dev/get-npm-info": "file:../../utils/get-npm-info",
    "colors": "^1.4.0"
}

//core/cli 命令行中执行 npm link
lerna add axios utils/get-npm-info/

lerna add semver utils/get-npm-info/

lerna add url-join utils/get-npm-info/


// utils/get-npm-info/命令行中
npm link

npm 全局更新功能开发

async function checkGlobalUpdate() {
  const currentVersion = pkg.version;
  const npmName = pkg.name;
  const { getNpmSemverVersion } = require('@imooc-cli-dev/get-npm-info');
  const lastVersion = await getNpmSemverVersion(currentVersion, npmName);
  if (lastVersion && semver.gt(lastVersion, currentVersion)) {
    log.warn(colors.yellow(`请手动更新 ${npmName},当前版本:${currentVersion},最新版本:${lastVersion}
                更新命令: npm install -g ${npmName}`));
  }
}
'use strict';

const axios = require('axios');
const urlJoin = require('url-join');
const semver = require('semver');

function getNpmInfo(npmName, registry) {
  if (!npmName) {
    return null;
  }
  const registryUrl = registry || getDefaultRegistry();
  const npmInfoUrl = urlJoin(registryUrl, npmName);
  return axios.get(npmInfoUrl).then(response => {
    if (response.status === 200) {
      return response.data;
    }
    return null;
  }).catch(err => {
    return Promise.reject(err);
  });
}

function getDefaultRegistry(isOriginal = false) {
  return isOriginal ? 'https://registry.npmjs.org' : 'https://registry.npm.taobao.org';
}

async function getNpmVersions(npmName, registry) {
  const data = await getNpmInfo(npmName, registry);
  if (data) {
    return Object.keys(data.versions);
  } else {
    return [];
  }
}

function getSemverVersions(baseVersion, versions) {
  return versions
    .filter(version => semver.satisfies(version, `>${baseVersion}`))
    .sort((a, b) => semver.gt(b, a) ? 1 : -1);
}

async function getNpmSemverVersion(baseVersion, npmName, registry) {
  const versions = await getNpmVersions(npmName, registry);
  const newVersions = getSemverVersions(baseVersion, versions);
  if (newVersions && newVersions.length > 0) {
    return newVersions[0];
  }
  return null;
}

async function getNpmLatestVersion(npmName, registry) {
  let versions = await getNpmVersions(npmName, registry);
  if (versions) {
    return versions.sort((a, b) => semver.gt(b, a))[0];
  }
  return null;
}

module.exports = {
  getNpmInfo,
  getNpmVersions,
  getNpmSemverVersion,
  getDefaultRegistry,
  getNpmLatestVersion,
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/469168.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为OD机试真题(Java),火星文计算(100%通过+复盘思路)

一、题目描述 已知火星人使用的运算符为#、$,其与地球人的等价公式如下: x#y 2*x3*y4 x$y 3*xy2 其中x、y是无符号整数;地球人公式按C语言规则计算;火星人公式中,$的优先级高于#,相同的运算符&#x…

数字船厂信息化整体解决方案(ppt可编辑)

本资料来源公开网络,仅供个人学习,请勿商用,如有侵权请联系删除 数字船厂建设思路 智慧船厂将以信息化为基础、以数据为纽带、以制造为核心、以管理为载体打造新型智慧园区,该智慧园区整合了船厂的安全、环保、能源、安防、应急…

基于 JavaWeb 的用户报名审核平台项目

目录 一、项目的需求: 二、项目的思路流程: 三、项目的框架(基于JavaWeb): 四、项目的详细搭建 1、数据库--建库建表 2、JavaBean编写(以Status.java为例) 3、Dao层(StatusDao…

Linux系统与shell编程第一节课

目录 1.1 Linux发展历史 1.2 什么是linux? 1.3 Linux的发行版 Host-Only(仅主机模式) windows开发 linux服务 区块链, 特点:稳定,安全,可移植性,低资源消耗,开源软…

做工业品行业的财务有多难

财务 做工业品行业的财务需要具备一定的财务和会计知识,以及对行业内经济运作有一定的了解。在处理大量数据和信息方面也需要有较高的能力。此外,工业品行业往往涉及到复杂的生产过程和供应链管理,需要对这些方面有一定的了解和掌握。因此&a…

数据结构初阶(栈和队列)

文章目录 一、栈1.1 什么是栈1.2 栈的使用(1)底层代码(2)方法(3)栈的应用 二、队列2.1 什么是队列2.2 队列的使用(1)底层代码的实现(2)队列的使用 2.3 双端队…

字节跳动发放年终奖,远超预期~

最近一段时间,国内互联网大厂接连公布年终奖情况,整个后厂村都洋溢在春节般的喜庆气氛里。 虽然由于各种各样的顾虑(主要是人员流失问题),大部分公司都将年终奖发放时间调整到了年中,但好饭不怕晚&#xf…

06_Callable接口

Thread类、Runnable接口使得多线程编程简单直接。 但Thread类和Runnable接口都不允许声明检查型异常,也不能定义返回值。没有返回值这点稍微有点麻烦。不能声明抛出检查型异常则更麻烦一些。 public void run()方法规范意味着你必须捕获并处理检查型异常。即使你小…

磁盘被格式化了能找到资料吗?资料找到的具体方法

磁盘格式化了还能找到,用读卡器接到电脑,就可以作为可移动磁盘来找到资料。下面讲下磁盘被格式化了能找到资料吗?资料找到的具体方法 磁盘被格式化了能找到资料吗?资料找到的具体方法 工具/软件:sayRecy 步骤1&#xf…

博世中国创新软件开发中心 BCSC

Bosch China Innovation and Software Development Campus 博世中国创新软件开发中心 BCSC 擎软件! 拓未来!Bosch China Innovation and Software Development Campus——IntroductionBOSCH——Our AdvantagesBOSCH——Hotly recruited positions Welcom…

wifi芯片行业信息汇总

1、Wifi概述 Wi-Fi这个术语被人们普遍误以为是指无线保真(Wireless Fidelity),并且即便是Wi-Fi联盟本身也经常在新闻稿和文件中使用“Wireless Fidelity”这个词。 主要版本: 随着最新的 802.11 ax 标准发布,新的 W…

『Linux』第九讲:Linux多线程详解(一)_ 线程概念 | 线程控制之线程创建 | 虚拟地址到物理地址的转换

「前言」文章是关于Linux多线程方面的知识,讲解会比较细,下面开始! 「归属专栏」Linux系统编程 「笔者」枫叶先生(fy) 「座右铭」前行路上修真我 「枫叶先生有点文青病」 「每篇一句」 我与春风皆过客, 你携秋水揽星河。 ——网络…

高精度延时

在使用STM32的时候可以使用SYSTICK来实现高精度延时。 I.MX6U没有SYSTICK定时器,但是有GPT定时器来实现高精度延时。 GPT(General Purpose Timer) GPT定时器是一个32位向上定时器(也就是从0x00000000开始向上递增计数&#xff0…

C#【必备技能篇】制作NuGet程序包,并发布到NuGet官网

文章目录 一、准备工作:在NuGet上创建并获取API Keys1、首先需要登录,直接用微软账户登录即可2、点击右上角菜单API Keys,创建Key3、填写信息并创建4、复制API Key 二、制作一个简单的dll三、创建发布文件夹四、上传NuGet程序包并发布1、方法…

java 上传压缩包遍历内容

项目环境&#xff1a;Spring Boot 2.0.6.RELEASE <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.6.RELEASE</version><relativePath/> <!-- loo…

Linux安装部署 seata server 1.4.2

Linux安装部署 seata server 1.4.2 下载安装包上传至服务器 1.首先从GitHub拉取seata压缩包 https://github.com/seata/seata/releases/download/v1.4.2/seata-server-1.4.2.zip 下载到本地后上传至服务器 或使用命令拉取 wget https://github.com/seata/seata/release…

数据库系统-故障恢复

文章目录 一、数据库故障恢复思路1.1 故障类型 影响1.1.1 DMBS运行方式1.1.2 故障类型 1.2 故障恢复1.2.1 数据库故障恢复1.2.2 事务故障恢复1.2.3 系统故障恢复1.2.4 介质故障恢复 二、运行日志及其检查点2.1 DB Log2.1.1 事务的操作2.1.2 缓冲区处理策略 2.2 日志记录 三、三…

Binder与 四大组件工作原理 Service、BroadCastReceiver、ContentProvider

Service 工作原理 Service有两套流程&#xff0c;一套是启动流程&#xff0c;另一套是绑定流程。我们做App开发的同学都应该知道 1&#xff09;在新进程启动Service 我们先看Service启动过程&#xff0c;假设要启动的Service是在一个新的进程中&#xff0c;分为5个阶段&#…

农业信息化有哪些SCI期刊推荐? - 易智编译EaseEditing

以下是一些农业信息化领域的SCI期刊推荐&#xff1a; Computers and Electronics in Agriculture&#xff1a; 该期刊涵盖了计算机和电子技术在农业生产和食品生产中的应用&#xff0c;如精准农业、农业机械自动化、智能传感器、农业模型和模拟等方面的研究。 影响因子为4.5…

离散数学组合计数

基本的组合计数公式 主要内容 加法法则和乘法法则排列与组合二项式定理与组合恒等式多项式定理 加法法则和乘法法则 加法法则乘法法则分类处理与分步处理 问题1&#xff1a;某旅游团从南京到上海&#xff0c;可以乘骑车&#xff0c;也可以乘火车&#xff0c;假定骑车每日有…