egg源码浅析一npm init egg --type=simple
要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.
initializerin this case is an npm package namedcreate-<initializer>,which will be installed bynpx,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');
之后,进入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的更多相关文章
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 【深入浅出jQuery】源码浅析2--奇技淫巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- Struts2源码浅析-ConfigurationProvider
ConfigurationProvider接口 主要完成struts配置文件 加载 注册过程 ConfigurationProvider接口定义 public interface Configurat ...
- 【深入浅出jQuery】源码浅析2--使用技巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- Android源码浅析(四)——我在Android开发中常用到的adb命令,Linux命令,源码编译命令
Android源码浅析(四)--我在Android开发中常用到的adb命令,Linux命令,源码编译命令 我自己平时开发的时候积累的一些命令,希望对你有所帮助 adb是什么?: adb的全称为Andr ...
- Android源码浅析(三)——Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机
Android源码浅析(三)--Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机 最近比较忙,而且又要维护自己的博客,视频和公众号,也就没 ...
- kernel(二)源码浅析
目录 kernel(二)源码浅析 建立工程 启动简析 head.s 入口点 查询处理器 查询机器ID 启动MMU 其他操作 start_kernel 处理命令行 分区 title: kernel(二) ...
- redux 源码浅析
redux 源码浅析 redux 版本号: "redux": "4.0.5" redux 作为一个十分常用的状态容器库, 大家都应该见识过, 他很小巧, 只有 ...
- spring初始化源码浅析之关键类和扩展接口
目录 1.关键接口和类 1.1.关键类之 DefaultListableBeanFactory 1.2.关键类之XmlBeanDefinitionReader 1.3.关键类之ClassPathXml ...
随机推荐
- 深度学习_1_Tensorflow_1
# 深度学习 # 图像识别,自然语言处理 # 机器学习 深度学习 # 分类:神经网络(简单) 神经网络(深度) # 回归 图像:卷积神经网络 # 自然语言处理:循环神经网络 # cpu:运行操作系统, ...
- Miniconda虚拟环境管理工具命令方法
创建制定Python版本的虚拟环境 conda create --name 虚拟环境名称 Python=3.7.3(版本号) 进入指定虚拟环境 conda activate 虚拟环境名称 退出虚拟环境 ...
- Image Processing and Analysis_8_Edge Detection:Multiresolution edge detection techniques ——1995
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- redis系列二: linux下安装redis
下面介绍在Linux环境下,Redis的安装与配置 一. 安装 1.首先上官网下载Redis 压缩包,地址:http://redis.io/download 下载稳定版3.0即可. 2.通过远程管理工 ...
- pip安装tesserocr时报错
在Xubuntu上的python2虚拟环境中, 使用pip安装tesserocr时报错error: command 'x86_64-linux-gnu-gcc' failed with exit st ...
- 【洛谷P2480】古代猪文
题目大意:求 \[ G^{\sum\limits_{d|N}\binom{n}{k}} mod\ \ 999911659 \] 题解:卢卡斯定理+中国剩余定理 利用卢卡斯定理求出指数和式对各个素模数的 ...
- Linux初始化脚本
以下脚本用于linux系统的初始化脚本,可以在服务器系统安装完毕之后立即执行.脚本结合各位大牛一些参数,已经在CentOS 5下通过. 使用方法:将其复制,保存为一个shell文件,比如init.sh ...
- asyncio模块实现线程的嵌套和穿插
import asyncio import time now = lambda :time.time() async def cpc_1(x): print('正在烙比萨饼,预计{}分钟'.forma ...
- 【Android-布局复用】 多个界面复用一个布局文件(二)
多个界面复用一个布局界面 ,如何找到复用布局文件中的控件的id? 举个栗子: 1. layout_common.xml 复用的布局文件,如何找到button 的id? <?xml versio ...
- 北京清北 综合强化班 Day2
a [问题描述] 你是能看到第一题的 friends呢. —— hja世界上没有什么比卖的这 贵弹丸三还令 ...