Writing in the front
JavaScript was developed to solve basic form validation problems and basic page interaction. The code was very simple and there were no modular concepts or problems. But with the development of Ajax, the Web has entered the 2.0 era, and JavaScript has become a very widely used language.
At this time, JS, as an embedded language, has shown its disadvantages. Without an authoritative specification, the problem is always to be solved. In the decades of front-end development, many JS specifications have been generated along the trend.
Front-end modularization
A, functions,
In the earliest JS, to achieve modular development, the simplest is function, because function can form a relatively closed space, through the function to achieve simple modularization is also the earliest solution
function model1 = {
}
function model2 = {
}
Copy the code
Disadvantages:
1. Global scope of pollution 2. High maintenance cost (naming conflicts are easy) 3Copy the code
Second, the object
Objects can contain properties and methods, acting as a container, and we can write the code of each module into an object to achieve modularity
var model1 = {
age: 11,
say() {
console.log(age)
}
}
var model2 = {
age: 15,
say() {
console.log(age)
}
}
Copy the code
disadvantages
External can modify module internal state, can modify a certain attribute of each module, there are considerable security risksCopy the code
Self-executing functions
IIFE(Immediately Invoked Function Expression), which is the self-executing function, creates a “private” namespace by defining an anonymous function. The variables and methods in the namespace do not corrupt the global namespace
Var module = (function(){var age = 11 var say = function(){console.log(age)} return {say}; var module = (function(){var age = 11 var say = function(){console.log(age)} return {say}; }) (); module.say(); //11 console.log(module.age) //undefinedCopy the code
disadvantages
External cannot access internal private variablesCopy the code
Fourth, the commonJs
The front-end really proposed the concept of modularity, is from the birth of commonJs, because JS as an embedded language, processing page logic and interaction, even without modularity can run, there is no problem, but the server must have the concept of modules. Therefore, the development of commonJs is related to NodeJS, especially in recent years nodeJS is more and more widely used, after NPM rules the whole front-end, commonJs specification is known to everyone.
1. Define modules
According to the CommonJS specification, a single file is a module. Each module is a separate scope, that is, variables defined inside the module cannot be read by other modules unless they are defined as properties of the Global object
2. Module output
The module has only one export, the Module.exports object, into which we need to put what the module wants to export
3. Load the module
The module is loaded using the require method, which reads a file and executes, returning the module.exports object inside the file
// model1.js
var age = 11
function say(){
console.log(age);
}
module.exports = {
say
}
// index.html
var wu = require('./index.js');
console.log(wu.say)
Copy the code
4, strengths,
The problem of dependency and global variable pollution is solved
5 and disadvantages
1. Synchronous loading
CommonJS loads modules synchronously. On the server side, the module files are stored on local disk and are very fast to read, so this should not be a problem. However, in the browser side, CommonJS is not suitable for loading browser-side modules due to network reasons. The reasonable solution is to use asynchronous loading.
2. The browser is unavailable
Fifth, AMD
AMD is an Asynchronous Module Definition.
The CommonJS specification mainly serves NodeJS on the server side, which loads module files without delay, but on the browser it is quite different. AMD is one of the specifications for implementing modular solutions in the browser hosting environment.
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.
The official website address is not available, you can download it directly from this address
Requirejs.org/docs/releas…
1. Introduce dependencies
<script src="js/require.js" data-main="./main"></script>
Copy the code
2. Module definition
Defined by the define method, in the DEFINE API:
Id: module name, or the name of the specified script requested by the module loader;
Dependencies: an array of modules that define modules. Defaults to [” require “, “exports”, “module”]
Factory: Initializes the function or object to be executed for the module. If it is a function, it should be executed only once. If it is an object, the object should be the output value of the module;
// hello.js define('hello', function (x,y){var add = function (x,y){console.log(x, y){1, 2 return x+y; }; Return {add: add}; });Copy the code
3. Module introduction
The require() function takes two arguments
The first argument is an array representing the dependent module
The second argument is a callback function that will be called after all the modules specified in the previous page have been successfully loaded. Loaded modules are passed to the function as arguments, so they can be used inside the callback function
// main.js
require.config({
'baseUrl': './js',
'paths': {
'hello': './hello'
}
})
define('main', function() {
require(['hello'], function(hello) {
console.log(hello.add(1, 2)) // 3
})
})
Copy the code
The require() function is asynchronously loaded when loading dependent functions, so that the browser does not lose response, and it specifies a callback function that will not run until all previous modules have been successfully loaded.
Six, CMD
CMD is called Common Module Definition and is the output of a modularity solution popularized by Sea-js. For CMD define, id, deps and factory are supported, but it is recommended to accept factory as an entry and then execute it with three parameters: require, exports and module:
1. Define modules
Require is a parameter that can be imported into other modules;
Exports can export some properties and methods in modules.
A module is an object that stores properties and methods associated with the current module.
Define (function(require, exports, module) {// each function exports.add = function(x, y) {return x + y; }});Copy the code
2. Reference modules
define(function(require, exports, module) { var hello = require('hello'); The console. The log (hello. Add (2, 3)); // exports.init = function init() {console.log('init'); }});Copy the code
3. HTML calls
<script SRC ="./js/ sea-.js "></script> <script> seajs.config({base: './js', // subsequent references based on this path alias: Hello: './js/hello.js'},}); Seajs.use ("./main.js", function(main) {main.init(); seajs.use("./main.js"); // init }); </script>Copy the code
4, AMD and CMD differences
There are many online versions of the difference between the two, which generally mean the same thing:
AMD advocates dependency preloading. When defining a module, it is necessary to declare its dependent module. CMD advocates nearby dependency, and requires only when a module is usedCopy the code
So at this point, there’s not much difference in performance. Since the speed of page rendering is most affected by the loading speed of resources, since both are preloaded, the loading time of module resources is the same (network conditions are the same).
Seven, UMD
UMD stands for Universal Module Definition. Since CommonJs is as popular as THE AMD style, a specification is needed that can unify browser-side and non-browser-side modular solutions.
Now the source code of the mainstream framework is using the UMD specification, because it can be compatible with both browser side and Node.
UMD implementation:
Check whether AMD is supported (define exists). If AMD exists, load the module.
Then check whether the node.js module format is supported (whether exports exist). If yes, use node.js module format.
If neither exists, the module is exposed globally (window or global);
Global object mount properties
(function(root, factory) {console.log(' no module environment, directly mount on the global object ') console.log(factory()) root.umdModule = factory(); }(this, function() {return {name: 'I am a umD module'}}))Copy the code
We write factory as an anonymous function that uses IIFE to execute the factory function. The returned object is assigned to root.umdModule, where root refers to the global object this, which may be window or global, depending on the runtime environment.
Compatible with AMD environment
(function(root, factory) {if (typeof define === 'function' && define. Amd) {// If (typeof define === 'function' && define. Amd) {// If (typeof define === 'function' && define. Else {console.log(' there is no module environment, such as require.js') define(factory)} else {console.log(' there is no module environment, such as require.js') ') root.umdModule = factory(); }}(this, function() {return {name: 'I am a umD module'}}))Copy the code
Compatible with commonJs and CMD
(function(root, Factory) {if (typeof Module === 'object' && typeof Module.exports === 'object') {console.log(' commonJS module specification, ') Nodejs environment ') module.exports = factory(); } else if (typeof define === 'function' && define.amd) {console.log(' is amd module specification, Js ') define(factory)} else if (typeof define === 'function' && define.cmd) {console.log(' is CMD module specification, Module.exports = factory()})} else {console.log(' no module environment, no module environment ') ') root.umdModule = factory(); }}(this, function() {return {name: 'I am a umD module'}}))Copy the code
How to use UMD for jQuery module:
(function (factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else if (typeof module === 'object' && module.exports) { // Node/CommonJS module.exports = function( root, jQuery ) { if ( jQuery === undefined ) { // require('jQuery') returns a factory that requires window to // build a jQuery instance, we normalize how we use modules // that require this pattern but the window provided is a noop // if it's defined (how jquery works) if ( typeof window ! == 'undefined' ) { jQuery = require('jquery'); } else { jQuery = require('jquery')(root); } } factory(jQuery); return jQuery; }; } else { // Browser globals factory(jQuery); } }(function ($) { $.fn.jqueryPlugin = function () { return true; }; }));Copy the code
Vue source code UMD specification:
(function (global, factory) {// Follow the UMD specification typeof exports === 'object' &&typeof Module! == 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = global || self, global.Vue = factory()); }(this, function () { 'use strict'; Function Vue(options) {// We can't call Vue(options) directly, we can only create instance if (! (this instanceof Vue) ) { warn('Vue is a constructor and should be called with the `new` keyword'); } this._init(options); } return Vue })Copy the code
Es6 module specification
The modular development of the front end was so complex that the TC39 committee, the drafters of the ECMAScript standard, could no longer sit on their hands and roll out ES2015 Modules (import, export) and finally the ES6 modular specification.
The imported value is also a read-only immutable object, unlike CommonJS, which is an in-memory copy. Take a look to see how ES6 has advantages over CommonJS.
CommonJs code
Var counter = 3; function incCounter() { counter++; } module.exports = { counter: counter, incCounter: incCounter, }; Var mod = require('./lib'); console.log(mod.counter); // 3 mod.incCounter(); console.log(mod.counter); // 3 var mod2 = require('./lib'); console.log(mod2.counter); / / 3Copy the code
Why are they all 3’s?
The CommonJS specification is a module specification for dynamically loaded, copy-value object execution. Each module is dynamically pulled and copied at run time as it is used. The module definition is unique, but there are as many copies as there are references. So, different runtime objects are generated for different require calls.
// lib.js var counter = 3; function incCounter() { counter++; } module.exports = { get counter() { return counter }, incCounter: incCounter, }; // main.js var mod = require('./lib'); console.log(mod.counter); // 3 mod.incCounter(); console.log(mod.counter); / / 4Copy the code
Why is it okay to add a getter function?
This is due to the CommonJS copy mechanism. Exports of module. Exports of module. Exports of module. Exports of module. No matter how many times incCounter is executed, it’s not the counter variable of the output object that changes.
When the getter property is defined, it points to the counter variable contained in the closure of the incCounter method as part of the output module object.
ES6 modular
/** define module hello.js **/ var age = 10; var add = function (a, b) { return age + a + b }; export { age, add }; /** reference module **/ import {age, add} from './js/hello.js'; function test() { console.log(age) return add(20, age); } console.log(test())Copy the code
In the ES6 module specification, there are only two keywords export and import.
You can also use the default keyword
/** define module hello.js **/ var age = 10; var add = function (a, b) { return age + a + b }; export default { age, add }; /** reference module **/ import hello from './js/hello.js'; function test() { console.log(hello.age) return hello.add(20, hello.age); } console.log(test())Copy the code
The ES6 module specification differs from the CommonJS specification:
(1) ES6 module specification is parsing (parsing is not compiled) static load, runtime dynamic reference, all referenced out of the module object are pointing to the same module object. Lib modules declared above using the CommonJS specification do not have counter ambiguity at all if they are declared using the ES6 module specification.
(2) The CommonJS specification is used to dynamically load and copy value objects at runtime. Each referenced module object is a separate object.
Write in the last
Front-end modular there are so many standards, why we use so little actual development, because later out of the Webpack this artifact, modular programming needs to do for us to solve.
Webpack implements a module mechanism of its own so that both the Require syntax of CommonJS modules and the import syntax of ES6 modules can be parsed and converted into runnable code for a given environment. With the popularity of webpack packaging tools and ES6 syntax in widespread hands, subsequent developers have less and less awareness of AMD CMD.
Refer to the link
https://juejin.cn/post/6844903927104667662
https://zhuanlan.zhihu.com/p/55407719
https://www.cnblogs.com/dolphinX/p/4381855.html
https://juejin.cn/post/6844903848511799303
Copy the code
Public account: Little Jerry has something to say