要egg文檔最開始的時候,有這樣的幾條命令:html
咱們推薦直接使用腳手架,只需幾條簡單指令,便可快速生成項目: $ mkdir egg-example && cd egg-example $ npm init egg --type=simple $ npm i
其中的 npm init egg --type=simple 命令爲何可以生成egg項目的基本構架呢?node
1、npm init命令typescript
根據 https://www.npmjs.cn/cli/init/ 官網的解釋:npm
npm init <initializer>
can be used to set up a new or existing npm package.json
initializer
in this case is an npm package namedcreate-<initializer>,
which will be installed by
npx
,and then have its main bin executed.
app
按照上面的解釋,npm init egg 至關於 npx create-egg 而且執行create-egg的bin.ui
2、npx命令this
npx至關於npm,但npx會把node_modules/.bin/目錄加入環境變量. spa
這裏講怎麼用:http://www.ruanyifeng.com/blog/2019/02/npx.htmlcode
也就是說,npm init egg 至關於執行 npx create-egg,而npx create-egg命令會下載create-egg庫,再執行裏面的bin(package.json裏的bin字段)。
另外,npx create-egg 會在當前目錄/node_modules目錄下查找有沒有create-egg,沒有就會下載到臨時目錄,最後刪除。
3、下載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庫。
4、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內容的由來了。