preface

After a week of hard work, I finally have time for the third record, or the same first on the overall introduction of the article

This is a continuous article, divided into the following stages, each stage will produce an article (this is the third section) :

  • Introduction and use of the entire project process and achieved and unachieved goals
  • Overall analysis of vue3.0 used in the front end and what pits we will use in the future
  • How does the NodeJS backend do strong type qualification like Java springMVC
  • How to realize automatic cluster deployment of the whole project on small server

The main idea of this article focuses on how to manage backend projects using Node, rather than as a mid-stage platform, and just provides an idea of its own. (Overall use of Java Spring ideas)

The project architecture

This thing I introduced in the previous article, here is not more to introduce, mainly a simple description, interested in the big guy can move this article to see juejin.cn/post/684490…

  • Start by looking at the overall process and see if it feels like Spring, where various layers of service entities are separated step by step from the underlying business and logic to achieve a high degree of reuse of the project
  • Then there are the decorators, which mainly decorate some of the service layers and the places that control route registration
  • Then use the MAPper layer to achieve the database mapping function, can avoid unnecessary SQL statement writing
  • Finally, static file app registration
Why did you choose this approach for an architectural project? Understanding these things as a front-end developer requires a certain amount of adaptation (except for THE TS guys), where is the advantage of this layering? I won't describe the advantages of Spring over Java, just why it is architected and some of the benefits of architecting.

Use decorators

Let’s start by comparing two pieces of code that give us an intuitive feeling

(redis) function cachable(){// If the arguments are the same, the original function is not processed. Function add(a, b) {return a + b; Function add(a, b) {add = cachable((a, b) => {return a + b; @cachable function add(a, b) {return a + b; }Copy the code

Although method 1 has been abbreviated, the main content and additional functionality of this function is still unknown at first glance, whereas method 2 is clear.

Use entities to build objects

When we are developing, we can create entity class as our data operation object. For example, when we write TS, we add the interface function of type verification, and we can customize the complex logical method of entity class to simplify the complexity of data object operation and strengthen the standardization. When writing, we can also get some normative hints and method hints, which can simplify the difficulty of operating specific objects.

A useful analogy: How do I implement data binding for an object without using a framework?

  • Under normal circumstances, the response value of the data get, set rewrite, through proxy or native method
  • Invoke the data binding method in the encapsulated entity class

Doing so simplifies the logical complexity of our code.

And entity objects and database one-to-one correspondence so that you can better understand the structure of the database. Let’s take a quick look at a simple entity class with only constructors:

export default class CodeTypes { private _id: number; private _typename: string; constructor(id: number, typename: string) { this._id = id; this._typename = typename; } get id(): number { return this._id; } set id(value: number) { this._id = value; } get typename(): string { return this._typename; } set typename(value: string) { this._typename = value; }}Copy the code

If you are interested in the configuration and registration functions of the project, you can continue to read this article. The rest of the route registration, Redis control and so on will not be described too much. Juejin. Cn/post / 684490…

Function implementation

For the basic implementation functions, such as the increase, deletion, change and check of the database here will not be too much description, for this aspect of the problem can be viewed before the template project to understand the specific process.

Online editing

The logic of online editing was mentioned earlier, where the front end passes the code to the back end, then accesses the interface, and finally the web page to get the result of editing. So what exactly does the back end accomplish? Let’s just say it in two places.

  • Get front-end code for processing:
/** * Return standard HTML page method * @route POST /code/codeOnline/setHtml * @group code online editing * @param {string} findid.formdata. required Returns * @ param {string} sendHtml. FormData. Required test * @ returns {VoidFunction} 200 - returns true * @ returns {VoidFunction} - 500 Return error */ @RouterDec.requestMapping ('/setHtml', mytype.post) Async setHtml(@RouterDec.requestParams ('String', 'findId') findId: string, @routerDec.RequestParams('String', 'sendHtml') sendHtml: string, @routerDec.Response() res: express.Response ): Promise<void> { const response = new BaseResponse<boolean>(); try { MyRedis.set(findId, sendHtml); MyRedis.exp(findId, 10); response._datas = true; response.changeType(BackType.success); } catch (e) { response._datas = false; response._msg = BaseErrorMsg.redisError; } res.json(response); }Copy the code

For those who do not understand the overall structure, please refer to the article mentioned above. Here we will see a redis storage function implemented in the function, and then the storage time is 10 seconds. After the storage is successful, the result status is returned. (return true)

So you can see that the actual implementation is actually handled when you access the web interface, so let’s see what’s being handled?

export default class CodeOnlineServices implements CodeOnlineServicesImp{ private static ThreePacksServices: ThreePacksServices = new ThreePacksServices() /** * @param {String} a code fragment * @returns {String} */ async dealVueOnlineCode(a: string): Promise<string> {' '} /** * returns the js required for generation * @param {Object} script passes in export default content * @param {Array} listObj passes in an Array of components * Private static createJs(script: object, listObj: any[]): private static createJs(script: object, listObj: any[]): String {' '} /** * Processing objects as a line of statements * @param {Object} obj passed in the Object to be processed * @param {string} name Generated Object name after processing * @returns {string} */ private static serialize(obj: object, name: string): String {' '} /** * Returns page string interception * @param {string} source Resource to be intercepted * @param {string} type Interception label type * @returns {any} Returns the interception result */ private static getSource(source: string, type: string): string { ``` } }Copy the code

DealVueOnlineCode () handles the redis cached code through both key values, and then handles the HTML back to the page to render iframe to implement our online editing.

The overall processing process is as follows:

NPM release

Before implementing the content, you need to understand some elements of NPM package distribution, and some requirements are not described here

Because the implementation is relatively special, so directly on the flow chart:

It’s a little bit more complicated, but the simple idea is to do some processing on the data and then publish it into a file.

Here because the amount of code is more, I will only entrance code out, interested in the big guy can be the last article under the source code down to see this figure

/** * Add a new Redis NPM package management cache * @param {String} path Path * @param {Object} componentsObj component NPM package Object * @returns {Promise<boolean>} */ addNewPackage(name: string, componentsObj: { [p: string]: Codes[] }, version: string, components: Components[]): Promise< Boolean > {return new Promise(async (resolve) => {try {// get base path const path = 'project/${name}'; // Add redis cache await MyRedis. Rpush ('npmPublishControl', json.stringify ({componentsObj, Path, Version, name, threePacks: Array.from(components.reduce((all, item) => { if (item.threePacks) { item.threePacks.split(',').forEach((item) => { all.add(item); }); } return all; }, new Set())).join(',') })); PublishPackageServices.npmRunFn(); resolve(true); } catch (e) { console.log(e); resolve(false); }}); }Copy the code

Finally, let’s take a look at what objects look like for the entire release process

interface NpmRedisObj {
    componentsObj: { [p: string]: Codes[] };
    path: string;
    version: string;
    name: string;
    threePacks: string;
}
Copy the code

With that information in hand, we can launch the door-to-door release process.

The next chapter forecast

Next chapter: A not trivial project practice for Vue3.0 (4) (the title will be changed to a link when the article is completed)

Main Content: As a small server, how to use Docker to build its own service cluster and realize automatic construction and deployment

Although this has nothing to do with writing code, there are still shells, configuration files, and so on.

#! /bin/bash echo $PATH IMAGE_NAME='registry.cn-hangzhou.aliyuncs.com/bymycode/vue-assemble-ui' IMAGE_VERSION=$(date "H + % Y % m % d % % m % S") echo IMAGE_NAME = $IMAGE_NAME echo '= = = = = = = = = = = = = = = = begin to create image = = = = = = = = = = = = = = = =' docker build - t $IMAGE_NAME:$IMAGE_VERSION . docker tag $IMAGE_NAME:$IMAGE_VERSION $IMAGE_NAME:latest echo '= = = = = = = = = = = = = = = = began to push the mirror = = = = = = = = = = = = = = = =' docker login - username = - password = registry.cn-hangzhou.aliyuncs.com docker push $IMAGE_NAME:$IMAGE_VERSION docker push $IMAGE_NAME:latest echo '====================OK! = = = = = = = = = = = = = = = = 'Copy the code

The source code

The following operations, including WebHooks, are done on the Gitee cloud because it is difficult to access Github. Welcome to download the source code to a little star oh

Source code address: gitee.com/beon/vue-as…

Run the NPM run start command

At the end

This content is significantly reduced compared to the second, not that I want to be lazy, but the specific project template in the previous article introduced, here is more about some implementation process, so the final final say again, interested in this process can go to see this article oh!

That’s all for this article, if you have any questions or want me to help with the development, feel free to comment on my private chat!