Nodejs framework of paypal Kraken-js source code analysis

Source: Internet
Author: User
Tags i18n
This article is based on the kraken-js0.6.1 version on how to use kraken-js can go to see the official site of the use of documentation click here. Kraken-js is based on express. It aims to allow engineers to focus more on code logic and less on their own development environments... syntaxHighlighter. all (); this article is based on kraken-js 0.6.1. For details about how to use kraken-js, go to the official website and click here. Kraken-js is based on express. It aims to allow engineers to focus more on code logic and less on their own development environments, all the common configurations of express are written in the configuration file. Few are exposed to developers. Let's take a look at the kraken-js source code and analyze how to create a nodejs application. If you are not familiar with express, you can refer to the decryption sequence of express framework written in my previous blog. Follow the steps on the kraken-js official website to create a new project and generate the code. The following describes the structure: /config --- application and middleware configuration/controllers --- routing and logic/lib --- user-developed third-party library/locales --- Language Pack/models --- model/public --- public resources/public/templates --- template/tests --- index of some test cases. js --- app portal let's look at the entry file index. js and the route file controllers/index. js 'use strict '; var kraken = require ('kraken-js'), app ={}; app. configure = function configure (nconf, next) {// Fired when an app configures itself next (null) ;}; app. requestStart = funct Ion requestStart (server) {// Fired at the beginning of an incoming request}; app. requestBeforeRoute = function requestBeforeRoute (server) {// Fired before routing occurs}; app. requestAfterRoute = function requestAfterRoute (server) {// Fired after routing occurs}; kraken. create (app ). listen (function (err) {if (err) {console. error (err) ;}}); 'use strict '; module. exports = function (server) {ser Ver. get ('/', function (req, res) {var model = {name: 'helloworld'}; res. render ('index', model) ;};}; we can see in index. in the js file, there are no port settings, no template engine and other middleware settings, and only some hooks. This is what kraken-js is like. The specific method is: first create an app, add some methods (configure, requestStart, requestBeforeRoute, requestAfterRoute) to the app, and then pass the app as the create method parameter of the kraken. create (app), and then call the listen method (mainly to call http createServer to create a service ). In fact, the app here provides some hooks for the express framework as a proxy. The parameter server of these methods is the instance created by the express framework. We use express's use method to call middleware. This will be explained in detail later. Since the create method of kraken is called, let's look at the kraken source code to see how the application is constructed. We can see in kraken-js/index. js provides an external call function: exports. create = function (route, delegate) {return create (). use (route, delegate) ;}; you can see that it first calls its own create method, and then calls the use method. Let's look at the create method: function create () {return Object. create (kraken, {_ app: {enumerable: true, writable: true, value: null}, _ promise: {enumerable: true, writable: true, value: null }, host: {enumerable: true, writable: true, value: undefined}, port: {enumerable: true, writable: true, value: undefined },'☯': {// This is silly, but since a require-d app may be using // kraken, but the proto isn' t a reference to the same // object, we need to have a unique identifier for the // 'iskraken' check. (Non-enumerable .) value :'☯'});} It creates a kraken object and adds some attributes. In the use method, the most important thing is: chain = create (this. _ app ). then (assign ). then (create ). then (mount); first, an empty app is passed in by calling the create method, and the create method is function create (delegate) {return appcore. create (delegate, pathutil. create (resolveRoot);} it directly calls the create method of appcore: function create (delegate, resolver, callback) {var app, appcore; if (isExpress (delegate )) {callback (null, delegate); return;} if (typeof resolver = 'function') {Callback = resolver; resolver = pathutil. create ();} app = express (); if (! Delegate) {patch. apply ('stream', app); callback (null, app); return;} appcore = Object. create (proto, {_ app: {enumerable: true, writable: false, value: app}, _ delegate: {enumerable: true, writable: false, value: delegate }, _ resolver: {enumerable: true, writable: false, value: resolver}, _ config: {enumerable: true, writable: true, value: undefined}, _ i18n: {enumerable: true, writable: true, Value: undefined}); appcore. init (function (err) {if (err) {callback (err); return;} callback (null, app );});} we know that the app for this parameter is empty. So I entered this branch: app = express (); if (! Delegate) {patch. apply ('stream', app); callback (null, app); return;} imports express directly. Patch. apply ('stream', app); directly rewrite the response of the app. Returns express. Then execute :. then (assign ). then (create ). then (mount); assign is to assign the app to this. _ app. At the same time, the second thing is done. The hooks of the application are returned and passed directly to the create FUNCTION. We can see that the create FUNCTION is called again. What is different from the first one is, this parameter is not blank, but the "app" we created in the application, that is, the hook we mentioned earlier. Finally, mount the application. In the second call of the create method. Actually, an appcore Object is created through proto: appcore = Object. create (proto, {_ app: {enumerable: true, writable: false, value: app}, _ delegate: {enumerable: true, writable: false, value: delegate }, _ resolver: {enumerable: true, writable: false, value: resolver}, _ config: {enumerable: true, writable: true, value: undefined}, _ i18n: {enumerable: true, writable: true, value: undefined}); we can see this app as appco The _ app attribute of re. delegate is actually an attribute of _ delagate. This is the index. the app object passed in by js, and then the init method of proto is called: appcore. init (function (err) {if (err) {callback (err); return;} callback (null, app) ;}); init directly calls the _ configure method, in this method, first assign the app value to app = this. _ app; then, use this. _ config = config. create (this. _ resolve ('. '), read the config file under the kraken and the config directory of the application. Finally, call the next method. In the next method: function next (err) {var config, settings; if (err) {callback (err); return;} config = self. _ config; patch. apply ('config', app, config); // XXX: Special-case resolving 'express: view' until we get config protocols working. config. set ('express: views', self. _ resolve (config. get ('express: views'); config. set ('express: env', config. get ('env: env'); config. set ('express: port', config. port); con Fig. set ('express: host', config. host); settings = config. get ('express '); Object. keys (settings ). forEach (function (key) {app. set (key, settings [key]) ;}); settings = config. get ('ssl '); if (settings) {app. set ('ssl ', settings); tls. SLAB_BUFFER_SIZE = settings. slabBufferSize | tls. SLAB_BUFFER_SIZE; tls. CLIENT_RENEG_LIMIT = settings. clientRenegotiationLimit | tls. CLIENT_RENEG_LIMIT; tls. CLIENT_RENEG_W INDOW = settings. clientRenegotiationWindow | tls. CLIENT_RENEG_WINDOW;} self. _ views (); self. _ middleware (); callback (); some parameters are configured first in this method. Then, the parameter _ views () for processing the view is called, and the _ middleware () function is called. We can see: if (typeof this. _ delegate. configure = 'function') {this. _ delegate. configure (this. _ config. raw, next); return;} If configure is a function, call this method first, and then call the next method. As we mentioned earlier, this. _ delegate is actually the "app" hook created in index. js. We omit the view. We mainly look at how to call the _ middleware function. First, go to the source code: _ middleware: function () {var app, delegate, config, srcRoot, staticRoot, errorPages; app = this. _ app; delegate = this. _ delegate; config = this. _ config. get ('middleware ware '); srcRoot = this. _ resolve (config. static. srcRoot); staticRoot = this. _ resolve (config. static. rootPath); app. use (express. favicon (); app. use (kraken. compiler (srcRoot, staticRoot, this. _ config, this. _ i18n); app. use (express. stat Ic (staticRoot); app. use (kraken. logger (config. logger); if (typeof delegate. requestStart = 'function') {delegate. requestStart (app);} config. bodyParser & console. warn (The 'middleware: bodyParser 'configuration will not be honored in future versions. use 'middleware: json', 'middleware: urlencoded', and 'middleware. multipart '. '); app. use (express. json (config. bodyParser | config. json); app. use (ex Press. urlencoded (config. bodyParser | config. urlencoded); console. warn ('multipart body parsing will be disabled by default in future versions. to enable, use 'middleware: multipart' configuration. '); app. use (express. multipart (config. bodyParser | config. multipart | {limit: 2097152}); // default to 2 mb limit app. use (express. cookieParser (config. session. secret); app. use (kraken. session (config. ses Sion); app. use (kraken. appsec (config. appsec); if (typeof delegate. requestBeforeRoute === 'function') {delegate. requestBeforeRoute (app);} enrouten (app ). withRoutes ({directory: this. _ resolve (this. _ config. get ('routes: routepath')}); if (typeof delegate. requestAfterRoute = 'function') {delegate. requestAfterRoute (app);} errorPages = config. errorPages | |{}; app. use (kraken. fileNotFound (errorPage S ['20140901']); app. use (kraken. serverError (errorPages ['20140901']); app. use (kraken. errorHandler (config. errorHandler);}, here we see the basic configurations of express which are very familiar, and some of its configurations are written here. As we can see, these are the hooks used to process our previous functions. As you can see, all applications built by express are passed in. If (typeof delegate. requestStart = 'function') {delegate. requestStart (app);} if (typeof delegate. requestBeforeRoute === 'function') {delegate. requestBeforeRoute (app);} if (typeof delegate. requestAfterRoute = 'function') {delegate. requestAfterRoute (app);} at the same time, there is enrouten (app ). withRoutes ({directory: this. _ resolve (this. _ config. get ('routes: routepath')}); this is actually used to process routes. It calls the express-enrouten mode. Module. exports = function (app) {return {withRoutes: function (settings) {settings = settings ||{}; if (settings. index) {require (resolve (settings. index) (app); return;} // Directory to scan for routes loaddir (settings. directory ). forEach (function (file) {var controller = require (file); if (typeof controller === 'function' & controller. length = 1) {controller (app ); }); (Settings. routes | []). forEach (function (def) {assert. OK (def. path, 'path is required'); assert. OK (typeof def. handler = 'function', 'handler is required'); var method = (def. method | 'get '). toLowerCase (); app [method] (def. path, def. handler) ;};};}; you can see that she directly entered each controller file require. Then he directly acts as a constructor and transmits the app as a parameter. All of them are in this way in our controller: 'Use strict '; module. exports = function (server) {server. get ('/', function (req, res) {var model = {name: 'helloworld'}; res. render ('index', model) ;};}; here, the server is actually an app, and this is the magic of kraken.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.