1. the front
It used to be nodejs Use in require
, Now all front ends need to use modules , Just learning webpack I saw this piece in the picture , So learn by the way
- commonjs
- amdjs
2. commonjs
First, make it clear that this is an internal module , All your content is in this module , That is, private variables
module.id
The ID of the module , Usually the module filename with absolute path .module.filename
The file name of the module , With an absolute path .module.loaded
Returns a Boolean value , Indicates whether the module has finished loading .module.parent
Return an object , Indicates the module calling the module .module.children
Returns an array , Indicates other modules to be used in this module .module.exports
Indicates the output value of the module .
These attributes are only... For me module.exports
Most useful .
Other properties I haven't found usage scenarios in my work yet .
You can go to model.exports Add variables , Here's the code
require('./1.js')
Copy code
In fact, it's called model.exports
So I simply wrote a list
index.js
exports.hello = () => { return 'hello' };
Copy code
other.js
const other = require('./other.js');
console.log(other.hello());
console.log(module);
Copy code
So you can see the value in the above attribute .
2.1 cache
In theory, just call , It will cache .
console.log(require.cache)
Copy code
You can see the cache , Want to get rid of
delete require.cache[name]
Copy code
2.2 load
-
If the parameter string is “/” start , It means that a module file in absolute path is loaded . such as ,
require('/home/marco/foo.js')
Will load/home/marco/foo.js
. -
If the parameter string is “./” start , It means that the load is a relative path ( Compared to the current location where the script is executed ) Module files for . such as ,
require('./circle')
Will load... From the same directory as the current scriptcircle.js
. -
If the parameter string does not use “./“ or ”/“ start , It means that a core module provided by default is loaded ( be located Node In the system installation directory ), Or one at all levels node_modules Installed module for directory ( Global or local installation ).
for instance , Script /home/user/projects/foo.js
Yes require('bar.js')
command ,Node The following files will be searched 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
The purpose of this design is , This enables different modules to localize the dependent modules .
-
If the parameter string does not use “./“ or ”/“ start , And it's a path , such as
require('example-module/path/to/file')
, You will findexample-module
The location of , Then take it as a parameter , Find the next path . -
If the specified module file is not found ,Node Will try to add
.js
、.json
、.node
after , Search again ..js
It will be in text format JavaScript Script file parsing ,.json
The document will use JSON Format text file parsing ,.node
The file will be parsed as a compiled binary . -
If you want
require
The exact filename the command loads , Userequire.resolve()
Method .
The above is an excerpt from Ruan Yifeng's blog , It may not be useful to know this , If you don't Scribble, you won't use it .
2.3 Scope
I did a simple experiment , Proved one thing ,commonjs
The scope is completely isolated , Neither internal nor external changes can affect the output
other.js
let number = 1;
setTimeout(() => { number = 2 }, 3000);
setInterval(() => {
console.log(number);
}, 1000)
exports.number = number;
Copy code
index.js
var other = require('./other.js');
setInterval(() => {
other.number = 3;
console.log('index', other.number);
}, 1000);
Copy code
Whether it's changing internal values , Or change the external value , Will not affect the output .
2.4 global
One problem is how to communicate between the two modules ?
In general, the two modules should remain independent , Should not be contacted by , But there are inevitable special circumstances
So you can use global
global.xxxx
Copy code
3. AMD
AMD namely
Asynchronous Module Definition
, The Chinese name is “ Asynchronous module definition ” It means . It is a specification for modular development on the browser side
This belongs to some of the early JavaScript The rules used by the framework
Create a file called "alpha" Module , Used require,exports, And called "beta" Module :
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
exports.verb = function() {
return beta.verb();
//Or:
return require("beta").verb();
}
});
Copy code
call
define(["alpha"], function (alpha) {
return {
verb: function(){
return alpha.verb() + 2;
}
};
});
Copy code
This is the simple call , But I didn't test anything else , Because I don't want to use the previous framework , Just make a comparison .
4. AMD && COMMONJS contrast
First of all, it must be in usage , I think commonjs Better , It's equivalent to declaring a variable directly .
The code structure looks more comfortable , But the main difference is not here .
advantage : Server side module reuse ,NPM There are many modules in the package , There are nearly 20 m .
shortcoming : The load module is synchronous , The following operations can only be performed after loading , That is, when the module is to be used , Load and use now , Not only the loading speed is slow , It also leads to performance 、 Usability 、 Debugging and cross domain access .Node.js Mainly used for server programming , The loaded module files are generally stored on the local hard disk , It's faster to load , Don't worry about asynchronous loading , therefore ,CommonJS Norms are more applicable . However , This doesn't work in a browser environment , Synchronization means Blocking Load , Browser resources are loaded asynchronously , So there is AMD CMD Solution .
AMD
advantage : Load modules asynchronously in the browser environment ; Load multiple modules in parallel ;
shortcoming : High development cost , It is difficult to read and write the code , The semantics of module definition is not smooth ; Not in line with the general modular way of thinking , It's a compromise ;
But now it doesn't matter which one you use in the front end ,webpack In fact, they all support , It just depends on which one you use better .
I never tried. nodejs Do you support amd
..
5. CMD
Actually sum AMD similar , It's just the difference in details , Different implementations of different frameworks , Don't look
SeaJS, RequireJS
7. UMD
UMD It's called the generic module definition specification (Universal Module Definition). It is also born with the trend of big front end , It can use the same code module at runtime or compile time CommonJs、CMD Even AMD In the project . The future is the same JavaScript The package runs on the browser side 、 The service area even APP All you need to do is follow the same script .
This is what can commonjs
& cmd
amd
Get together , stay webpack You can also see , Support umd
This means that these specifications support .
8. es6
keyword export
Allows you to ESM Expose the contents of to other modules
other.js
export function aa() { console.log('aa') };
export function bb() { console.log('bb') };
Copy code
index.js
import { aa,bb } from './other.js'
Copy code
8.1 Promise characteristic
import('./other.js').then(()=>{
console.log('other.js is loaded dynamically');
});
async function cc() {
const other = await import('./other.js');
......
}
Copy code
Another way
if(condition) {
import("./a.js").then...
}
else {
import("./b.js").then...
}
Copy code
in other words promise
Some functions import
Both can be used. .
Promise.all([
import("./a.js"),
import("./b.js"),
import("./c.js")
]).then((a,b,c) => {})
Copy code
Make full use of the ability of parallelism
8.2 Dynamic import
In fact, other specifications can also be imported dynamically , I just don't know if it supports regular .
async function test(p) {
return import(p)
}
Copy code
In this way, you can also import something dynamically , If you need some plug-ins , Put it in a directory , Dynamic import is a better choice .
But that's what's going on webpack There's going to be a problem , He will pack all the bags in the whole computer , Because he doesn't know what you'll bring in , For example, you want to be completely dynamic , You are reading the value from the database .
Therefore, it is suggested to narrow the scope .
import('./module/' + p);
Copy code
The regular representation was tested for half a day , Later, he issued that he was stupid .
8.3 Scope
A little bit more simple
a.js
export let c = 2;
setInterval(() => {
console.log(c);
})
Copy code
b.js
import c from './module/a';
c = 3;
Copy code
The output will always be 2
But if you change it
let c = 2;
export { c };
setInterval(() => {
console.log(c);
})
Copy code
It has always been 3
But there's something here that makes me wonder
import('./module/1.js').then(({ c }) => {
console.log(1, c);
c = 4;
import('./module/1.js').then(({ c }) => {
console.log(2, c);
})
})
Copy code
He keeps outputting 2
I checked for a long time and didn't get the answer , I can only roughly think of the difference between deep replication and shallow replication .
I hope this point can be answered in the follow-up study .
in general
- dynamic
import()
Offer based on Promise Of API,Promise Yes, you can useimport()
follow ES Module rules : Single case 、 Match symbol 、CORS etc.