1. The front
I used to use require in NodeJS all the time, but now all the front ends need to use modules. I happened to see this in learning WebPack, so I’ll take a look at it
- commonjs
- amdjs
2. commonjs
First of all, make it clear that this is an internal module so you declare that all of your content is in this module, which is private variables
module.id
The module’s identifier, usually the module’s file name with an absolute path.module.filename
The file name of the module, with an absolute path.module.loaded
Returns a Boolean value indicating whether the module has finished loading.module.parent
Returns an object representing the module that called the module.module.children
Returns an array representing other modules used by this module.module.exports
Represents the output value of the module.
These are the only properties that are most useful to me: Module.exports.
Other attributes I haven’t found usage scenarios in my work yet.
You can add variables to model.exports as shown here
require('./1.js')
Copy the code
This is called model. Exports
So I wrote a simple example
index.js
exports.hello = () => { return 'hello' };
Copy the code
other.js
const other = require('./other.js');
console.log(other.hello());
console.log(module);
Copy the code
You can see the values in the properties above.
2.1 the cache
Theoretically, as long as it’s called, it’s cached.
console.log(require.cache)
Copy the code
You can see the cache and you want to clear it
delete require.cache[name]
Copy the code
2.2 loading
-
If the argument string begins with a slash, it means that a module file is loaded in an absolute path. For example, require(‘/home/ Marco /foo.js’) will load /home/marco/foo.js.
-
If the argument string begins with a “./ “, it means that a module file is loaded in a relative path (compared to where the script is currently executing). For example, require(‘./circle’) will load circ.js in the same directory as the current script.
-
If the parameter string does not start with a “./ “or”/”, it indicates that either a core module provided by default (in Node’s system installation directory) or an installed module (global or local) in each node_modules directory is being loaded.
Script, for example, / home/user/projects/foo js performed the require (‘ bar. Js) command, the Node will search the following files in turn.
- /usr/local/lib/node/bar.js
- /home/user/projects/node_modules/bar.js
- /home/user/node_modules/bar.js
- /home/node_modules/bar.js
- /node_modules/bar.js
This is designed so that different modules can localize their dependencies.
-
If the argument string does not start with a “./ “or”/” and is a path, such as require(‘example-module/path/to/file’), the location of example-module will be found first, and then the subsequent path will be found using it as an argument.
-
If the specified module file is not found, Node will try to add.js,.json, and.node to the file name before searching. .js files are parsed as text JavaScript script files,.json files are parsed as json text files, and.node files are parsed as compiled binary files.
-
To get the exact filename of the require command to load, use the require.resolve() method.
The above is excerpted from ruan yifeng’s blog, know these may not have what use, you do not write disorderly actually use not to.
2.3 scope
I did a simple experiment that proved one thing: The CommonJS scope was completely isolated, and neither internal nor external changes affected the output
other.js
let number = 1;
setTimeout(() => { number = 2 }, 3000);
setInterval(() => {
console.log(number);
}, 1000)
exports.number = number;
Copy the code
index.js
var other = require('./other.js');
setInterval(() => {
other.number = 3;
console.log('index', other.number);
}, 1000);
Copy the code
Changing either the internal or external values does not affect the output.
2.4 global
One question is how do the two modules communicate with each other?
In general, the two modules should remain independent and should not be linked, but there are exceptions
So you can use global
global.xxxx
Copy the code
3. AMD
AMD is an Asynchronous Module Definition. It is a specification for modular development on the browser side
This is one of the rules used by some early JavaScript frameworks
Create a module called “alpha” using require, exports, and a module called “beta” :
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) { exports.verb = function() { return beta.verb(); //Or: return require("beta").verb(); }});Copy the code
call
define(["alpha"], function (alpha) { return { verb: function(){ return alpha.verb() + 2; }}; });Copy the code
That’s the simple thing to call, but I didn’t test anything else because I didn’t want to use the old framework again, just to make a comparison.
AMD && COMMONJS comparison
I think commonJS is a better way to declare a variable.
The code structure looks a little more comfortable, but the main difference is not here.
Advantages: server-side module reuse, NPM module packages, there are nearly 200,000.
Disadvantages: The loading module is synchronous, and the following operations can be performed only after the loading is complete. That is, when the module is needed, loading the module now and using it now is slow, but also causes performance, availability, debugging, and cross-domain access problems. Node.js is mainly used for server programming. Loaded module files are generally stored in the local hard disk, which is relatively fast to load without considering the asynchronous loading mode. Therefore,CommonJS specification is suitable. However, this is not suitable in a browser environment where synchronization means blocking loading and browser resources are loaded asynchronously, hence the AMD CMD solution.
AMD
Advantages: Asynchronously loading modules in the browser environment; Load multiple modules in parallel;
Disadvantages: high development cost, difficult to read and write code, semantics of module definition is not smooth; Does not accord with the general modular thinking, is the realization of a compromise;
But now it doesn’t really matter which front-end you use, webPack actually supports it, it just depends on which one you use more easily.
I haven’t tried whether NodeJS supports AMD or not..
5. CMD
In fact and AMD similar, only the details of the difference, different framework implementation of the different implementation, did not look closely
SeaJS, RequireJS
7. UMD
UMD is called the Universal Module Definition. It also follows the trend towards a big front end, which allows the same code module to run at run time or compile time in projects using CommonJs, CMD or even AMD. In the future, the same JavaScript package running on the browser side, the server side, and even the APP side will only need to follow the same script.
This is the ability to bring commonJS & CMD AMD together, as seen in webpack configuration, supporting UMD means that these specifications are supported.
8. es6
The keyword export allows the contents of the ESM to be exposed to other modules
other.js
export function aa() { console.log('aa') };
export function bb() { console.log('bb') };
Copy the code
index.js
import { aa,bb } from './other.js'
Copy the code
8.1 Promise features
import('./other.js').then(()=>{ console.log('other.js is loaded dynamically'); }); async function cc() { const other = await import('./other.js'); . }Copy the code
Let’s do it another way
if(condition) {
import("./a.js").then...
}
else {
import("./b.js").then...
}
Copy the code
This means that all promise functions can be used with import.
Promise.all([
import("./a.js"),
import("./b.js"),
import("./c.js")
]).then((a,b,c) => {})
Copy the code
Take full advantage of parallelism
8.2 Dynamic Import
Other specifications can also be dynamically imported, but I don’t know if they support regex.
async function test(p) {
return import(p)
}
Copy the code
This allows you to import something dynamically. If you need plug-ins, put them in a directory and import them dynamically is a good choice.
But there’s a problem with that in Webpack, it packs all the packages in the entire computer, because it doesn’t know what you’re passing in, like if you want to be fully dynamic, you’re reading the value from the database.
So narrow it down.
import('./module/' + p);
Copy the code
Originally tested the regular representation for a long time, then found himself stupid.
8.3 scope
A little bit more simple
a.js
export let c = 2;
setInterval(() => {
console.log(c);
})
Copy the code
b.js
import c from './module/a';
c = 3;
Copy the code
The output will always be 2
But if I change it
let c = 2;
export { c };
setInterval(() => {
console.log(c);
})
Copy the code
It’s always going to be 3
But here’s where I get confused
import('./module/1.js').then(({ c }) => { console.log(1, c); c = 4; import('./module/1.js').then(({ c }) => { console.log(2, c); })})Copy the code
He keeps putting out 2
I did not get an answer for a long time, I can only think about the difference between deep copy and shallow copy.
This point is expected to be solved in the follow-up study.
On the whole
- dynamic
import()
Provide apis based on promises, you can use any Promise you haveimport()
Follow ES module rules: singletons, matching characters, CORS, etc
9. end
Javascript.ruanyifeng.com/nodejs/modu…
Github.com/amdjs/amdjs…
www.jianshu.com/p/386916c73…
Blog.csdn.net/ixygj197875…
Webpack.js.org/api/module-…