From 5b959e0a382491b3111afb66e10b6e866105e0c8 Mon Sep 17 00:00:00 2001 From: Darren Wong Date: Sat, 27 May 2017 18:38:31 +0800 Subject: [PATCH] docs: translate tutorials/progressive.md to English version (#966) --- docs/source/en/tutorials/progressive.md | 219 ++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 docs/source/en/tutorials/progressive.md diff --git a/docs/source/en/tutorials/progressive.md b/docs/source/en/tutorials/progressive.md new file mode 100644 index 0000000000..92942745d0 --- /dev/null +++ b/docs/source/en/tutorials/progressive.md @@ -0,0 +1,219 @@ +title: Progressive Development +--- + +Egg provides both [Plugin](../advanced/plugin.md) and [Framework](../advanced/framework.md), and the former has two loading modes includes `path` and `package`. Then how should we choose? + +Step-by-step example will be provided to demonstrate how to start coding development progressively. + +Find detail codes on [eggjs/examples/progressive](https://github.com/eggjs/examples/tree/master/progressive). + +## Getting Started + +Assume we are writing a code to analyze UA to implement the function below: + +- `ctx.isAndroid` +- `ctx.isIOS` + +You can easily write it down after previous tutorials, let's have a quick review: + +Codes refer to [step1](https://github.com/eggjs/examples/tree/master/progressive/step1). + +Directory structure: + +```bash +example-app +├── app +│ ├── extend +│ │ └── context.js +│ └── router.js +├── test +│ └── index.test.js +└── package.json +``` + +Core code: + +```js +// app/extend/context.js +module.exports = { + get isIOS() { + const iosReg = /iphone|ipad|ipod/i; + return iosReg.test(this.get('user-agent')); + }, +}; +``` + +## Prototype of Plugin + +Obviously, the logic is universal that can be written as a plugin. + +But since function might not perfect at the beginning, it might difficult to maintain if encapsulate into a plugin directly. + +We can put the code as the format of plugin, but not separate out. + +Codes refer to [step2](https://github.com/eggjs/examples/tree/master/progressive/step2). + +New directory structure: + +```bash +example-app +├── app +│ └── router.js +├── config +│ └── plugin.js +├── lib +│ └── plugin +│ └── egg-ua +│ ├── app +│ │ └── extend +│ │ └── context.js +│ └── package.json +├── test +│ └── index.test.js +└── package.json +``` + +Core code: + +- `app/extend/context.js` move to `lib/plugin/egg-ua/app/extend/context.js`. + +- `lib/plugin/egg-ua/package.json` to declare plugin. + +```json +{ + "eggPlugin": { + "name": "ua" + } +} +``` + +- `config/plugin.js` use `path` to mount the plugin. + +```js +// config/plugin.js +const path = require('path'); +exports.ua = { + enable: true, + path: path.join(__dirname, '../lib/plugin/egg-ua'), +}; +``` + +## Extraction to Independent Plugin + +The module's functions become more better after a period of developing so we could extract it out as an independent plugin. + +We extract an egg-ua plugin and have a quick review as below. Details refer to [Plugin](../advanced/plugin.md). + +Directory structure: + +```bash +egg-ua +├── app +│ └── extend +│ └── context.js +├── test +│ ├── fixtures +│ │ └── test-app +│ │ ├── app +│ │ │ └── router.js +│ │ └── package.json +│ └── ua.test.js +└── package.json +``` + +Codes refer to [step3/egg-ua](https://github.com/eggjs/examples/tree/master/progressive/step3/egg-ua). + +Then modify the application, details refer to [step3/example-app](https://github.com/eggjs/examples/tree/master/progressive/step3/example-app). + +- Remove directory `lib/plugin/egg-ua`. +- declare dependencies `egg-ua` in `package.json`. +- change type to `package` in `config/plugin.js`. + +```js +// config/plugin.js +exports.ua = { + enable: true, + package: 'egg-ua', +}; +``` + +**Note:We can use `npm link` for local test before releasing the plugin. Details refer to [npm-link](https://docs.npmjs.com/cli/link).** + +```bash +$ cd example-app +$ npm link ../egg-ua +$ npm i +$ npm test +``` + +## Finally: A Framework + +After repeating the process above, we accumulate a few plugins and configurations, and might found that most of our team projects are using them. + +At that time, you can consider to abstract them as a framework which suitable for business scenarios. + +Firstly, abstract the example-framework as below. Let's have a quick review, details refer to [Framework](../advanced/framework.md). + +Directory structure: + +```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 +``` + +- Codes refer to [example-framework](https://github.com/eggjs/examples/tree/master/progressive/step4/example-framework). +- Remove the dependencies of plugins such as `egg-ua` and remove it from example-app, then configure them into the `package.json` and `config/plugin.js` of the framework. + +Then modify the application, details refer to [step4/example-app](https://github.com/eggjs/examples/tree/master/progressive/step4/example-app). + +- Remove declaring dependencies `egg-ua` in `config/plugin.js`. +- Remove dependencies `egg-ua` in `package.json`. +- declare dependencies `example-framework` in `package.json` and configure the `egg.framework`. + +```json +{ + "name": "progressive", + "version": "1.0.0", + "private": true, + "egg": { + "framework": "example-framework" + }, + "dependencies": { + "example-framework": "*" + } +} +``` + +**Note:We can use `npm link` for local test before releasing the framework [npm-link](https://docs.npmjs.com/cli/link).** + +```bash +$ cd example-app +$ npm link ../egg-framework +$ npm i +$ npm test +``` + +## Last + +In conclusion, we can see how to make the framework evolution step by step which benefits from Egg provides the powerful plugin mechanism, code co-build, reusability and modularity. + + +- in general, put codes into `lib/plugin` if it can be reused in the application. +- separate it into a `node module` when plugin becomes stable. +- application with relatively reusable codes will work as a separate plugin. +- abstract as framework to release after application become certain solutions of specified business scenario. +- it would be a great improvement of teamwork after plugins extract, modularize and finally as a framework, beacuase other projects could reuse codes by just `npm install`. + +- **Note:Whether application/plugin/framework, unittest is a must and try to reach 100% coverage**