Modular:
A module is a file that implements a particular function. With a module, we can more easily use other people’s code and load whatever function we want. Module development needs to follow a certain set of rules, and everything goes wrong.
AMD (for browsers) : Asynchronous Module Definition It is a specification for modular development on the browser side.
Because it is not JavaScript native support, page development using AMD specification requires the corresponding library function, also known as RequireJS. In fact, AMD is the standardized output of RequireJS module definition in the promotion process.
require(['Service'],function (Service){ }); RequireJS mainly solves two problems: (1) Multiple JS files may have dependencies, and the dependent files need to be loaded into the browser earlier than the dependent files; (2) When JS is loaded, the browser will stop page rendering. The more files loaded, the longer the response time of the page will be;Copy the code
2, CMD: The Common Module Definition, CMD specification is domestic development, just as AMD has a requireJS, CMD has a browser implementation SeaJS, SeaJS to solve the same problem as requireJS, There are just differences in how modules are defined and when modules are loaded (run, parse, so to speak).
Define (function (require, exports, module) {var React = require(' React '); }); CMD advocates: (1) one module per file, so often use filename as module ID; (2) CMD advocates nearby dependency, so it is generally not written in define parameters;Copy the code
3, CommonJS (for server) Node applications are composed of modules, using the CommonJS module specification. Each file is a module, with its own independent scope, variables, methods, etc., invisible to other modules. The CommonJS specification states that within each module, the module variable represents the current module. This variable is an object whose exports property (module.exports) is the interface to the outside world. Loading a module loads the module.exports property of that module. The require method is used to load modules.
The CommonJS module has the following features: (1) all code runs in the module scope, does not pollute the global scope; (2) The module can be loaded many times, but it will only run once at the first time of loading, and then the result of running will be cached. After loading, the cache result will be read directly. For the module to run again, the cache must be cleared; (3) The order of module loading, according to the order of its appearance in the code; The module.exports property refers to the interface that the current module exports. Other files that load the module actually read the module.exports variable. Node provides an exports variable (an object, so to speak) for each module, pointing to module.exports. Var exports = module.exports; var exports = module.exports;Copy the code
This way, you can add methods to this variable when you export it. Exports.add = function (r){return math.pi *r *r}; Note: exports cannot be pointed directly at a value, as this would disconnect exports from module.exports. Such as exports = function (x) {the console. The log (x)};
A module's external interface, which is a single value, cannot be exported using exports; it must be exported using module.exports. module.exports=function(x){console.log(x); }; AMD specification and commonJS specification: 1. Similarities: both for modularity. 2. Differences: THE AMD specification is asynchronously loaded modules, allowing you to specify callback functions. The CommonJS specification loads modules synchronously, meaning that subsequent operations cannot be performed until the load is complete. Example.js: exports.name = 'Tom '; exports.age = 50; var example = require('./example.js');Copy the code
ES6 Modules are designed to be as static as possible, so that the dependencies of the module, as well as the input and output variables, can be determined at compile time. Both CommonJS and AMD modules can only determine these things at runtime. For example, a CommonJS module is an object, and you have to look for object properties when you enter it.
The modularity of ES6 is divided into export and import modules:
(1) the module of ES6 automatically opens strict mode, no matter whether you add use strict in the module head or not; (2) The module can import and export various types of variables, such as functions, objects, strings, numbers, booleans, classes, etc.; (3) Each module has its own context. Variables declared in each module are local variables and will not pollute the global scope; (4) Each module is only loaded once (singleton), if the same file under the same directory is loaded again, it is read directly from the memory; Usage: ES6 modules use the export keyword to provide an interface: export default {} export {} import modules: import a module import test from './test'Copy the code
5, the difference between the two:
The most obvious difference is that in module definition, the dependency processing is different (1), AMD advocates the dependency front, in the definition of the module should declare its dependency module (2), CMD advocates the nearby dependency, only when the use of a module to requireCopy the code
In addition, requireJS and SeaJS support each other’s writing methods. The biggest difference between AMD and CMD is that the execution time of dependent modules is handled differently, not the loading time or the way
Modular:
Why componentize? Whether front-end or back-end, are a part of the entire software system. A software product is also a product, and its development process must have a purpose. The vast majority of software products are profit-driven, and when product goals are set, there are two ways to optimize costs: reduce deployment costs and improve development efficiency.
There is a lot of research on reducing deployment costs in the industry, such as “deioE”, which is very popular in recent years. It is typical to migrate from some high cost high-performance products to open source easily replaceable product clusters, and to deploy.NET applications using Linux + Mono, avoiding the costs of Windows Server.
When it comes to componentization, the most common MVVM frameworks are React, Angular, and Vue.
The React programming mode doesn’t have to take Web standards into consideration. The migration cost is not high, and the UI layer implementation is even shielded due to its implementation mechanism. Therefore, you can see that the use of native or canvas is quite different from DOM based programming. Compatibility issues with Web Components need to be addressed when encapsulating tags, as they were before anyway. React uses the Virtual DOM, so performance is good, and everything is component, so the code is more modular and easier to reuse. The Angular 1.x release, like most frameworks/libraries of its time, had little consideration for future standards compatibility, but the redesigned version 2.0 made a lot of trade-offs and became a radical change, suddenly a thing of the future.
Reusability:
The so-called componentization, the core meaning is to extract the real reusable value of things. So what kind of things are reusable? Control 2. Basic logic functionality 3. Common styles 4. Stable business logic 5.
Basic logic functions are primarily things that are unrelated to the interface, such as helper libraries like underscore, or purely logical functions such as validations.
The reusability of common styles is also easy to recognize, so bootstrap, Foundation, semantic, and so on are popular, but they are not pure style libraries anymore, and they come with small logic packages.
The last piece, business logic. The reuse of this piece is controversial, on the one hand, many people do not agree that business logic also needs to be componentized, on the other hand, how exactly to componentize this thing, also needs to be considered.
In addition to the ones listed above, there are a large number of business interfaces, which obviously have very low reuse value and are almost non-reusable, but there are still many solutions that “componentize” them, making them “non-reusable components.”
The essential purpose of componentization is not necessarily reuse, but to improve maintainability. Just like object-oriented languages, Java is purer than C++ because it allows no exceptions. Even the main function must be written to a class, so Java is a pure object-oriented language, while C++ is not.
For a Web application of some size, there is greater administrative convenience in “componentizing” everything. When writing code, short code is obviously more readable than long code, which is why many languages advise that a method should be no more than one line, and a class should be no more than one line. In the Web front-end system, javascript is relatively well done, and now the entry-level level of people, there are very few will have a bunch of JS are written together. CSS, under the guidance of SASS, LESS and other frameworks, is also gradually developing into modularity. Otherwise, it will be very painful to write bootstrap-like CSS.
Promises and asynchronous frontend tend to handle asynchrony in the form of events, but many times in purely logical “serialization” scenarios, this approach makes logic hard to read. In the new ES specification, there are also various native asynchronous processing solutions represented by Yield, but these solutions still have significant barriers to understanding, limited popularity, and will largely remain in the hands of better-educated developers. Especially on the browser side, it should have a narrower audience than Node.
In the front end, the most widely accepted solution for handling continuous asynchronous messages is promise, and I won’t discuss its rationale or its use in business here, but what it can do within a componentized framework.
There is no front-end componentization framework that does not consider asynchronous loading, because loading is an insuperable obstacle in the front-end world and must be loaded in order to have execution. Each componentized framework cannot prevent its user scale from expanding, so solutions should be proposed at the framework level as well.
We may configure routes dynamically, or we may introduce new components into dynamically loaded routes. It is worth considering how to control the life cycle of these things, and it is good for the consistency of the programming experience if it is fully asynchronous at the framework level. The promise of all kinds of interfaces can provide more convenience in terms of maintainability and scalability.
Front-end routes Front-end routes and back-end routes are implemented in different technologies, but the principles are the same. Prior to HTML5’s History API, front-end routing was implemented using hashes, which were compatible with older browsers. It needs a # in its URI rules.
The Web service does not parse hash, which means that the Web service automatically ignores everything after #, but JavaScript can be read using window.location.hash, and the path can be read and parsed to respond to the logic of different paths.
History is a new Html5 API that allows you to manipulate the browser’s session history. Routing based on history can be the same as the path rules mentioned in the original example.
In terms of performance and user experience, the back-end route sends a request to the server every time it accesses a new page, and the server responds to the request, which is definitely delayed. The front-end routing only changes the path when accessing a new page, without network latency, which will greatly improve the user experience.