### Initialization on Application Starting Source: https://eggjs.org/advanced/plugin Example of defining a task function that executes when the application starts. ```javascript exports.task = async (ctx) => { // your logic code }; ``` -------------------------------- ### Start application with EGG_SERVER_ENV Source: https://eggjs.org/basics/env Use the EGG_SERVER_ENV environment variable when starting the application to define the runtime environment. Example sets it to 'prod' for production. ```shell EGG_SERVER_ENV=prod npm start ``` -------------------------------- ### Start cluster with egg.startCluster Source: https://eggjs.org/advanced/framework Example of using the entry function for the multiprocess launcher to start the Master process. ```javascript const startCluster = require('egg').startCluster; startCluster( { // directory of code baseDir: '/path/to/app', // directory of framework framework: '/path/to/framework', }, () => { console.log('app started'); }, ); ``` -------------------------------- ### Use bootstrap for setup Source: https://eggjs.org/core/mock Using the bootstrap helper to automatically wire common setup and teardown for tests. ```javascript const { app, mock, assert } = require('egg-mock/bootstrap'); describe('test/controller/home.test.js', () => { // test cases }); ``` -------------------------------- ### Run development server Source: https://eggjs.org/intro/quickstart Start the development server and open the application in your browser. ```bash npm run dev open http://localhost:7001 ``` -------------------------------- ### Example application dependencies Source: https://eggjs.org/advanced/loader Example dependency configuration for an application, showing plugin2 depending on plugin3, and framework1 containing plugin1 and inheriting from egg. This is used to illustrate the loading order. ```text app | ├── plugin2 (depends plugin3) | └── plugin3 └── framework1 | └── plugin1 └── egg ``` -------------------------------- ### Install moment dependency Source: https://eggjs.org/intro/quickstart Install the moment library to handle date formatting. ```bash npm i moment --save ``` -------------------------------- ### Initial Directory Structure Source: https://eggjs.org/intro/progressive The directory structure for the initial application setup. ```bash example-app ├── app │ ├── extend │ │ └── context.js │ └── router.js ├── test │ └── index.test.js └── package.json ``` -------------------------------- ### Deploy single-process bundle Source: https://eggjs.org/core/bundle Commands to install production dependencies and start the single-process worker. ```bash $ npm ci --omit=dev $ node ./dist-bundle/worker.js ``` -------------------------------- ### Initialize project manually Source: https://eggjs.org/intro/quickstart Create a project directory and install the necessary egg and egg-bin packages. ```bash mkdir egg-example cd egg-example npm init npm i egg --save npm i egg-bin --save-dev ``` -------------------------------- ### Start Application with PM2 Source: https://eggjs.org/community/faq To use PM2, create a server.js file in the project root and then start the application using the pm2 command. ```javascript // server.js const egg = require('egg'); const workers = Number(process.argv[2] || require('os').cpus().length); egg.startCluster({ workers, baseDir: __dirname, }); ``` ```bash pm2 start server.js ``` -------------------------------- ### Build and start cluster mode bundle Source: https://eggjs.org/core/bundle Commands to build the cluster bundle and start it using egg-scripts. ```bash $ egg-bin bundle --cluster $ egg-scripts start --bundle --bundle-dir ./dist-bundle ``` -------------------------------- ### Quick Start Unit Test Source: https://eggjs.org/basics/unittest A basic example of an HTTP test using @eggjs/mock and Node.js assert. ```typescript import { app } from '@eggjs/mock/bootstrap'; import assert from 'node:assert'; describe('test/app/controller/home.test.ts', () => { it('should GET /', async () => { const result = await app.httpRequest().get('/').expect(200); assert(result.text === 'hi, egg'); }); }); ``` -------------------------------- ### Build Application Package Source: https://eggjs.org/core/deployment Install production dependencies and create a compressed archive for deployment. ```bash $ cd baseDir $ npm install --production $ tar -zcvf ../release.tgz . ``` -------------------------------- ### Create an app instance Source: https://eggjs.org/core/mock Manual setup of an Egg.js application instance for testing. ```javascript const mock = require('@eggjs/mock'); describe('test/controller/home.test.js', () => { let app; before(async () => { app = mock.app({ baseDir: 'path/to/your/app' }); await app.ready(); }); after(() => app.close()); }); ``` -------------------------------- ### Install egg-socket.io Source: https://eggjs.org/tutorials/socketio Install the plugin via npm. ```bash $ npm i egg-socket.io --save ``` -------------------------------- ### LoaderOptions initializer example Source: https://eggjs.org/advanced/loader Shows how to use the initializer option to process each file's exported value during loading. The example includes a model class definition and the loader setup that instantiates the model with app and path. The initializer receives the exported object and an options object containing the current file path. ```javascript // app/model/user.js module.exports = class User { constructor(app, path) {} }; // Loading from app/model, could do some initializations when loading. const directory = path.join(app.config.baseDir, 'app/model'); app.loader.loadToApp(directory, 'model', { initializer(model, opt) { // The first parameter is export's object // The second parameter is an object that only contains current file path. return new model(app, opt.path); }, }); ``` -------------------------------- ### Install testing dependencies Source: https://eggjs.org/intro/quickstart Install egg-mock as a development dependency. ```bash npm i egg-mock --save-dev ``` -------------------------------- ### Initialize project with scaffold Source: https://eggjs.org/intro/quickstart Use the Egg.js scaffold to generate a project structure and install dependencies. ```bash mkdir egg-example && cd egg-example npm init egg --type=simple npm i ``` -------------------------------- ### Controller example: app/controller/home.js and router Source: https://eggjs.org/core/unittest Shows a minimal controller and its router configuration. The controller returns 'hello world' as the response body. ```javascript // app/router.js module.exports = (app) => { const { router, controller } = app; router.get('homepage', '/', controller.home.index); }; // app/controller/home.js class HomeController extends Controller { async index() { this.ctx.body = 'hello world'; } } ``` -------------------------------- ### Install @eggjs/mock Source: https://eggjs.org/core/mock Command to install the mocking package as a development dependency. ```bash npm i @eggjs/mock --save-dev ``` -------------------------------- ### HttpClient data processing examples Source: https://eggjs.org/core/httpclient Demonstrates how data is processed for GET and POST requests, including JSON content type handling. ```javascript // GET + data ctx.curl(url, { data: { foo: 'bar' }, }); // POST + data ctx.curl(url, { method: 'POST', data: { foo: 'bar' }, }); // POST + JSON + data ctx.curl(url, { method: 'POST', contentType: 'json', data: { foo: 'bar' }, }); ``` -------------------------------- ### Generate manifest in Dockerfile with npx egg-bin manifest generate Source: https://eggjs.org/core/manifest Dockerfile steps for container deployment: install production dependencies, build, generate the startup manifest with npx egg-bin manifest generate --env=prod, then start the app. The manifest is used automatically on startup. ```dockerfile # Install dependencies and build RUN npm install --production RUN npm run build # Generate startup manifest RUN npx egg-bin manifest generate --env=prod # Start the app (manifest is used automatically) CMD ["npm", "start"] ``` -------------------------------- ### Test directory structure example Source: https://eggjs.org/core/unittest Test files must be placed in the 'test' directory and named with the pattern `${filename}.test.js`. This example shows the expected directory layout. ```bash test ├── controller │ └── home.test.js ├── hello.test.js └── service └── user.test.js ``` -------------------------------- ### loadToContext example: loading services into ctx Source: https://eggjs.org/advanced/loader Shows how to use app.loader.loadToContext to load service files into ctx with lazy instantiation. The example includes the service class definition and the loader setup in app.js. The call option is true so the exported class is returned, and fieldClass stores the class in app.serviceClasses. Instances are created on first access via ctx.service.user and cached per request. ```javascript // The following is just an example, using loadService in practice // app/service/user.js const Service = require('egg').Service; class UserService extends Service {} module.exports = UserService; // app.js // get all loadUnit const servicePaths = app.loader.getLoadUnits().map((unit) => path.join(unit.path, 'app/service')); app.loader.loadToContext(servicePaths, 'service', { // service needs to inherit app.Service, so needs app as parameter // enable call will return UserService when loading call: true, // loading file into app.serviceClasses fieldClass: 'serviceClasses', }); ``` -------------------------------- ### Install egg-passport and egg-passport-github Source: https://eggjs.org/tutorials/passport Install the egg-passport plugin and the GitHub strategy package using npm. ```bash $ npm i --save egg-passport $ npm i --save egg-passport-github ``` -------------------------------- ### Routing Rules Examples (app/router.js) Source: https://eggjs.org/basics/router Example of defining routes in `app/router.js`. Shows how to use `router.get`, `router.post` with middleware and controllers. Controllers can be specified directly or as strings, and sub-directories are supported. ```javascript // app/router.js module.exports = (app) => { const { router, controller } = app; router.get('/home', controller.home); router.get('/user/:id', controller.user.page); router.post('/admin', isAdmin, controller.admin); router.post('/user', isLoginUser, hasAdminPermission, controller.user.create); router.post('/api/v1/comments', controller.v1.comments.create); // app/controller/v1/comments.js }; ``` -------------------------------- ### Configure package.json Scripts Source: https://eggjs.org/core/deployment Define start and stop commands in your package.json file. ```json { "scripts": { "start": "egg-scripts start --daemon", "stop": "egg-scripts stop" } } ``` -------------------------------- ### Correct test setup with beforeAll hook Source: https://eggjs.org/core/unittest Shows the correct way to run setup code before tests: place it in a beforeAll hook. This ensures the code runs at the intended time during test execution. ```TypeScript // Good import { app } from '@eggjs/mock/bootstrap'; describe('good test', () => { beforeAll(() => doSomethingBefore()); it('should redirect', () => { return app.httpRequest().get('/').expect(302); }); }); ``` -------------------------------- ### Access Helper in Controller (app/controller/user.js) Source: https://eggjs.org/basics/objects Shows how to get the Helper instance via ctx.helper in a Controller. The example uses ctx.helper.formatUser(user) to format a user object and sets it as the response body. ```javascript // app/controller/user.js class UserController extends Controller { async fetch() { const { app, ctx } = this; const id = ctx.query.id; const user = app.cache.get(id); ctx.body = ctx.helper.formatUser(user); } } ``` -------------------------------- ### Install passport-local Source: https://eggjs.org/tutorials/passport Command to install the passport-local strategy package via npm. ```bash $ npm i --save passport-local ``` -------------------------------- ### Start Application with egg-scripts Source: https://eggjs.org/core/deployment Launch the application in production mode using egg-scripts with specific configuration flags. ```bash $ egg-scripts start --port=7001 --daemon --title=egg-server-showcase ``` -------------------------------- ### Service example: app/service/user.js Source: https://eggjs.org/core/unittest Shows a service class that fetches a user by name from a user database. ```javascript // app/service/user.js class UserService extends Service { async get(name) { return await userDatabase.get(name); } } ``` -------------------------------- ### Install egg-mysql plugin via npm Source: https://eggjs.org/basics/plugin Install the egg-mysql plugin using npm. The command is run in the terminal. ```bash $ npm i egg-mysql --save ``` -------------------------------- ### Initialize a new framework scaffold Source: https://eggjs.org/advanced/framework Commands to create a new directory, initialize the egg framework scaffold, install dependencies, and run tests. ```bash $ mkdir yadan && cd yadan $ npm init egg --type=framework $ npm i $ npm test ``` -------------------------------- ### Initialize Socket.io Client in Browser Source: https://eggjs.org/tutorials/socketio Example of initializing a socket connection in the browser with query parameters and event listeners for p2p communication. ```javascript // browser const log = console.log; window.onload = function () { // init const socket = io('/', { // Actual use can pass parameters here query: { room: 'demo', userId: `client_${Math.random()}`, }, transports: ['websocket'], }); socket.on('connect', () => { const id = socket.id; log('#connect,', id, socket); // receive online user information // listen for its own id to implement p2p communication socket.on(id, (msg) => { log('#receive,', msg); }); }); socket.on('online', (msg) => { log('#online,', msg); }); // system events socket.on('disconnect', (msg) => { log('#disconnect', msg); }); socket.on('disconnecting', () => { log('#disconnecting'); }); socket.on('error', () => { log('#error'); }); window.socket = socket; }; ``` -------------------------------- ### Render templates with ctx.render, renderView, and renderString Source: https://eggjs.org/core/view Example controller showing the three rendering interfaces: render, renderView, and renderString. renderString requires a viewEngine unless defaultViewEngine is set. ```js // {app_root}/app/controller/home.js class HomeController extends Controller { async index() { const data = { name: 'egg' }; // render a template, path relate to `app/view` await ctx.render('home/index.tpl', data); // or manually set render result to ctx.body ctx.body = await ctx.renderView('path/to/file.tpl', data); // or render string directly ctx.body = await ctx.renderString('hi, {{ name }}', data, { viewEngine: 'nunjucks', }); } } ``` -------------------------------- ### Start application with proxy environment variable Source: https://eggjs.org/core/httpclient Run your application with the http_proxy environment variable set to route traffic through your capture tool. ```bash $ http_proxy=http://127.0.0.1:8888 npm run dev ``` -------------------------------- ### agent.js - Agent initialization and IPC Source: https://eggjs.org/core/cluster-and-ipc Example of agent.js for implementing custom logic in the Agent process, including sending messages to App Workers after 'egg-ready' event. ```js // agent.js module.exports = agent => { // put your initialization logics here // messages can also be sent by the messenger object to App Worker // but you should wait until App Worker starts up successfully, or the message may be lost agent.messenger.on('egg-ready', () => { const data = { ... }; agent.messenger.sendToApp('xxx_action', data); }); }; ``` -------------------------------- ### Install egg-bin dependency Source: https://eggjs.org/core/development Install the egg-bin module as a development dependency to enable local development and unit testing tools. ```bash $ npm i egg-bin --save-dev ``` -------------------------------- ### Directory structure showing access level example Source: https://eggjs.org/basics/di This tree shows the module layout for the access level example. `fooModule` contains `Private.ts`, `Public.ts`, and `Access.ts`; `barModule` contains `Access.ts`. The comment indicates which prototypes can be injected in each `Access.ts`. ```ts root dir └── app └── module ├── fooModule │ ├── Private.ts │ ├── Public.ts │ └── Access.ts // Can Inject Private/Public └── barModule └── Access.ts // Can only Inject Public ``` -------------------------------- ### Example package.json for an Egg.js plugin Source: https://eggjs.org/advanced/plugin This package.json example shows the required eggPlugin property and the keywords to include for indexing. The plugin name is 'nunjucks' and it depends on the 'security' plugin. ```json { "name": "egg-view-nunjucks", "version": "1.0.0", "description": "view plugin for egg", "eggPlugin": { "name": "nunjucks", "dep": ["security"] }, "keywords": ["egg", "egg-plugin", "eggPlugin", "egg-plugin-view", "egg-view", "nunjucks"] } ``` -------------------------------- ### Example of application_config_meta.json Source: https://eggjs.org/basics/config Shows the format of the meta file that indicates which configuration file defined a property. Here, 'logger.dir' is defined in '/path/to/config/config.default.js'. ```json { "logger": { "dir": "/path/to/config/config.default.js" } } ``` -------------------------------- ### Start Egg.js Master process with egg-scripts Source: https://eggjs.org/core/cluster-and-ipc Starts the Master process in daemon mode using the egg-scripts CLI. This is the recommended way to launch the application in production. ```bash $ egg-scripts start --daemon ``` -------------------------------- ### Simple Connection Handling Source: https://eggjs.org/tutorials/socketio Example of handling a connection by immediately disconnecting if a condition is met. ```javascript // {app_root} /app/io/middleware/connection.js module.exports = (app) => { return async (ctx, next) => { if (true) { ctx.socket.disconnect(); return; } await next(); console.log('disconnection!'); }; }; ``` -------------------------------- ### Controller Implementation Source: https://eggjs.org/tutorials/socketio Example of a controller class and an async function approach for handling socket events. ```javascript // {app_root} /app/io/controller/default.js 'use strict'; const Controller = require('egg').Controller; class DefaultController extends Controller { async ping() { const { ctx, app } = this; const message = ctx.args[0]; await ctx.socket.emit('res', `Hi! I've got your message: $ {message}`); } } module.exports = DefaultController; // or async functions exports.ping = async function () { const message = this.args[0]; await this.socket.emit('res', `Hi! I've got your message: $ {message}`); }; ``` -------------------------------- ### Implement MySQL in Service Layer Source: https://eggjs.org/tutorials/mysql Example of querying the database within a Service class. ```javascript // app/service/user.js class UserService extends Service { async find(uid) { // assume we have the user id then trying to get the user details from database const user = await this.app.mysql.get('users', { id: 11 }); return { user }; } } ``` -------------------------------- ### Start cluster mode from snapshot blobs Source: https://eggjs.org/advanced/snapshot Launches the application in cluster mode by providing specific blobs for the app and agent roles. ```bash $ egg-scripts start --bundle \ --app-snapshot-blob ./dist-bundle/app.snapshot.blob \ --agent-snapshot-blob ./dist-bundle/agent.snapshot.blob ``` -------------------------------- ### Framework startup sequence diagram Source: https://eggjs.org/core/cluster-and-ipc ASCII diagram showing the startup sequence between Master, Agent, and Worker processes. ```bash +---------+ +---------+ +---------+ | Master | | Agent | | Worker | +---------+ +----+----+ +----+----+ | fork agent | | +-------------------->| | | agent ready | | |<--------------------+ | | | fork worker | +----------------------------------------->| | worker ready | | |<-----------------------------------------+ | Egg ready | | +-------------------->| | | Egg ready | | +----------------------------------------->| ``` -------------------------------- ### GET /api/v2/topics/:id - Response body (JSON) Source: https://eggjs.org/tutorials/restful Example response body for the GET /api/v2/topics/:id endpoint. Returns a single topic object with the same fields as the list response. ```json { "id": "57ea257b3670ca3f44c5beb6", "author_id": "541bf9b9ad60405c1f151a03", "tab": "share", "content": "content", "title": "Finished Rewriting of Let's Learning Node.js Together", "last_reply_at": "2017-01-11T10:20:56.496Z", "good": false, "top": true, "reply_count": 193, "visit_count": 47633 } ``` -------------------------------- ### Using koa-compress in Koa Source: https://eggjs.org/basics/middleware Example of how koa-compress is traditionally used in a Koa application. ```javascript const koa = require('koa'); const compress = require('koa-compress'); const app = koa(); const options = { threshold: 2048 }; app.use(compress(options)); ``` -------------------------------- ### Start process from snapshot blob Source: https://eggjs.org/advanced/snapshot Launches a single self-contained process using the specified snapshot blob. ```bash $ egg-scripts start --snapshot-blob ./dist-bundle/snapshot.blob --port 7001 ``` -------------------------------- ### Listen to Application Events Source: https://eggjs.org/basics/objects Use the app.js start script to listen for server lifecycle events such as server startup, errors, and request/response logging. ```javascript // app.js module.exports = (app) => { app.once('server', (server) => { // websocket }); app.on('error', (err, ctx) => { // report error }); app.on('request', (ctx) => { // log receive request }); app.on('response', (ctx) => { // ctx.starttime is set by framework const used = Date.now() - ctx.starttime; // log total cost }); }; ``` -------------------------------- ### GET /api/v2/topics - Response body (JSON) Source: https://eggjs.org/tutorials/restful Example response body for the GET /api/v2/topics endpoint. Returns a list of topic objects with fields like id, author_id, tab, content, title, and various counts. ```json [ { "id": "57ea257b3670ca3f44c5beb6", "author_id": "541bf9b9ad60405c1f151a03", "tab": "share", "content": "content", "last_reply_at": "2017-01-11T13:32:25.089Z", "good": false, "top": true, "reply_count": 155, "visit_count": 28176, "create_at": "2016-09-27T07:53:31.872Z" }, { "id": "57ea257b3670ca3f44c5beb6", "author_id": "541bf9b9ad60405c1f151a03", "tab": "share", "content": "content", "title": "Finished Rewriting of Let's Learning Node.js Together", "last_reply_at": "2017-01-11T10:20:56.496Z", "good": false, "top": true, "reply_count": 193, "visit_count": 47633 } ] ``` -------------------------------- ### Implement framework extension Source: https://eggjs.org/advanced/framework Example of extending the Egg Application class and overriding customEggPaths to define a custom framework. ```javascript // package.json { "name": "yadan", "dependencies": { "egg": "^2.0.0" } } // index.js module.exports = require('./lib/framework.js'); // lib/framework.js const path = require('path'); const egg = require('egg'); class Application extends egg.Application { protected override customEggPaths() { // return the path of framework return [path.dirname(__dirname), ...super.customEggPaths()]; } } // rewrite Egg's Application module.exports = Object.assign(egg, { Application, }); ``` -------------------------------- ### HTTPHeaders decorator to get request headers Source: https://eggjs.org/basics/httpcontroller Uses the HTTPHeaders decorator to inject the complete request headers. Note that header keys are converted to lowercase, so access them with lowercase names. The example shows a GET endpoint that reads a custom header 'x-custom'. ```typescript import { HTTPController, HTTPMethod, HTTPMethodEnum, HTTPHeaders, IncomingHttpHeaders } from 'egg'; @HTTPController() export default class ArgsController { // curl http://localhost:7001/api/hello -H 'X-Custom: custom' @HTTPMethod({ method: HTTPMethodEnum.GET, path: '/api/hello' }) async getHeaders(@HTTPHeaders() headers: IncomingHttpHeaders) { const custom = headers['x-custom']; // ... } } ``` -------------------------------- ### Connection Middleware Implementation Source: https://eggjs.org/tutorials/socketio Example of a connection middleware used for authorization or handling client connections and disconnections. ```javascript // {app_root} /app/io/middleware/connection.js module.exports = (app) => { return async (ctx, next) => { ctx.socket.emit('res', 'connected!'); await next(); // execute when disconnect. console.log('disconnection!'); }; }; ``` -------------------------------- ### Example output of npm run debug Source: https://eggjs.org/core/development The console output when starting the application in debug mode, showing debugger listeners and the DevTools proxy URL. ```bash ➜ showcase git:(master) ✗ npm run debug > showcase@1.0.0 debug /Users/tz/Workspaces/eggjs/test/showcase > egg-bin debug Debugger listening on ws://127.0.0.1:9229/f8258ca6-d5ac-467d-bbb1-03f59bcce85b For help see https://nodejs.org/en/docs/inspector 2017-09-14 16:01:35,990 INFO 39940 [master] egg version 1.8.0 Debugger listening on ws://127.0.0.1:5800/bfe1bf6a-2be5-4568-ac7d-69935e0867fa For help see https://nodejs.org/en/docs/inspector 2017-09-14 16:01:36,432 INFO 39940 [master] agent_worker#1:39941 started (434ms) Debugger listening on ws://127.0.0.1:9230/2fcf4208-4571-4968-9da0-0863ab9f98ae For help see https://nodejs.org/en/docs/inspector 9230 opened Debug Proxy online, now you could attach to 9999 without worry about reload. DevTools → chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9999/__ws_proxy__ ``` -------------------------------- ### Directory structure of example-framework Source: https://eggjs.org/intro/progressive The standard directory layout for an Egg.js-based framework. ```bash example-framework ├── config │ ├── config.default.js │ └── plugin.js ├── lib │ ├── agent.js │ └── application.js ├── test │ ├── fixtures │ │ └── test-app │ └── framework.test.j. ├── README.md ├── index.js └── package.json ``` -------------------------------- ### Configure dev script in package.json Source: https://eggjs.org/core/development Add the dev script to your package.json to start the application in development mode. ```json { "scripts": { "dev": "egg-bin dev" } } ``` -------------------------------- ### Build Snapshot Entry Source: https://eggjs.org/advanced/snapshot Use buildSnapshot to start Egg in snapshot mode and generate the blob. ```typescript import { buildSnapshot } from 'egg'; await buildSnapshot({ baseDir: import.meta.dirname, }); ``` -------------------------------- ### Initialize Egg.js application with npm init egg --type=simple Source: https://eggjs.org/tutorials/restful Initializes a new Egg.js application in a directory named cnode-api using the simple template and installs dependencies. ```bash $ mkdir cnode-api && cd cnode-api $ npm init egg --type=simple $ npm i ``` -------------------------------- ### Async function example with await Source: https://eggjs.org/intro/egg-and-koa Shows how to use async/await to write asynchronous code in a synchronous style. The function awaits getUser and fetchPosts, then returns an object. The promise is handled with .then and .catch. ```javascript const fn = async function () { const user = await getUser(); const posts = await fetchPosts(user.id); return { user, posts }; }; fn() .then((res) => console.log(res)) .catch((err) => console.error(err.stack)); ``` -------------------------------- ### Send messages after egg-ready in app.js Source: https://eggjs.org/core/cluster-and-ipc Example app.js that uses app.messenger to send messages to Agent and App processes. Messages can only be sent after the 'egg-ready' event fires, ensuring all processes are started. ```javascript // app.js module.exports = (app) => { // Note, only after egg-ready event occurs can the message be sent app.messenger.once('egg-ready', () => { app.messenger.sendToAgent('agent-event', { foo: 'bar' }); app.messenger.sendToApp('app-event', { foo: 'bar' }); }); }; ``` -------------------------------- ### CustomLoader with loadToApp example Source: https://eggjs.org/advanced/loader Shows the traditional way to define a custom loader using app.loader.loadToApp in app.js. It loads files from app/adapter into app.adapter. ```javascript // app.js module.exports = (app) => { const directory = path.join(app.config.baseDir, 'app/adapter'); app.loader.loadToApp(directory, 'adapter'); }; ``` -------------------------------- ### Initiate Framework Testing with mock.app Source: https://eggjs.org/advanced/framework Demonstrates how to initialize a framework test using mock.app. The framework option is required to point to the current directory, and app.ready() must be awaited. ```javascript const mock = require('@eggjs/mock'); describe('test/index.test.js', () => { let app; before(() => { app = mock.app({ // test/fixtures/apps/example baseDir: 'apps/example', // importent !! Do not miss framework: true, }); return app.ready(); }); after(() => app.close()); afterEach(mock.restore); it('should success', () => { return app.httpRequest().get('/').expect(200); }); }); ``` -------------------------------- ### Class-based AppBootHook for beforeStart Source: https://eggjs.org/advanced/loader-update The recommended approach using didLoad for plugins and willReady for applications to replace beforeStart. ```javascript // app.js or agent.js: class AppBootHook { constructor(app) { this.app = app; } async didLoad() { // Please put your codes of `app.beforeStart` here for your plugin } async willReady() { // Please put your codes of `app.beforeStart` here for your application } } module.exports = AppBootHook; ``` -------------------------------- ### Implementing a Plugin with app.addSingleton Source: https://eggjs.org/advanced/plugin Demonstrates how to use app.addSingleton to mount a service instance and initialize it with a creator function. ```javascript // egg-mysql/app.js module.exports = (app) => { // The first parameter mysql defines the field mounted to app, we can access MySQL singleton instance via `app.mysql` // The second parameter createMysql accepts two parameters (config, app), and then returns a MySQL instance app.addSingleton('mysql', createMysql); }; /** * @param {Object} config The config is processed by the framework. If the application is configured with multiple MySQL instances, each config would be passed in and call multiple createMysql * @param {Application} app the current application * @return {Object} return the created MySQL instance */ function createMysql(config, app) { assert(config.host && config.port && config.user && config.database); // create instance const client = new Mysql(config); // check before start the application app.beforeStart(async () => { const rows = await client.query('select now() as currentTime;'); app.coreLogger.info(`[egg-mysql] init instance success, rds currentTime: ${rows[0].currentTime}`); }); return client; } ``` -------------------------------- ### Initialize Socket.io Client in WeChat Applet Source: https://eggjs.org/tutorials/socketio Example of using a library like wxapp-socket-io to connect to a socket server from a WeChat applet. ```javascript // Small program-side sample code import io from 'vendor/wxapp-socket-io.js'; const socket = io('ws://127.0.0.1:7001'); socket.on('connect', function () { socket.emit('chat', 'hello world!'); }); socket.on('res', (msg) => { console.log('res from server: %s!', msg); }); ``` -------------------------------- ### Final loading order Source: https://eggjs.org/advanced/loader Final loading order for the example dependencies: plugin1, plugin3, plugin2, egg, framework1, app. This order respects plugin dependencies and framework inheritance. ```text => plugin1 => plugin3 => plugin2 => egg => framework1 => app ``` -------------------------------- ### Perform a GET request with ctx.curl Source: https://eggjs.org/core/httpclient Demonstrates a basic GET request to an external API. The HttpClient defaults to GET if no method is specified. ```javascript // app/controller/npm.js class NpmController extends Controller { async get() { const ctx = this.ctx; const result = await ctx.curl('https://httpbin.org/get?foo=bar'); ctx.status = result.status; ctx.set(result.headers); ctx.body = result.data; } } ``` -------------------------------- ### Scaffold plugin with npm init Source: https://eggjs.org/advanced/plugin Creates a new plugin project using the egg-boilerplate-plugin scaffold. Run these commands in order to initialize the project, install dependencies, and run tests. ```bash $ mkdir egg-hello && cd egg-hello $ npm init egg --type=plugin $ npm i $ npm test ``` -------------------------------- ### Asynchronous Plugin Initialization Source: https://eggjs.org/advanced/plugin Shows how to use an async function for initialization when configuration needs to be fetched asynchronously. ```javascript async function createMysql(config, app) { // get mysql configurations asynchronous const mysqlConfig = await app.configManager.getMysqlConfig(config.mysql); assert(mysqlConfig.host && mysqlConfig.port && mysqlConfig.user && mysqlConfig.database); // create instance const client = new Mysql(mysqlConfig); // check before start the application const rows = await client.query('select now() as currentTime;'); app.coreLogger.info(`[egg-mysql] init instance success, rds currentTime: ${rows[0].currentTime}`); return client; } ``` -------------------------------- ### Basic Gzip Middleware Function Source: https://eggjs.org/basics/middleware A simple middleware example demonstrating the Koa onion model by awaiting the next middleware before processing the response body. ```javascript const isJSON = require('koa-is-json'); const zlib = require('zlib'); async function gzip(ctx, next) { await next(); // convert the response body to gzip after the completion of the execution of subsequent middleware let body = ctx.body; if (!body) return; if (isJSON(body)) body = JSON.stringify(body); // set gzip body, correct the response header const stream = zlib.createGzip(); stream.end(body); ctx.body = stream; ctx.set('Content-Encoding', 'gzip'); } ``` -------------------------------- ### Install egg-view-nunjucks plugin Source: https://eggjs.org/core/view Install the egg-view-nunjucks plugin as a dependency for your Egg.js application. ```bash $ npm i egg-view-nunjucks --save ``` -------------------------------- ### Asynchronous Agent Startup with agent.beforeStart Source: https://eggjs.org/advanced/plugin Use the agent.beforeStart API to perform asynchronous initialization tasks for the agent process. ```javascript // ${plugin_root}/agent.js const MyClient = require('my-client'); module.exports = (agent) => { agent.myClient = new MyClient(); agent.myClient.on('error', (err) => { agent.coreLogger.error(err); }); agent.beforeStart(async () => { await agent.myClient.ready(); agent.coreLogger.info('my client is ready'); }); }; ``` -------------------------------- ### Install egg-dev as devDependency Source: https://eggjs.org/basics/plugin Install the egg-dev plugin as a devDependency and add it to package.json. This is used for environment-specific plugin loading. ```js // npm i egg-dev --save-dev // package.json { "devDependencies": { "egg-dev": "*" } } ``` -------------------------------- ### Asynchronous Application Startup with beforeStart Source: https://eggjs.org/advanced/plugin Use the app.beforeStart API to perform asynchronous initialization tasks before the application is ready. ```javascript // ${plugin_root}/app.js const MyClient = require('my-client'); module.exports = (app) => { app.myClient = new MyClient(); app.myClient.on('error', (err) => { app.coreLogger.error(err); }); app.beforeStart(async () => { await app.myClient.ready(); app.coreLogger.info('my client is ready'); }); }; ``` -------------------------------- ### GET request response from Koa server Source: https://eggjs.org/core/security Response from a GET request to the Koa server, showing the httpOnly cookie being set. ```http HTTP/1.1 200 OK X-Powered-By: koa Set-Cookie: a=1; path=/; httponly Content-Type: text/plain; charset=utf-8 Content-Length: 2 Date: Thu, 06 Nov 2014 05:04:42 GMT Connection: keep-alive OK ``` -------------------------------- ### Package the application Source: https://eggjs.org/core/manifest Create a compressed archive of the project, including the generated .egg/manifest.json file. ```bash tar -zcvf release.tgz . ``` -------------------------------- ### Mock service method with app.mockService Source: https://eggjs.org/core/unittest Use app.mockService('user', 'get', fn) to mock the get(name) method in app/service/user to return a nonexistent user. The test sends a GET request to /user?name=fengmk1 and expects a 200 status with the mocked user object. ```javascript it('should mock fengmk1 exists', () => { app.mockService('user', 'get', () => { return { name: 'fengmk1', }; }); return ( app .httpRequest() .get('/user?name=fengmk1') .expect(200) // return an originally nonexistent user .expect({ name: 'fengmk1', }) ); }); ``` -------------------------------- ### Configuration file using exports.key = value Source: https://eggjs.org/basics/config A shorthand format for configuration files, setting keys and logger level directly. ```js exports.keys = 'my-cookie-secret-key'; exports.logger = { level: 'DEBUG', }; ``` -------------------------------- ### Error: framework.RouterConflictError for GET /apps/:id Source: https://eggjs.org/faq/TEGG_ROUTER_CONFLICT The error message shown when a route conflict is detected. It indicates that the GET /apps/:id route is already registered. ```bash framework.RouterConflictError: register http controller GET AppController2.get failed, GET /apps/:id is conflict with exists rule /apps/:id ``` -------------------------------- ### Initialize plugin with npm init egg --type=plugin Source: https://eggjs.org/tutorials/passport Run this command to scaffold a new egg plugin named egg-passport-local. ```bash $ npm init egg --type=plugin egg-passport-local ``` -------------------------------- ### Access helper object with ctx.helper and use pathFor Source: https://eggjs.org/basics/extend Shows how to access the helper object and use a built-in helper method. The example assumes a home router is defined and demonstrates pathFor generating a URL with query parameters. ```javascript // Assume that home router has already defined in app/router.js app.get('home', '/', 'home.index'); // Use helper to calculate the specific url path ctx.helper.pathFor('home', { by: 'recent', limit: 20 }); // => /?by=recent&limit=20 ``` -------------------------------- ### Run bundle command Source: https://eggjs.org/core/bundle Execute the bundling process to generate a self-contained artifact in the default output directory. ```bash $ egg-bin bundle ``` -------------------------------- ### Initialize Egg.js project with CLI Source: https://eggjs.org/tutorials Use the npm init command to scaffold a new Egg.js application with a specific boilerplate type. ```bash $ npm init egg --type=simple ``` -------------------------------- ### Declare a simple HTTP controller with GET endpoint Source: https://eggjs.org/basics/httpcontroller Use @HTTPController() to mark a class as an HTTP controller and @HTTPMethod to define a GET /api/hello/:name endpoint. The @HTTPParam() decorator injects the route parameter 'name'. ```typescript import { HTTPController, HTTPMethod, HTTPMethodEnum, HTTPParam } from 'egg'; @HTTPController() export default class SimpleController { // Declare a GET /api/hello/:name interface @HTTPMethod({ method: HTTPMethodEnum.GET, path: '/api/hello/:name' }) async hello(@HTTPParam() name: string) { return { message: 'hello ' + name, }; } } ``` -------------------------------- ### Node.js cluster IPC example Source: https://eggjs.org/core/cluster-and-ipc Official Node.js example showing basic IPC between Master and Worker processes using the cluster module. Demonstrates sending a message from Master to a forked Worker and echoing it back. ```javascript 'use strict'; const cluster = require('cluster'); if (cluster.isMaster) { const worker = cluster.fork(); worker.send('hi there'); worker.on('message', (msg) => { console.log(`msg: ${msg} from worker#${worker.id}`); }); } else if (cluster.isWorker) { process.on('message', (msg) => { process.send(msg); }); } ``` -------------------------------- ### Synchronous Startup Initialization Source: https://eggjs.org/advanced/plugin Read local configuration or data files during application startup in app.js. ```javascript // ${plugin_root}/app.js const fs = require('fs'); const path = require('path'); module.exports = (app) => { app.customData = fs.readFileSync(path.join(app.config.baseDir, 'data.bin')); app.coreLogger.info('read data ok'); }; ``` -------------------------------- ### Mock service error with app.mockServiceError Source: https://eggjs.org/core/unittest Use app.mockServiceError('user', 'get', error) to mock the get(name) method in app/service/user to throw an exception. The test expects a 500 status code and the error message 'mock user service error' in the response. ```javascript it('should mock service error', () => { app.mockServiceError('user', 'get', 'mock user service error'); return ( app .httpRequest() .get('/user?name=fengmk2') // service exception causing the 500 status code .expect(500) .expect(/mock user service error/) ); }); ``` -------------------------------- ### Dynamically Create MySQL Instance Source: https://eggjs.org/tutorials/mysql Initialize a MySQL instance dynamically using app.mysql.createInstance() within the application startup lifecycle. ```javascript // {app_root}/app.js module.exports = (app) => { app.beforeStart(async () => { // obtain the MySQL configuration from the configuration center // { host: 'mysql.com', port: '3306', user: 'test_user', password: 'test_password', database: 'test' } const mysqlConfig = await app.configCenter.fetch('mysql'); app.database = app.mysql.createInstance(mysqlConfig); }); }; ``` -------------------------------- ### Class-based AppBootHook for ready Source: https://eggjs.org/advanced/loader-update The recommended approach using didReady to replace app.ready. ```javascript // app.js or agent.js: class AppBootHook { constructor(app) { this.app = app; } async didReady() { // Please put your codes of `app.ready` here } } module.exports = AppBootHook; ``` -------------------------------- ### Kick Out User Example Source: https://eggjs.org/tutorials/socketio Utility function to disconnect a specific user by ID. ```javascript const tick = (id, msg) => { logger.debug('# tick', id, msg); socket.emit(id, msg); app.io.of('/').adapter.remoteDisconnect(id, true, (err) => { logger.error(err); }); }; ``` -------------------------------- ### Configure Namespace in Socket.io and Egg.js Source: https://eggjs.org/tutorials/socketio Demonstrates the difference between standard Socket.io namespace initialization and the Egg.js configuration approach. ```javascript // socket.io var nsp = io.of('/my-namespace'); nsp.on('connection', function (socket) { console.log('someone connected'); }); nsp.emit('hi', 'everyone!'); // egg exports.io = { namespace: { '/': { connectionMiddleware: [], packetMiddleware: [], }, }, }; ``` -------------------------------- ### Dynamically create MySQL instance in app.js using app.mysql.createInstanceAsync Source: https://eggjs.org/advanced/plugin Use this in app.js to create a MySQL instance at runtime before the application starts. The configuration is fetched from a configuration center, and the instance is stored on app.database. The framework reads the 'default' configuration from the config file as the default when creating the instance dynamically. ```javascript // app.js module.exports = (app) => { app.beforeStart(async () => { // get MySQL config from configuration center { host, post, password, ... } const mysqlConfig = await app.configCenter.fetch('mysql'); // create MySQL instance dynamically app.database = app.mysql.createInstanceAsync(mysqlConfig); }); }; ``` -------------------------------- ### Emit Exchange Event from Client Source: https://eggjs.org/tutorials/socketio Example of how to trigger the exchange event from the client side. ```javascript socket.emit('exchange', { target: '/webrtc#Dkn3UXSu8_jHvKBmAAHW', payload: { msg: 'test', }, }); ``` -------------------------------- ### Legacy beforeStart implementation Source: https://eggjs.org/advanced/loader-update The deprecated way of handling beforeStart using module.exports in app.js. ```javascript module.exports = (app) => { app.beforeStart(async () => { // Here's where your codes were before }); }; ``` -------------------------------- ### View project directory structure Source: https://eggjs.org/intro/quickstart The expected file structure after creating the controller, router, and config files. ```bash egg-example ├── app │ ├── controller │ │ └── home.js │ └── router.js ├── config │ └── config.default.js └── package.json ``` -------------------------------- ### Disabling default middleware Source: https://eggjs.org/basics/middleware Example of disabling the default bodyParser middleware in the application configuration. ```javascript module.exports = { bodyParser: { enable: false, }, }; ``` -------------------------------- ### Configure EJS Plugin Source: https://eggjs.org/advanced/view-plugin Example configuration for the EJS template engine plugin in config/config.default.js. ```javascript // config/config.default.js module.exports = { ejs: { cache: true, }, }; ``` -------------------------------- ### Get one record Source: https://eggjs.org/tutorials/mysql Retrieves a single record from the specified table based on the provided criteria. ```javascript const post = await this.app.mysql.get('posts', { id: 12 }); => SELECT * FROM `posts` WHERE `id` = 12 LIMIT 0, 1; ``` -------------------------------- ### Configuration Loading Sequence under prod Environment Source: https://eggjs.org/basics/config Shows the order in which configuration files are loaded in a 'prod' environment, with later files overwriting earlier ones. Priority: application > framework > plugin, and environment-specific configs override defaults. ```text -> plugin config.default.js -> framework config.default.js -> application config.default.js -> plugin config.prod.js -> framework config.prod.js -> application config.prod.js ``` -------------------------------- ### Install egg-scripts Dependency Source: https://eggjs.org/core/deployment Add egg-scripts to your project dependencies to manage application lifecycle in production. ```bash $ npm i egg-scripts --save ``` -------------------------------- ### Bootstrap test file with @eggjs/mock Source: https://eggjs.org/core/unittest Creates a test file that imports the app and mock from '@eggjs/mock/bootstrap' to avoid redundant app instance creation. When using egg-bin, '@eggjs/mock/setup_vitest' is automatically injected as a vitest setup file, handling beforeAll, afterEach, and afterAll automatically. ```TypeScript // test/controller/home.test.ts import { app, mock } from '@eggjs/mock/bootstrap'; import assert from 'node:assert'; describe('test/controller/home.test.ts', () => { // test cases }); ``` -------------------------------- ### Run unit tests Source: https://eggjs.org/intro/quickstart Execute the test suite using npm. ```bash npm test ```