Why explore the egg source code
There’s a lot of variety in frameworks right now, and that’s a good thing, as Node itself grows and developers have more options. I don’t want to get into a debate about the relative merits of multiple frameworks.
Among all these frameworks, Egg has its own legions of users, and it solves my practical production problems. I have benefited from it, and I want to learn about it, but that’s all.
Framework Stats
Role played by Egg-bin
Egg-bin is the entry point to the framework and is responsible for command line parsing (startup, debugging, testing) in a development environment. This chapter mainly from the source code for everyone to parse the egg dev start process.
You can see it in the initialized egg project package.json:
"scripts": {
"dev": "egg-bin dev"."debug": "egg-bin debug"."test-local": "egg-bin test"."cov": "egg-bin cov"
}
Copy the code
In the egg project package.json, you can see that the dev, debug, test-local, and cov commands all rely on egg-bin to start.
Egg-bin source code parsing
The directory structure is as follows:
package.json
index.js
bin
├─ egg-bin.js // Implement entry
├ ─ ─ ets. Js
└ ─ ─ mocha. Js
lib
├─ CMD // Command Line Parsing directory
│ ├ ─ ─ autod. Js
│ ├ ─ ─ cov. Js
│ ├ ─ ─ the debug. Js
│ ├ ─ ─ dev. Js
│ ├ ─ ─ local. Js
│ ├ ─ ─ pkgfiles. Js
│ └ ─ ─ test. Js
├ ─ ─ command. Js
└ ─ ─ start – cluster
Package. The json entrance
In the egg-bin module package.json you can see that the bin entry file is /bin/egg-bin.js
"bin": {
"egg-bin": "bin/egg-bin.js"."mocha": "bin/mocha.js"."ets": "bin/ets.js"
},
Copy the code
bin/egg-bin.js
#!/usr/bin/env node
'use strict';
const Command = require('.. ');
new Command().start();
Copy the code
The Command object comes from index.js with the following code:
const Command = require('./lib/command');
class EggBin extends Command {
constructor(rawArgv) {
super(rawArgv);
this.usage = 'Usage: egg-bin [command] [options]';
this.load(path.join(__dirname, 'lib/cmd')); // Load the js file corresponding to the command line arguments}}module.exports = exports = EggBin;
Copy the code
In index.js, we can see that the Command object is the EggBin class, which in turn inherits from Command and implements Command line implementation and processing on this class.
Common-bin Command line parsing
/lib/ command-js:
'use strict';
const path = require('path');
const fs = require('fs');
const BaseCommand = require('common-bin');
class Command extends BaseCommand {... }module.exports = Command;
Copy the code
As you can see from the code, the Command class in turn inherits from BaseCommand, and the implementation of the egg-bin module commands uses the common-bin common module.
Here is a brief description of the use of the common-bin module (git repository code example).
The this.load method was previously called from the EggBin class constructor
this.load(path.join(__dirname, 'lib/cmd'));
Copy the code
This method loads the js file in the lib/ CMD directory:
-
autod.js
-
cov.js
-
debug.js
-
dev.js
-
pkgfiles.js
-
test.js
This is equivalent to defining the autod, cov, debug, dev, pkgfiles, test commands, such as dev.js when we execute NPM run dev.
Equivalent to executing in the egg-bin module directory:
node ./bin/egg-bin.js dev
Copy the code
So Egg starts NPM run dev and executes the dev.js file.
Start the Master process
Dev.js contains three main features
-
Command line parameter Settings (root directory, port, number of processes..)
-
Process parameter formatting (parameter passing, port detection available)
-
Process started
class DevCommand extends Command {
constructor(rawArgv) {
this.options = { // Command line parameter Settings. }; } *run(context){...const task = this.helper.forkNode(this.serverBin, devArgs, options); // The process starts
}
* formatArgs(context) { // Format the process startup parameters.const port = yield detect(this.defaultPort);
}
module.exports = DevCommand;
Copy the code
The formatArgs method returns the value of the process’s arguments before starting:
{...tscompiler: 'ts-node/register'.workers: 1.// Number of processes
baseDir: '/Users/***/study/eggStudy/egg-bin'.// The current process root directory
port: 7001./ / port
framework: '/Users/***/study/eggStudy/egg-bin/node_modules/egg' // Frame directory
}
Copy the code
This.helper.forkNode is the EggBin method. I thought this.helper.forkNode was the EggBin method. Use to fork a child process. The this.serverBin parameter is the execution file, which is the lib/start-cluster file.
Start – cluster file:
require(options.framework).startCluster(options);
Copy the code
After executing a sequence of code starting with NPM run dev and temporarily stepping into the code in the start-cluster, the egg-bin module is done.
We will analyze the key module — egg-cluster! Please give a thumbs-up to ❤️❤️❤️
The next chapter is egg-cluster source code parsing