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

  1. Command line parameter Settings (root directory, port, number of processes..)

  2. Process parameter formatting (parameter passing, port detection available)

  3. 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