头图

前端脚手架开发入门

背景

脚手架是一个通用开发工具,之前自己写一下原生web工程时总是需要重复搭建开发环境、重复写几乎相同的配置文件。为了避免每次的重复工作,统一开发环境、规范,于是想到自己写一个脚手架用用,顺便记录一下。

目前个人习惯基于当前主流的webpack打包工具开发项目,所以此脚手架是基于webpack5开发的。

概览

本文我们先实现作为脚手架最基本的功能:输入命令 创建统一的模板项目

开发

依赖

开发一个的脚手架,你至少需要如下npm包:

  • commander:命令行处理工具
  • inquirer:命令行交互工具
  • download-git-repo:git仓库下载工具
  • ora:终端loading美化工具
  • chalk:命令行输入/输出美化工具

初始化项目

mkdir web-cli
cd web-cli
npm init -y

package.json 配置文件中定义bin字段

node.js 内置了对命令行操作的支持 bin 字段可以定义命令名和关联的执行文件。

项目中会使用ES6模块化开发,需要转换成最终执行命令的node.js能识别的common.js模块化,在script定义Babel编译的命令

"bin": {
  "web": "./bin/index.js"
}

在根目录下创建src/index.js文件作为入口,并在行首加入一行 #!/usr/bin/env node 指定当前脚本由node.js进行解析

Babel配置

项目中会使用ES6模块化开发,需要配置Babel转换成最终执行命令的node.js能识别的common.js模块化,安装相关依赖:

npm install --save-dev @babel/core @babel/cli @babel/preset-env

package.json 配置文件中script字段定义Babel编译的命令

"scripts": {
  "build": "babel src -d dist"
}

添加Babel配置文件babel.config.json

{
  "presets": ["@babel/preset-env"]
}

测试一下效果

除了将项目发包再global安装外,我们可以在项目根目录下执行npm link命令把指定的执行文件链接到全局环境。我们在入口代码中写一个输出hello world

#!/usr/bin/env node 

console.log('helo world!')

执行npm link后,我们打开命令行终端输入:web

我们能看到输出hello world

1662474680503.png

模板项目

我们需要创建一个完成通用配置的模板项目并上传到GitHub的公共仓库,这一步就不多演示了。我创建了一个基于webpack5并完成htmlWebpackPlugin、css资源处理、JavaScript资源处理及基础优化等基础配置的项目模板:https://github.com/LeoJ340/we...

接下来,我们需要通过输入命令拉取仓库代码并动态配置一些个人信息。需要实现的逻辑是:

  • 在命令行输入创建项目的命令以及项目名
  • 输入项目或作者的基本信息
  • 去GitHub拉取模板项目到自定义项目名的目录下
  • 根据读取的项目信息修改package.json配置

安装相关依赖:

npm install commander download-git-repo inquirer@6.5.0

commander

commander是一个用来注册命令以及获取命令行参数的第三方库,commander的注册命令基本用法如下:

import { program } from 'commander';

program.command('命令 [参数]', '命令描述', opts).action(回调函数)

// 解析用户执行时输入的参数
// process.argv 是 nodejs 提供的属性
program.parse(process.argv);

download-git-repo

download-git-repo是一个用于下载GitHub、Gitlab上的公共仓库的库。基本用法如下:

import download from 'download-git-repo';

download(repository, destination, options, callback)
  • repository:远程仓库的地址
  • destination:下载到本地的路径
  • options:配置参数(若传入函数,则覆盖回调函数)
  • callback:回调函数

inquirer

inquirer是一个提供了命令行的交互操作的库(新版的inquirer只支持ESM,即使用babel编译也会报错,所以这里需要使用老版本),用法也很简单(摘自官网):

import inquirer from 'inquirer';

inquirer
  .prompt([
    /* Pass your questions in here */
  ])
  .then((answers) => {
    // Use user feedback for... whatever!!
  })
  .catch((error) => {
    if (error.isTtyError) {
      // Prompt couldn't be rendered in the current environment
    } else {
      // Something else went wrong
    }
  });

接下来,我们修改一下入口代码:

#!/usr/bin/env node 

import { program } from 'commander';
import inquirer from 'inquirer';
import download from 'download-git-repo';

program.version('1.0.0')
// 注册create命令,name作为参数 指项目名
program.command('create <name>').action(name => {
    // 获取一些项目信息
    inquirer.prompt([
        {
            name: 'author',
            message: '你的名字是:'
        },
        {
            name: 'version',
            message: '版本号',
            default: '1.0.0'
        },
        {
            name: 'description',
            message: '项目描述',
            default: 'a web project template with Babel & ESLint'
        }
    ]).then(res => {
        // 拿到信息参数
        const { author, version, description } = res
        const beginTime = new Date().getTime()
        download(`LeoJ340/webpack-template`, `./${name}`, err => {
            const time = (new Date().getTime() - beginTime) / 1000
            console.log(err || `create project finish in ${time}s`)
        })
    })
});

program.parse(process.argv)

到这里,我们完成了脚手架最基本的输入命令、下载仓库的功能。通过inquirer获取的参数可以使用nodeJS的fs文件库修改package.json文件

优化

到目前为止,我们完成的脚手架最基本的功能,但是我们发现...命令行太丑了。于是决定优化一下,这里需要依赖两个库:chalkora

chalk

chalk是一个命令行美化工具,能够让你输出五彩斑斓的命令。

npm i chalk@4.1.2

import chalk from 'chalk';
console.log(chalk.green(`create project finish in 1s`))

ora

ora是一个实现命令行loading效果的库。使用方法也很简单:

npm i ora@3.4.0

import ora from 'ora';
// 定义一个loading
const loading = ora('template downloading...');
// 启动loading
loading.start()
// loading 成功
loading.success()
// loading 停止
loading.stop()

基于上面上个第三方库再优化一下代码,就完成了最初版的脚手架开发

源码仓库

GitHub:https://github.com/LeoJ340/web-cli,欢迎star⭐⭐⭐

如果你觉得本文对你有帮助,还请帮忙点个赞❤,如果你有不同的见解,欢迎评论区讨论。

9 声望
0 粉丝
0 条评论
推荐阅读
马上2023了,还不会TypeScript?快速入门
前言TypeScript is JavaScript with syntax for types.这是是官网对TypeScript的定义。作为JavaScript的超集,TypeScript重点提出了类型系统。如今 TS 已经受到了广泛的应用,它坚持与 JavaScript 核心语法标准 E...

coderLeo阅读 257

封面图
从零搭建 Node.js 企业级 Web 服务器(零):静态服务
过去 5 年,我前后在菜鸟网络和蚂蚁金服做开发工作,一方面支撑业务团队开发各类业务系统,另一方面在自己的技术团队做基础技术建设。期间借着 Node.js 的锋芒做了不少 Web 系统,有的至今生气蓬勃、有的早已夭折...

乌柏木143阅读 12k评论 10

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木60阅读 6k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs39阅读 6.2k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木39阅读 7.1k评论 6

CSS 绘制一只思否猫
欢迎关注我的公众号:前端侦探练习 CSS 有一个比较有趣的方式,就是发挥想象,绘制各式各样的图案,比如来绘制一只思否猫?思否猫,SegmentFault 思否的吉祥物,是一只独一无二、特立独行、热爱自由的(&gt;^ω^&lt...

XboxYan42阅读 2.8k评论 14

封面图
还在用 JS 做节流吗?CSS 也可以防止按钮重复点击
举个例子:一个保存按钮,为了避免重复提交或者服务器考虑,往往需要对点击行为做一定的限制,比如只允许每300ms提交一次,这时候我想大部分同学都会到网上直接拷贝一段throttle函数,或者直接引用lodash工具库

XboxYan34阅读 2.2k评论 2

封面图
9 声望
0 粉丝
宣传栏