要egg文档最开始的时候,有这样的几条命令:

我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目:
$ mkdir egg-example && cd egg-example
$ npm init egg --type=simple
$ npm i

其中的 npm init egg --type=simple 命令为什么能够生成egg项目的基本构架呢?

一、npm init命令

根据 https://www.npmjs.cn/cli/init/ 官网的解释:

npm init <initializer> can be used to set up a new or existing npm package.

initializer in this case is an npm package named create-<initializer>, which will be installed by npx, and then have its main bin executed.

 按照上面的解释,npm init egg 相当于 npx create-egg 并且执行create-egg的bin.

二、npx命令

  npx相当于npm,但npx会把node_modules/.bin/目录加入环境变量.

  这里讲怎么用:http://www.ruanyifeng.com/blog/2019/02/npx.html

也就是说,npm init egg 相当于执行 npx create-egg,而npx create-egg命令会下载create-egg库,再执行里面的bin(package.json里的bin字段)。

  另外,npx create-egg 会在当前目录/node_modules目录下查找有没有create-egg,没有就会下载到临时目录,最后删除。

三、下载create-egg库

  create-egg的目录结构如下,package.json里没有main,却有bin字段,bin字段值是./bin/create-egg.js。当安装create-egg的时,会在当前安装目录下的node_modules/.bin/目录放置create-egg作为可执行文件。

  

  create-egg.js文件里只有一行代码:

console.log('--------i am create-egg');
require('egg-init/bin/egg-init');

  再来看egg-init库。

四、egg-init

#!/usr/bin/env node
'use strict';
const co = require('co');
const Command = require('..'); co(function* () {
console.log('process.cwd:', process.cwd());
console.log('process.argv.slice:', process.argv.slice(2));
// process.cwd: /Users/demon/Desktop/test/createeggtest
// process.argv.slice: [ '--type=simple' ]
yield new Command().run(process.cwd(), process.argv.slice(2));
}).catch(err => {
console.error(err.stack);
process.exit(1);
});

process.cwd是命令执行的所有文件夹,argv.slice(2)之后是--type=simple字符串。

之后,向 https://registry.npmjs.org/egg-init-config/latest请求,获取响应:

{
"name":"egg-init-config",
"version":"1.5.0",
"description":"egg init boilerplate config",
"config":{
"boilerplate":{
"simple":{
"package":"egg-boilerplate-simple",
"description":"Simple egg app boilerplate"
},
"microservice":{
"package":"egg-boilerplate-microservice",
"description":"Microservice app boilerplate based on egg"
},
"sequelize":{
"package":"egg-boilerplate-sequelize",
"description":"egg app with sequelize"
},
"ts":{
"package":"egg-boilerplate-ts",
"description":"Simple egg && typescript app boilerplate"
},
"empty":{
"package":"egg-boilerplate-empty",
"description":"Empty egg app boilerplate"
},
"plugin":{
"package":"egg-boilerplate-plugin",
"description":"egg plugin boilerplate"
},
"framework":{
"package":"egg-boilerplate-framework",
"description":"egg framework boilerplate"
}
}
},
...
}

根据得到的响应,匹配--type=simple,得到package:

"simple":{
"package":"egg-boilerplate-simple",
"description":"Simple egg app boilerplate"
},

得到egg-boilerplate-simple,再次向 https://registry.npmjs.org/egg-boilerplate-simple/latest请求,

{
"name": "egg-boilerplate-simple",
"version": "3.3.1",
 ...
"dist": {
"integrity": "sha512-zj8ES0n7lAXGMWornOOY1n0Q+skX0wA9hjl40QsTa3SS5FcExVoEWQ52kCeT+bnvNKEL8fiOD9S2J4J9wDjbKg==",
"shasum": "c56c87c1f2b705a9247b0903958aac76d141b2c6",
"tarball": "https://registry.npmjs.org/egg-boilerplate-simple/-/egg-boilerplate-simple-3.3.1.tgz",
"fileCount": 31,
"unpackedSize": 19461,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcv91nCRA9TVsSAnZWagAAyZ8P/RyW3+wL32xjrVTDNDlQ\nBuxafQ/J5gGtG3tlwkqG184G3hSoceY0qSiIKv60sVsOtMZfJUZd5znNAGro\n/pSmKW23jfA1Xw49HGMfT++6ZQ+PoZ8l13p5zwjIHs10+d/RAx1hi3xm6xiA\nTjfKQXCUbt7aLYGQgpX155ZD/DcvI+VUWTw6fc5pJg7NXkOFDSwo+TaxsxHX\nw7iom89bQICaK6mBybDMI2+gkeMvSuKPnBiI8TuSCrgoGnkfXWF6Hd6ZL76O\nG3uA2LqYNqELUsPyoD97NL17vOayGbP8xJdn+l9dUQF8e4oD9m6gjEz0uTKO\nr3zxjx8X8HrjaJo2CJbYrOl5+zNYrM4dTt/oY5zU56aoOesCcht8FxrcaHNl\n/fVxIH8YgUzv3ZbwGRAb5G/NwF5GwtfmyGtkiJ/9i5awB+QLezC7Hkl4ZMGZ\nnblIDGnPGF+zY7Epg2FPDQgB/SDurENiAFiSPBX7jbi3AH9hfABHeH4NeYTi\n5j+NGtv2QY6eqffxrQpg7Vibe5nbRKCPkLqcqy0BsPixSHe7RvnNMulxX609\nJUCrz5M9YNQEAkDckomD5QDzWzTFaPEWqUUjohfgPheIi2KJ9w0jU2QV6pxG\nh3MbZNyLYHw1cXUEkupiNqSVwP7NGbDcH5t5uQGrSS4j4RdpxrSonNaB0You\nZdaq\r\n=Q83Q\r\n-----END PGP SIGNATURE-----\r\n"
},
  ...
}

拿到dist.tarball字段的值,下载到临时目录下的egg-init-boilerplate目录并解压:

const saveDir = path.join(os.tmpdir(), 'egg-init-boilerplate');
  yield compressing.tgz.uncompress(response.res, saveDir);

之后,进入saveDir/package/boilerplate目录,boilerplate目录内容如下

之后就是把这个目录的内容拷贝到目标目录下,当然会把_前缀去掉:

const to = path.join(targetDir, this.replaceTemplate(this.fileMapping[file] || file, locals));
const content = fs.readFileSync(from);
this.log('write to %s', to); // check if content is a text file
const result = isTextOrBinary.isTextSync(from, content)
? this.replaceTemplate(content.toString('utf8'), locals)
: content; mkdirp.sync(path.dirname(to));
fs.writeFileSync(to, result);

这就是npm init egg --type=simple内容的由来了。

 
 


egg源码浅析一npm init egg --type=simple的更多相关文章

  1. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  2. 【深入浅出jQuery】源码浅析2--奇技淫巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  3. Struts2源码浅析-ConfigurationProvider

    ConfigurationProvider接口 主要完成struts配置文件 加载 注册过程 ConfigurationProvider接口定义 public interface Configurat ...

  4. 【深入浅出jQuery】源码浅析2--使用技巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  5. Android源码浅析(四)——我在Android开发中常用到的adb命令,Linux命令,源码编译命令

    Android源码浅析(四)--我在Android开发中常用到的adb命令,Linux命令,源码编译命令 我自己平时开发的时候积累的一些命令,希望对你有所帮助 adb是什么?: adb的全称为Andr ...

  6. Android源码浅析(三)——Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机

    Android源码浅析(三)--Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机 最近比较忙,而且又要维护自己的博客,视频和公众号,也就没 ...

  7. kernel(二)源码浅析

    目录 kernel(二)源码浅析 建立工程 启动简析 head.s 入口点 查询处理器 查询机器ID 启动MMU 其他操作 start_kernel 处理命令行 分区 title: kernel(二) ...

  8. redux 源码浅析

    redux 源码浅析 redux 版本号: "redux": "4.0.5" redux 作为一个十分常用的状态容器库, 大家都应该见识过, 他很小巧, 只有 ...

  9. spring初始化源码浅析之关键类和扩展接口

    目录 1.关键接口和类 1.1.关键类之 DefaultListableBeanFactory 1.2.关键类之XmlBeanDefinitionReader 1.3.关键类之ClassPathXml ...

随机推荐

  1. 移动端设备管理平台 atx server2实践

    目录 1.需求背景 2.初步调研 2.1.云测试平台 2.2.开源工具 2.3.VNC 2.4.企业内部自研云测试平台 3.ATX Server安装 依赖环境 安装rethinkdb 安装atx se ...

  2. 《浏览器工作原理与实践》<06>渲染流程(下):HTML、CSS和JavaScript,是如何变成页面的?

    在上篇文章中,我们介绍了渲染流水线中的 DOM 生成.样式计算和布局三个阶段,那今天我们接着讲解渲染流水线后面的阶段. 这里还是先简单回顾下上节前三个阶段的主要内容:在 HTML 页面内容被提交给渲染 ...

  3. 万能模拟器eve-ng介绍

    作为一名网络工程师,通过模拟器来搭建实验环境是必不可少的,主流的网络模拟器有如下几款:Packet Tracer是思科公司出的一款模拟器,只能模拟思科自己的设备,由于此款软件是纯软件模拟,所以思科设备 ...

  4. Jmeter官方插件实现Dubbo接口测试

    目前主流的分布式框架有Dubbo和SpringCloud, SpringCloud是基于Http协议的分布式框架,Dubbo是基于RPC的分布式框架,Jmeter没有内置对Dubbo接口的支持,很难直 ...

  5. 回顾了下shell 编程的一些细节

    回顾了一些细节 shell 的通配符扩展   *  ? []  [^xxxx]  {aaa,bbb}         子进程 more `grep -l POSIX *` more $(grep -l ...

  6. mysql你问我答

    1.尊敬的先生,请您谈谈mysql数据库的引擎 数据库中的表设定了什么存储引擎,那么该表在数据存储方式.数据更新方式.数据查询性能以及是否支持索引等方面就会有不同的“效果”. mysql引擎大致分两类 ...

  7. redis序列化和反序列化

    RedisTemplate中需要声明4种serializer,默认为“JdkSerializationRedisSerializer”: 1) keySerializer :对于普通K-V操作时,ke ...

  8. 【Java-算法】 十六进制转字节数组

    Java Code public class Convert{ public static void main(String args[]) { String sHex = "00 B6 0 ...

  9. python中装饰器(语法糖)概念

    “”“” 什么是装饰器? """ 还是通过一个例子来慢慢说明 先看下面的例子 def func_1(x): return x*2 def fun_2(x): return ...

  10. hybird(h5)页面自动化测试