美文网首页
npm脚手架开发学习

npm脚手架开发学习

作者: Felicity0512 | 来源:发表于2020-06-19 14:42 被阅读0次

之前学习了怎么在npm上传自己的模块,现在可以开发自己的脚手架了。

1、结构介绍

模块目录基本结构如下:

/bin  # ------ 命令执行文件
/lib  # ------ 工具模块
/template # ------ 模板
package.json

可以先不用在意这个结构。

2、实现命令行的操作

1)新建package.json

$ md my-cli                 // 创建插件项目文件夹
$ cd my-cli                 // 进入新建项目目录
$ npm init -y               // 创建package.json文件

根目录下得到package.json文件,修改如下:

{
  "name": "my-cli",
  "version": "1.0.0",
  "description": "",
  // "main": "index.js",
  "bin": { // main入口修改为bin入口
    "my-cli": "./bin/cli.js"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

2)新建入口文件cli.js

根目录新建./bin/cli.js文件,如下:

#!/usr/bin/env node
console.log("my-cli");

此时根目录运行如下:

$ node ./bin/cli.js
my-cli

得到my-cli的信息,表示运行成功。

文件开头的 #!/usr/bin/env node 是必须的。详情见https://www.npmjs.cn/files/package.json/#bin

3)使用commander开发命令行工具

生产环境安装commander,如下:

$ npm i commander -S

注册命令行

./bin/cli.js文件修改如下:

#!/usr/bin/env node
const program = require('commander'); // npm i commander -S

program.version('0.0.1')
    .usage('<command> [项目名称]')
    .command('init', 'init')
    .parse(process.argv)

此时需要新增./bin/cli-init.js文件如下:

#!/usr/bin/env node
console.log('init');

此时根目录运行如下:

$ node ./bin/cli.js init
init

得到init的信息,表示命令行工具注册成功。

获取命令行输入的内容

./bin/cli-init.js文件修改如下:

#!/usr/bin/env node
const program = require('commander')
const path = require('path')

program.usage('<project-name>').parse(process.argv)

let projectName = program.args[0] // 根据输入,获取项目名称
let rootName = path.basename(process.cwd()); // 获取当前进程的根目录名称
console.log(projectName, rootName);

验证:

$ node ./bin/cli.js init my-project
my-project my-cli

官方中文文档:Commander开发命令行工具

4)使用inquirer命令行交互工具

生产环境安装inquirer,如下:

$ npm i inquirer -S

./bin/cli-init.js文件修改如下:

#!/usr/bin/env node
const program = require('commander')
const path = require('path')
const inquirer = require('inquirer') // 新增引入inquirer

program.usage('<project-name>').parse(process.argv)

let projectName = program.args[0]
let rootName = path.basename(process.cwd());
console.log(projectName, rootName);

// 新增命令行交互
inquirer.prompt([
  {
    name: 'projectName', // 参数名称
    message: '项目的名称', // 信息提示
    default: projectName // 默认值
  }, {
    name: 'projectVersion',
    message: '项目的版本号',
    default: '0.0.1'
  }, {
    name: 'projectDescription',
    message: '项目的简介',
    default: `A project named ${projectName}`
  }
]).then(answers => {
  console.log(answers); // 打印输入参数
})

运行,输出如下:

$ node ./bin/cli.js init my-project
my-project my-cli
? 项目的名称 my-project
? 项目的版本号 0.0.1
? 项目的简介 A project named my-project
{
  projectName: 'my-project',
  projectVersion: '0.0.1',
  projectDescription: 'A project named my-project'
}

以上,就得到了几个重要的参数:项目名称、项目更目录名称、用户录入参数。简单的实现了,node命令行的操作。

推荐阅读:inquirer一个用户与命令行交互的工具

3、脚手架本地运行和测试

目前一直是$ node ./bin/cli.js init my-project的方式在运行脚本,体验并不好,没有脚手架的使用效果。我们现在可以进行本地包的运行和测试了。

1)安装my-cli脚手架到全局

my-cli根目录运行如下:

$ npm link

此时脚手架被安装到全局,可以使用了。

推荐阅读:npm link的使用
npm unlink // 卸载link安装

2)新建一个项目

在其它目录下新建一个项目如下:

$ md my-project                // 创建项目文件夹
$ cd my-project                // 进入项目文件夹
$ my-cli init my-project       // 运行脚手架
my-project my-project
? 项目的名称 my-project
? 项目的版本号 0.0.1
? 项目的简介 A project named my-project
{
  projectName: 'my-project',
  projectVersion: '0.0.1',
  projectDescription: 'A project named my-project'
}

得到如上信息,代表脚手架运行成功!

这篇文章的目的是为学习,为了最简单的理解脚手架是怎么工作,用什么实现的,所以这里是没有做校验逻辑。

4、复制模板文件到项目

只是单文件的复制,使用node的fs就能完成,但模板文件一般都是文件夹的多文件复制,所以我使用mvdir模块来复制文件夹,很好用。

1)新建模板文件

my-cli根目录下,新建template文件夹,新建模板文件package.json,也可以是任意你想复制的文件。
my-cli/template/package.json文件如下:

{
  "name": "{{projectName}}",
  "version": "{{projectVersion}}",
  "description": "{{projectDescription}}",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

{{}}内的是模板变量占位符。

2)mvdir复制模板文件

my-cli根目录安装mvdir,如下:

$ npm i mvdir -S

./bin/cli-init.js文件修改如下:

  ……
const mvdir = require('mvdir') // 引入模块
  ……
]).then(answers => {
  console.log(answers);
  // 使用mvdir复制template文件夹内容到my-project项目的.download-temp文件夹下。.download-temp为临时文件夹,编译模板后会删除。
  mvdir(path.join(__dirname, '../template'), '.download-temp', { copy: true }).then((err) => {
    if (err) {
      console.log(err);
    } else {
      console.log('复制成功');
    }
  });
})

my-project项目根目录下,运行:

$ my-cli init my-project

得到复制成功,就可在项目下看到复制的模板文件。

目前模板文件很小,所以放在了npm包里。如果模板文件很大,不适合放在npm包里的时候,可以将模板文件放在git上,然后使用download-git-repo工具,下载git上的模板文件到.download-temp的临时文件夹下。

5、使用Metalsmith编译模板文件

metalsmith就是一个静态网站生成器,可以用在批量处理模板的场景。handlebars是metalsmith的超集。

生产环境安装metalsmith和handlebars,如下:

$ npm i metalsmith handlebars -S

./bin/cli-init.js文件修改如下:

  ……
const Metalsmith = require('metalsmith') // 引入静态网站生成器
const Handlebars = require('handlebars') // 引入模板引擎
const rm = require('rimraf').sync
  ……
    } else {
      console.log('复制成功');
      const src = `${process.cwd()}/.download-temp`;
      Metalsmith(process.cwd())
      .metadata(answers) // 全局元数据
      .clean(false) // 是否删除
      .source(src) // 编译来源路径
      .destination('.') // 编译目标路径
      .use((files, metalsmith, done) => { // 自定义插件
        const meta = metalsmith.metadata()
        Object.keys(files).forEach(fileName => {
          const t = files[fileName].contents.toString()
          files[fileName].contents = Buffer.from(Handlebars.compile(t)(meta))
        })
        done()
      })
      .build(err => {
        rm(src)
        if(err) {
          console.log(err);
        } else {
          console.log('脚手架运行成功');
        }
      })
    }
  ……

my-project下运行:

$ my-cli init my-project

得到“脚手架运行成功”的提示,至此npm脚手架的基本功能就完成了。

目前还没有使用lib文件夹,后续的开发中,需要对用户输入的校验、模板编译文件的筛选、异步操作队列化等功能,都可封装到lib工具模块中使用,减小bin文件的体积,提高可复用性。

扩展阅读:metalsmith-apihandlebars
本人基于此文章《基于node.js的脚手架工具开发经历》学习,学习后重新整理思路,编写此文章留作笔记。

相关文章

  • npm脚手架开发学习

    之前学习了怎么在npm上传自己的模块,现在可以开发自己的脚手架了。 1、结构介绍 模块目录基本结构如下: 可以先不...

  • First day of react project

    启动项目开发使用 react 脚手架搭建项目开发环境运行: npm start生产环境打包运行: npm run ...

  • 搭建vue3.0 项目

    安装脚手架卸载原来的脚手架 npm uninstall vue-cli -g下载新的脚手架 npm unins...

  • 快速创建vue项目的两种方法

    正在学习vue开发,通过脚手架可以快速创建一个vue项目,前提是安装好node和淘宝npm镜像。 1.安装vue脚...

  • react学习二

    脚手架安装 安装官方脚手架: npm 创建项目: create-react-app 启动项目: npm start...

  • Angular2-Step 1

    前提需知:node、npm 包管理器 安装脚手架 @angular/cli 用于初始化、开发、搭建 Angular...

  • Hello React

    一、 开发环境配置(Mac) 1. node.js 安装 (node + npm) 2. 官方脚手架工具 crea...

  • GOME新环境新开发流程分享

    以下内容均是新开发环境的JS部分,无涉及构建部分 一: 开发前准备阶段: 脚手架安装:前提:(1)切域: npm ...

  • 使用react框架做的web后台管理系统技术总结

    react后台管理系统学习笔记 全局下载脚手架: npm install -g create-react-app ...

  • Guli 前端知识 28-

    前端技术栈和后端技术栈的类比 使用vue脚手架进行模块化开发 npm install webpack -g 全局...

网友评论

      本文标题:npm脚手架开发学习

      本文链接:https://www.haomeiwen.com/subject/fzjsxktx.html