In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces "what is the CommonJS specification". In the daily operation, I believe that many people have doubts about what is the CommonJS specification. The editor consulted all kinds of materials and sorted out a simple and easy-to-use method of operation. I hope it will be helpful to answer the doubts about "what is the CommonJS specification?" Next, please follow the editor to study!
one。 What is modularization?
In many development situations, we all know to use modular development, so why use it?
In fact, the ultimate goal of modular development is to divide the program into small structures.
Writing your own logic code in this structure has its own scope and will not affect other structures.
This structure can export the variables, functions, objects, etc. that you want to expose to its structure for use.
You can also import variables, functions, objects, etc., from another structure in some way.
The structure mentioned above is the module.
The process of dividing the development program according to this structure is the process of modular development.
II. JavaScript design defects
In the early days of web development, because JavaScript was only a scripting language and could only do some simple form validation or animation implementation, it still had a lot of defects, such as:
The problem of variable scope defined by var
JavaScript's object-oriented cannot use class like regular object-oriented languages.
In the early days, there was no modularization problem in JavaScript, so there was no corresponding modular solution.
But with the rapid development of front-end and JavaScript, JavaScript code becomes more and more complex.
The emergence of ajax and the separation of front-end and front-end development means that after the back-end returns data, we need to render the front-end page through JavaScript.
With the advent of SPA, front-end pages become more complex: a series of complex requirements, including front-end routing, state management, and so on, need to be implemented through JavaScript
Including the implementation of Node, JavaScript to write complex back-end programs, no modularization is a fatal injury
Therefore, modularity has become a very urgent need for JavaScript:
But JavaScript itself, it was not until ES6 (2015) that it launched its own modularization scheme.
Before that, in order to make JavaScript support modularization, many different modularization specifications emerged: AMD, CMD, CommonJS, etc.
At this point, we understand why modular development is needed.
What problems will it bring if there is no modularization?
three。 There is no problem of modularization
When we are faced with a large front-end project in a company, it is usually developed by multiple people and different business logic is divided into multiple folders.
2.1 there are no disadvantages brought by modularization to the project.
Suppose there are two people, Xiao Hao and Xiao Hong, developing a project.
The directory structure of the project is like this
Bar.js file developed by Xiaohao
Var name = "Xiaohao"; console.log ("bar.js----", name)
Baz.js file developed by Xiaohao
Console.log ("baz.js----", name)
The foo.js file developed by Xiao Hong
Var name = "Xiao Hong"; console.log ("foo.js----", name)
The reference path is as follows:
Finally, when I went to execute it, I found the result of the execution:
When we see this result, some friends may be surprised, isn't the baz.js file written by Xiao Hao? Why did you output Xiao Hong's name?
Investigate the reason, we found that, in fact, JavaScript is not modular concept (at least so far has not used the ES6 specification), in other words, each .js file is not an independent module, no scope of its own, so the variables defined in the .js file can be shared elsewhere, so Xiaohao development of baz.js inside the name, in fact, access is Xiao Hong re-declared.
But the downside of sharing is that other collaborators on the project can change them at will, which is obviously not what we want.
2.2 IIFE addresses early modularity issues
So, with the development of the front end, modularity becomes essential, so how is it solved in the early days?
In the early days, because the function had its own scope, you could use an immediate function call expression (IIFE), that is, a self-executing function, with the variable to be used by the outside world as the return result of the function.
Xiaohao-- bar.js
Var moduleBar = (function () {var name = "Xiaohao"; var age = "18"; console.log ("bar.js----", name, age); return {name, age,};}) ()
Xiaohao-- baz.js
Console.log (baz.js----, moduleBar.name); console.log (baz.js----, moduleBar.age)
Xiao Hong-foo.js
(function () {var name = "Xiao Hong"; var age = 20; console.log ("foo.js----", name, age);}) ()
Let's take a look at the output after the solution, and the original call order remains the same.
However, this brings about new problems:
I must remember the name of the object returned in each module in order to use it correctly in the use of other modules.
The code is disorganized, and the code in each file needs to be wrapped in an anonymous function.
In the absence of appropriate specifications, everyone and every company may be arbitrarily named, or even have the same module name.
Therefore, there is an urgent need for a unified specification to solve these defects, so the CommonJS specification came out.
III. Node modular development-- CommonJS specification
3.1 CommonJS specification features
CommonJS is a specification that was originally proposed for use outside the browser and was named ServerJS at the time, but was later modified to the CommonJS specification to reflect its extensiveness.
Node is a representative server-side implementation of CommonJS.
Browserify is an implementation of CommonJS in the browser.
Webpack Packaging tool has support and transformation for CommonJS
It is precisely because CommonJS is supported and implemented in Node that it has the following characteristics
Each js file in Node is a separate module
This module contains the core variables of the CommonJS specification: exports, module.exports, require
Use core variables for modular development
There is no doubt that the core of modularization is export and import, which is implemented in Node:
Exports and module.exports can be responsible for exporting the content in the module.
The require function can help us import content from other modules (custom module, system module, third-party library module).
3.2 CommonJS with Node modular development assumes that there are now two files:
Bar.js
Const name = "time House"; const age = 18; function sayHello (name) {console.log ("hello" + name);}
Main.js
Console.log (name); console.log (age)
After performing the node main.js, you will see
This is because the variable name is not found in the current main.js module
This is significantly different from what we saw earlier, because each js file in Node is a separate module.
So if you want to access the bar.js variable in another file
Bar.js needs to export the variables, functions, objects, etc., that you want to expose.
Main.js imports desired variables, functions, objects, and so on from bar.js.
3.3 exports Export
Exports is an object, we can add many attributes to this object, and the added attributes will be exported.
Bar.js file export:
Const name = "time House"; const age = 18; function sayHello (name) {console.log ("hello" + name);} exports.name = name; exports.age = age; exports.sayHello = sayHello
Main.js file import:
Const bar = require ('. / bar'); console.log (bar.name); / / console.log (bar.age); / / 18
The following points should be noted:
The bar variable in main.js is equal to the exports object
Bar = exports
So we use variables in the exported file, such as name,age, through bar.xxx
Require is actually a function, and the return value is an object, and the exports object whose value is "Export File"
3.4 from the perspective of memory, bar and exports are the same object.
In Node, there is a special global object, in fact, exports is one of them.
If you no longer export a variable in the form of exports.xxx in a file, exports is actually an empty object.
Reference relationship between modules
When we import require in main.js, it automatically finds the special global object exports and assigns the execution result of the require function to bar.
Bar and exports point to the same reference (same reference address)
If we find a variable on exports, it will be put on the bar object, which is why we can read the variable we want from bar.
For further argument, bar and exports are the same object:
Let's join the timer and have a look
So to sum up, the essence of implementing the CommonJS specification in Node is the reference assignment of objects (shallow copy essence).
Assign a reference to the exports object to the bar object.
The essence of CommonJS specification is the reference assignment of objects.
What is 3. 5 module.exports?
But we often use module.exports to export things in Node, and we also encounter interview questions like this:
What is the relationship or difference between module.exports and exports?
3.6 require details
Require is essentially a function that can help us import objects imported in a file (module).
The lookup rule https://nodejs.org/dist/latest-v14.x/docs/api/modules.html#modules_all_together of require
3.7 loading order of require modules
Conclusion 1: when the module is introduced for the first time, the js code in the module will be run once
/ / aaa.js const name = 'coderwhy'; console.log ("Hello aaa"); setTimeout () = > {console.log ("setTimeout");}, 1000); / / main.js const aaa = require ('. / aaa')
The code in aaa.js will be run once when introduced
Conclusion 2: when the module is introduced many times, it will be cached and will only be loaded (run) once.
/ / main.js const aaa = require ('. / aaa'); const bbb = require ('. / bbb'); / / aaa.js const ccc = require (". / ccc"); / / bbb.js const ccc = require (". / ccc"); / / ccc.js console.log ('ccc loaded')
The code in ccc runs only once.
Why is it only loaded and run once?
Each module object module has one property: loaded
False indicates that it has not been loaded yet
Indicates for true that it has been loaded
Conclusion 3: if a loop is introduced, what is the loading order?
If the reference relationships of the following modules appear, what is the loading order?
This is actually a kind of data structure: graph structure.
In the process of traversing the graph structure, there are depth first search (DFS, depth first search) and breadth first search (BFS, breadth first search).
Node uses a depth-first algorithm: main-> aaa-> ccc-> ddd-> eee-> bbb.
The introduction relationship of multiple modules
IV. Module.exports
4.1 what is really exported is module.exports
The following is an analysis of the CommonJS specification through Wikipedia:
There is no concept of module.exports in CommonJS.
But in order to export modules, Module classes are used in Node, and each module is an instance module of Module
So what is really used for export in Node is not exports at all, but module.exports.
Exports is just an object on module
But why can exports also be exported?
This is because the exports property of the module object is a reference to the exports object
Equivalent to bar in module.exports = exports = main (CommonJS internal encapsulation)
4.2 what is the relationship or difference between module.exports and exports?
Contact: module.exports = exports
Further prove that module.exports = exports
/ / bar.js const name = "time House Hao"; exports.name = name; setTimeout (() = > {module.exports.name = ""; console.log ("after 1s in bar.js", exports.name);}, 1000); / / main.js const bar = require (". / bar"); console.log ("main.js", bar.name); setTimeout ((_) = > {console.log ("after 1s in main.js", bar.name) }, 2000)
In the above code, as long as you modify the properties in the exports object in bar.js, the result of the export will change, because even if the real export is module.exports, and module.exports and exports are both the same reference address, if you change the properties of one of them, the other will change accordingly.
Note: the core of the real exported module content is module.exports, just to implement the specification of CommonJS. It just so happens that module.exports uses the same reference to the exports object.
Difference: there are two points
So if the code is modified like this:
Module.exports has nothing to do with exports.
No matter how exports is changed, it will not affect the final export result.
Because the form module.exports = {xxx} creates a new memory space in the heap memory and generates a new object, it replaces the export of the previous exports object.
Then it means that the object imported by require is a new object.
Illustrate the difference between module.exports and exports
After talking about the difference between the two, let's take a look at the following two examples to see if you have really mastered the use of module.exports
4.3 exercises on module.exports
Exercise 1: the exported variable is a value type
/ / bar.js let name = "time House"; setTimeout () = > {name = "123123";}, 1000); module.exports = {name: name, age: "20", sayHello: function (name) {console.log ("Hello" + name);},}; / / main.js const bar = require (". / bar"); console.log ("main.js", bar.name) / / main.js time House Xiaohao setTimeout (() = > {console.log ("after 2s in main.js, bar.name); / / time House after 2s in main.js}, 2000)
Exercise 2: the exported variable is a reference type
/ / bar.js let info = {name: "time House",}; setTimeout () = > {info.name = "123123";}, 1000); module.exports = {info: info, age: "20", sayHello: function (name) {console.log ("Hello" + name);},}; / / main.js const bar = require (". / bar"); console.log ("main.js", bar.info.name) / / main.js time House Hsiao setTimeout (() = > {console.log ("after 2s in main.js, bar.info.name); / / after 2s in main.js 123123}, 2000)
Judging from the main.js output, the result of the name variable modified by the timer does not affect the imported result in main.js.
Because name is a value type, a basic type, once defined, put its attribute value in the memory of module.exports (exercise 1)
Because info is a reference type, the reference address of info is stored in module.exports, so the variable changed by the timer will affect the result of main.js import (exercise 2)
5. The loading process of CommonJS
The process by which the CommonJS module loads the js file is loaded at run time and synchronized:
Runtime loading means that the js engine loads the module during the execution of the js code
Synchronized means that the following code will not be executed until a file is loaded.
Const flag = true; if (flag) {const foo = require ('. / foo'); console.log ("output this code after waiting for the require function to be executed");}
What CommonJS exports through module.exports is an object:
Exporting an object means that references to that object can be assigned to other variables in other modules
But in the end, they all point to the same object, so a variable modifies the properties of the object, and everything will be modified.
VI. The essence of CommonJS specification
The essence of CommonJS specification is the reference assignment of objects.
At this point, the study of "what is the CommonJS specification" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.