Node.js Domestic MVC Framework ThinkJS Development Configuration

Keywords: Javascript Attribute JSON npm node.js

Original: Jingxiu Web page instantly pushes https://xxuyou.com Reprinted please indicate the source
Links: https://blog.xxuyou.com/nodejs-thinkjs-study-config/

This series of tutorials is in the version of ThinkJS v2.x. Official website (For example, the course is mainly about practical operation.

Define configuration files by module

thinkjs allows developers to configure their own parameters directly under src/common/config/and add js files directly. As long as the file name meets the requirements of json attribute name, the file content follows the following format:

// Add file assets.js and type the following
'use strict';
export default {
  // key: value
};

The content of the file can only be defined in a json object format. Let's look at a configuration definition for log4js:

// log4js.js
'use strict';
export default {
  appenders: [
    {
      type    : "console",
      category: "console"
    },
    // Define a logger
    {
      type                : "dateFile",                 // Log file type, using date as placeholder for file name
      filename            : "logs/",     // Log file name, you can set relative path or absolute path
      pattern             : "debug/yyyyMMddhh.txt",  // Placeholder, right behind filename
      absolute            : true,                   // Is filename an absolute path
      alwaysIncludePattern: true,       // Does the file name always contain placeholders
      category            : "logInfo"               // Logger name
    }
  ],
  levels   : {
    logInfo: "DEBUG"
  }        // Set the default display level of the logger. Logs below this level will not be output
}

Configuration files belong to static settings, which generally store settings parameters that do not change frequently (of course, the values of configuration parameters can be changed in memory, which will be explained in detail below).

In addition, configuration files export variable-defined js files in ES6 format instead of json files, which has the advantage of adding annotations beginning with //.

Carefully, you must have noticed that besides src/common/config, there is also a config folder under the src/home/module.

Generally speaking, it is reasonable to define and arrange configuration files according to their scope of action.

For example, the configurations used by all modules are more appropriate under src/common/config, while configurations used only for home modules are more appropriate under src/home/config.

When there are more configuration files, we need to pay attention to the loading order of multiple configuration files.

Configuration file loading order

This is how the official website describes the loading order of configuration files:

Default Configuration of Framework - > Framework Configuration in Project Mode - > Project Public Configuration - > Public Configuration in Project Mode - > Configuration under Module

First, ask the question: Where do these five configurations all refer to?

The first two can be omitted, which is the configuration settings of thinkjs framework itself. Usually there are no configuration parameters that our project will use.

The third and fourth are in different project creation modes (see Project Creation Mode). Introduction to ThinkJS Development of Node.js Domestic MVC Framework (Jingxiu Network) The default config configuration folder under:

# normal mode
thinkjs_normal/src/config/*
# module mode
thinkjs_module/src/common/config/*

The last one refers to the project under module mode, each module's own config, located in:

thinkjs_module/src/home/config/*

Note that multiple configuration files will eventually be loaded at thinkjs runtime and merged together (note bold text).

Therefore, when there are multiple configuration files, it is necessary to pay attention to the key of the configuration parameters (that is, the attribute name) as far as possible not to repeat, because according to the loading order, the value of the key loaded after will override the value of the key loaded first, resulting in undesirable results.

Tip: This tutorial mainly explains the development mode under the module mode.

Automatic switching configuration file

As mentioned earlier, we can place configuration files under src/common/config, either in one file for all configuration parameters or in multiple files.

There is a common scenario that every developer will encounter:

Some configuration parameters are used only when they are developed locally, while others are used only when they are run online. When development is completed and continuous integration is done, configuration parameters are uploaded and found that development parameters and online parameters are mixed together...

thinkjs provides three configuration parameter environments under src/common/config/env/. They are development configuration, production configuration and test configuration, which can save our continuous integration.

We can divide the project configuration into three parameters with the same attribute name and put them in different configuration environments. So local development is thinkjs automatic loading development configuration, and continuous integration is followed by production configuration. Is it convenient to ~?

Development and configuration

The development configuration file is: src/common/config/env/development.js

As mentioned earlier, development configurations are suitable for local development, so how does thinkjs know which environment it is now?

The answer is: defined in package.json

{
  "scripts": {
    "start": "node www/development.js",
    "compile": "babel src/ --out-dir app/",
    "watch-compile": "node -e \"console.log('<npm run watch-compile> no longer need, use <npm start> command direct.');console.log();\"",
    "watch": "npm run watch-compile"
  }
}

You can see that the scripts.start attribute defines the actual node www/development.js command that we execute when we use npm start directly.

In line with the principle of breaking the casserole to the end, see what is in this document:

var thinkjs = require('thinkjs');
var path = require('path');

var rootPath = path.dirname(__dirname);

var instance = new thinkjs({
  APP_PATH: rootPath + path.sep + 'app',
  RUNTIME_PATH: rootPath + path.sep + 'runtime',
  ROOT_PATH: rootPath,
  RESOURCE_PATH: __dirname,
  env: 'development'  // < -- This defines the running environment of the current thinkjs instance
});

// Build code from src to app directory.
instance.compile({
  log: true
});

instance.run();

:-)

Production configuration

The production configuration file is: src/common/config/env/production.js

Understanding the principle of development configuration, it is not difficult to understand the production configuration.

Using the node www/production.js command, you can tell thinkjs that the production environment is running now.

Similarly, the parameter name (attribute name) in production configuration is generally the same as that in development configuration, but with different values.

The most common connection is database connection. When developing locally, the connection is test library. In production environment, the connection is production library. Different addresses, users, passwords and library names are to be managed by operation and maintenance personnel.

Test configuration

The test configuration file is: src/common/config/env/test.js

Understanding the first two configurations, this is not difficult to understand

Using the node www/test.js command, you can tell thinkjs that the test environment is now running.

Define and use configuration files

In fact, the distribution principles and definition methods of configuration files have been introduced before, so long as they are not conflicted with the specific configuration of the system, they can be freely defined.

System Specific Configuration

Below is a list of default configuration files for thinkjs. These system-specific configurations have corresponding usage scenarios and parameter settings. Details and complete parameters are given in detail. https://thinkjs.org/zh-cn/doc/2.2/config.html#toc-f2a

src/common/config/
├── config.js  # You can place your own configuration
├── db.js  # Database Connection
├── env  # Runtime configuration, as detailed below
│   ├── development.js
│   ├── production.js
│   └── testing.js
├── error.js  # Wrong configuration
├── hook.js  # Hook configuration
├── locale  # Multilingual version configuration
│   └── en.js
├── session.js
└── view.js  # View file configuration

Custom Configuration

The general practice is to organize configuration parameters with hierarchical configuration definitions (of course, you have to put all the parameters under the root is not impossible). See the following configuration:

// development.js
'use strict';
export default {
  site_name: "",
  site_title: "",
  site_keywords: "",
  site_description: "",
  db: {  // The configuration here replaces db.js
    type   : 'mysql',
    log_sql: true, //Whether to record sql statements
    adapter: {
      mysql: {
        host    : '127.0.0.1',
        port    : '3306',
        database: '',
        user    : '',
        password: '',
        prefix  : 'thinkjs_',
        encoding: 'utf8'
      }
    }
  },
  jwt: { // Common definitions of third-party modules
    options: {
      algorithm: 'HS128',
      expiresIn: '7d'
    }
  },
  pay: {
    // Define parameters related to the online payment interface
  },
  backend: {
    // Define parameters related to the management background
  },
  home: {
    // Define parameters related to front-end websites
  },
  rest: {
    // Define parameters related to REST API
  },
  task: {
    // Define crond-related parameters
  }
};

After the configuration parameters are organized according to the hierarchy, it should be noted that when obtaining the configuration, this. config (parameters. parameters. parameters. parameters) can not go down indefinitely, as described in the following ways of reading the configuration.

Several ways of reading configuration

After the configuration file is defined, the values of configuration parameters need to be read (or set) in the special business running the project. thinkjs provides the following ways of reading according to the location of the configuration.

this.config()

This is the most frequently used read configuration method, which can be used in most locations, such as controller logic model service middleware.

// Configure development.js
let dbOpt = this.config('db');
let jwtOpt = this.config('jwt.options');

Here's one thing to note: thinkjs can only parse two layers of configuration parameters, and no parsing can be done at the level exceeded (only two layers are returned if the source code is written dead).

// Configure development.js
let jwtOpt = this.config('jwt.options');
console.log(jwtOpt);
// Read successfully, print:
// {
//   options: {
//     algorithm: 'HS128',
//     expiresIn: '7d'
//   }
// }
let jwtOptAlg = this.config('jwt.options.algorithm');
console.log(jwtOptAlg);
// Over three layers, read failure, can only read two layers of content, print:
// {
//   options: {
//     algorithm: 'HS128',
//     expiresIn: '7d'
//   }
// }
jwtOptAlg = jwtOpt['algorithm'];
console.log(jwtOptAlg);
// Correct reading mode, printing:
// HS128

think.config()

The think.config method can:

  • Read configuration parameters without considering the current location (its internal operation is similar to this.config)
  • Read configuration parameters across modules

For the former, the configuration parameters can be read more freely without thinking about the current module.

For the latter, it is very important to develop multi-module collaboration. There is only one configuration parameter, so it is impossible to replicate the same configuration to different modules. Therefore, it is necessary to "configure in one place and use in many places". So instead of thinking about "where do I read the configuration", just think about "where do I read the configuration".

// Configuration file: src/home/config/assets.js
let siteName = think.config('assets.site_name', undefined, 'home');

The second parameter of the method is undefined to avoid changing the read action to the set action.

The third parameter of the method indicates which module the configuration parameter is under. Once given this parameter, thinkjs will think that the configuration below src/home/config/is the target you need to read.

http.config()

The http.config method is essentially an alias for think.config(), which reads and sets configuration parameters.

Avoid reading parameters correctly when trampling holes

If you can't understand thinkjs design configuration file reading strategy, you will inadvertently step on the pit. Here's an example, the code speaks.

Suppose there are two configuration files, src/common/config/assets.js and src/home/config/assets.js, with the same attribute name:

// src/common/config/assets.js
export default {
  "site_title": "my site"
};

// src/home/config/assets.js
export default {
  "site_title": "my test"
};
// Two configuration parameters with the same attribute name
// Use different ways of reading
// Notice the different context objects of the config method
// Causes different results to be read
// src/home/controller/index.js
let assets = this.config('assets');
let siteTitle = assets['site_title'];
console.log('siteTitle is: ', siteTitle);
// Print:
// my test

// src/home/controller/index.js
let assets = think.config('assets', undefined, 'common');
let siteTitle = assets['site_title'];
console.log('siteTitle is: ', siteTitle);
// Print:
// my site

Understanding the order in which thinkjs configuration files are loaded will not surprise you about what happened above.

If you're too lazy to think about the difference between this.config and think.config, it's recommended that you simply use the latter, which behaves the same as the former when only the first parameter is passed in. This seems to be more conducive to code maintenance.

Dynamic modification of configuration parameters to avoid trampling pits

When the configuration parameters are read, of course, they can be dynamically modified to new values to allow subsequent processing to read new values. The dynamic modification method is also simple: the second parameter of the config method is the given new value.

let siteTitle = this.config('assets.site_title');
console.log(siteTitle);
// Print:
// my test
this.config('assets.site_title', 'test 123');
siteTitle = this.config('assets.site_title');
console.log(siteTitle);
// Print:
// test 123

The above dynamic modification methods are actually insipid. Let's take a look at the more interesting modification methods, as follows:

let siteAuthor = this.config('assets.site_author');
console.log(siteAuthor);
// Print:
// {
//   name: 'xxuyou.com',
//   email: 'cap@xxuyou.com'
// }
siteAuthor['name'] = 'cap';
siteAuthor = this.config('assets.site_author');
console.log(siteAuthor);
// Print:
// {
//   name: 'cap',
//   email: 'cap@xxuyou.com'
// }

If the code snippet above is modified, the expected effect can be achieved as follows:

let siteAuthor = think.extend({}, this.config('assets.site_author')); // The difference is here.
console.log(siteAuthor);
// Print:
// {
//   name: 'xxuyou.com',
//   email: 'cap@xxuyou.com'
// }
siteAuthor['name'] = 'cap';
siteAuthor = this.config('assets.site_author');
console.log(siteAuthor);
// Print:
// {
//   name: 'xxuyou.com',
//   email: 'cap@xxuyou.com'
// }

Regardless of where the think.extend is sacred, why modifying the variables on the left of the equals sign works the same as modifying the configuration directly?

The reason is simple:

  1. thinkjs caches configuration parameters internally.
  2. The value of the configuration parameter is an Object rather than a String.

OK~

Language pack

Language packages themselves can be described as i18n, but internationalization is rarely involved in actual development or even architecture, so here is a brief description.

src/config/locale/en.js

The default English language environment of the system defines the relevant language templates.

src/config/locale/zh-CN.js

For the sake of specifications, it is suggested to set up this language template file manually and to enable this language template by modifying the default parameter in src/common/config/local.js to zh-CN.

done~

Last article: Introduction to ThinkJS Development of Node.js Domestic MVC Framework (Jingxiu Network)
Next article: Node.js Domestic MVC Framework ThinkJS Development controller (Jingxiu Network)

Original: Jingxiu Web page instantly pushes https://xxuyou.com Reprinted please indicate the source
Links: https://blog.xxuyou.com/nodejs-thinkjs-study-config/

Posted by paulareno on Thu, 27 Dec 2018 18:36:06 -0800