文章目录
  1. 1. 使用
  2. 2. 需求
  3. 3. 分析
  4. 4. 核心代码

vue有 vue-cli, angular有 angular-cli, react有 create-react-app。
那么我们该有什么?

这只是个笔记,这只是个笔记,这只是个笔记

使用

1
2
3
npm install -g mlive-cli
mlive list
mlive init

需求

随着ndoe和 webpack构建工具的发展,我们的具体项目开发环境越来越复杂,官方的构建工具和模板已经不能满足需求。
每次开始一个新的项目,需要不断复制之前的开发环境代码,然后修改,急需一个 类似 cli的脚手架工具产生 开发环境模板代码。这里解析模仿 vue-cli 产生自己的脚手架工具.

分析

首先 需要明确的是,模板文件需要一个 模板仓库来存放各种模板,可以使github或者什么资源仓库都好。
脚手架的功能主要是:

  • 查询可用模板
  • 下载模板
  • 安装模板

核心技术插件:

npm 中 bin的使用:
bin项用来指定各个内部命令对应的可执行文件的位置,例如:

1
{ "bin" : { "myapp" : "./cli.js" } }

当安装 myapp的时候,将为cli.js创建一个软连接 /usr/local/bin/myapp

注意, 可执行文件js 必须以 #!/usr/bin/env node开头,否则将无法执行

npm 中 link的使用

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// 根据传入的模板名称 下载模板
function download(template) {
const spinner = ora('正在下载模版...')
spinner.start()
if (exists(tmp)) {
rm(tmp)
}
downloadGitRepo(template, tmp, function (err) {
spinner.stop()
if (err) {
logger.error(chalk.red(err))
}
console.log()
logger.success('模版下载成功!')
generateProject({
name: name,
src: tmp,
dest: to
})
})
}

function generateProject(conf) {
generate(conf, function (err, files) {
if (err) {
logger.error('生成模版失败! ' + err)
}
logger.success('初始化完成!')
})
}
// 生成模板

function generate(conf, done) {

var opts = getOptions(conf.name, conf.src)
var metalsmith = Metalsmith(conf.src + '/template')

/**
* metalsmith.metadata() 全局插件流的一块元数据,
* Get the global metadata. This is useful for plugins that want to set global-level metadata that can be applied to all files.
*/
var data = Object.assign(metalsmith.metadata(), {
destDirName: conf.name,
inPlace: conf.dest === process.cwd(),
noEscape: true
})

/**
* 先不用 handlebars 处理模版
*/

// 第一步,给用户选择权利 装一些 插件的机会
metalsmith.use(askQuestions(opts.prompts))
.use(renderTemplateFiles())

metalsmith.clean(true)
.source('.')
.destination(conf.dest)
.build((err, files) => {
done(err, files)
console.log(opts.completeMessage)
})
}

/**
*
* @param {中间件 询问问题} prompts
*/
function askQuestions(prompts) {
return function (files, metalsmith, done) {
ask(prompts, metalsmith.metadata(), done)
}
}

详情请参考github

文章目录
  1. 1. 使用
  2. 2. 需求
  3. 3. 分析
  4. 4. 核心代码
顶部