编程知识 cdmana.com

About JavaScript modules

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

  1. 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.

  2. 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 script circle.js.

  3. 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 .

  1. If the parameter string does not use “./“ or ”/“ start , And it's a path , such as require('example-module/path/to/file'), You will find example-module The location of , Then take it as a parameter , Find the next path .

  2. 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 .

  3. If you want require The exact filename the command loads , Use require.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 use
  • import() follow ES Module rules : Single case 、 Match symbol 、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-…

版权声明
本文为[Lazy and ugly]所创,转载请带上原文链接,感谢
https://cdmana.com/2021/09/20210909135431040L.html

Scroll to Top