Design ideas and objectives

The profile

This paper mainly introduces how to realize front-end modularization and distributed deployment scheme in the engineering front-end project under the Vue framework.

This is also a front-end architecture and engineering scheme that has been used in my department for nearly a year.

PS:

It’s a series…

This is the module refers to the business function module, not js category module. For the sake of differentiation, the js category modules are called jsModule.

This is a memoir of a real-life setting, so 1. 2. It is not the simplest implementation of a goal and can be a bit complicated

Architecture diagram

What’s the difficulty

If it is in a project, the decoupling between business and non-business logic and business components is completed, and the verification of code reference specifications is added, which can basically meet the modularization of business functions. But if the module is expected to be independently deployed, the problem becomes more complicated.

Independent deployment means:

  1. The code needs to be packaged separately
  2. The code is hosted on different servers with different domain names
  3. Different business modules may access different back-end services

This can cause some problems:

  1. It will have an impact on existing r&d processes

There was a time when NPM Run Dev would package all the code, and Webpack or some other packaging tool would take care of code splitting and loading. Now you need to package the platform and module code separately, start the platform resource service and module resource service separately, and then load the module code and execute it yourself

  1. Changes in Router and Vuex management modes

Modules are postloaded, asynchronous, and each module is responsible for its own routing and state management, which is unpredictable and pre-defined for the platform, so Router and Vuex need to be dynamically injected, but fortunately, they both support this feature

  1. Separately packaged code, which can result in code reference errors if the packaging tool is incorrectly configured to run

The packaging tool used in the project is WebPack, which registers a global variable (webpackJsonp by default) and manages the jsModule as an array. If you load another piece of code packaged in the same way, the jsModule managed by both will become messy because the jsModule references are implemented as array indexes.

  1. Module resource management

As a result of module packaging, js, CSS and other static resource files may be generated. If the chunkId concatenation of file names is expected, or if the packaging configuration changes and later resource changes are considered, the final resource list of the module will not be enumerable manually. So I’ll need the packaging tool to output a list of resources when it’s done, but the WebPack plugin is great, so don’t worry.

  1. Loading of module resources

Consider an inter-module dependency scenario: if A depends on B, how do you know that B has finished loading? Consider a scenario where modules C and D request to load the same resource at the same time. So I need to know what the module is, whether it is fully loaded, and I need a separate resource loader to avoid repeated resource requests.

  1. Module conflicts in the development environment

Consider this scenario: A system A (platform) has integrated module B (B’s resources point to the test or production environment address). How can the resources of module B be pointed to the development environment during development? (Ideally you might want to provide a clean platform, but there are always surprises.)

  1. Module function test in multiple environments

A function needs to go through: development environment > test environment > pre-release environment > production environment. Each platform and module has its own corresponding above environment. The above different processes, except the domain name is different, the code itself and its running environment does not have any difference, then how to ensure that the platform of the test environment load the module resources of the test environment? Production environment loaded production?

  1. Cross-domain problem

This is also one of the most troublesome issues to deal with. The module request actually has two parts: module resources (JS/CSS etc.) and data resources (Ajax requests). Often different modules correspond to different back-end services (b.com). When a module is integrated into a platform to run, the object that actually makes the request is not the module itself but the platform (a.com). Of course we can choose the same platform proxy, or ask the module server to trust the platform source request. Secondly, in terms of development, any form of domain name hard coding in the code is prohibited in principle. There is no record of domain name in the module, so how should the platform know the domain name requested by the data resource of the module?

  1. The module separation

For example, if the platform chooses to use AXIos to provide HTTP services, if module A references Axios and provides A global configuration, such as adding A baseUrl, the other modules will be completely destroyed. I didn’t want each module to introduce its own HTTP service, which would be messy and lead to a lot of repetitive code, and I didn’t want iframe, which would waste resources and performance, as well as introduce some layout holes. I did a partial quarantine to make sure there was no unintended AOE

  1. Other problems

In fact, there are other details, such as the automatic browser opening function after NPM run dev. I need to start the platform service and the module service separately. These are two processes and I need to make sure that the platform code is compiled, so interprocess communication is a necessity. For example, the global compile command was removed, hotreload also caused me to step on a few holes, etc…

My goal

  1. No change in r&d practices

Whether module or platform development, keep the original flavor of NPM run dev, there will be hot loading, there will be automatic browser opening. Of course, the configuration file has changed

  1. Module development without worrying about details such as how to write cross-domain code

This is a bit of bullshit, in fact, in the development process at that time, let the front brother accompany me to step on a lot of pits, this part of the treatment also experienced a big modification, of course, now work well.

  1. In the above requirements to achieve modular front-end, distributed deployment

Specific item

  1. Compilation command transformation, support platform, module code packaging, which is also a necessary step to solve the above problems
  2. Compile command integration template functionality (platform and module templates)
  3. Module management tool (client run)
  4. Added esLint rules to prohibit non-standard cross-module code references
  5. Separate HTTP services from mock services
  6. The document

And then…

  1. Module interface design
  2. Implementation of the module manager
  3. Definition and implementation of module dependencies
  4. Module, platform communication function realization
  5. Routing management
  6. State management
  7. Cross-domain request processing
  8. Revision of compilation tools
  9. Development pattern Architecture
  10. Development and testing

The above output order or structure may be adjusted

FLAG: Treat your future self with self-discipline