Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the knowledge points of JavaScript module?

2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces "what are the knowledge points of the JavaScript module". In the daily operation, I believe many people have doubts about the knowledge points of the JavaScript module. The editor consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful to answer the questions of "what are the knowledge points of the JavaScript module?" Next, please follow the editor to study!

Module usually refers to the code organization mechanism provided by the programming language, which can be used to disassemble the program into independent and general code units. The so-called modularization mainly solves many aspects, such as code segmentation, scope isolation, dependency management between modules and automatic packaging and processing when released to the production environment.

Advantages of Modul

Maintainability. Because the module is independent, a well-designed module will make the external code as less dependent on itself as possible, so that it can be updated and improved independently.

Namespace. In JavaScript, if a variable is declared outside the most powerful function, it becomes available globally. As a result, naming conflicts often occur accidentally. Using modular development to encapsulate variables can avoid polluting the global environment.

Reuse code. We sometimes like to copy code from previously written projects to new projects, which is fine, but a better way is to avoid duplicate code bases through module references.

CommonJS

CommonJS started as a project by Mozilla engineers in 2009 to enable JavaScript outside browsers (such as server-side or desktop-side) to develop and collaborate in a modular manner.

In the CommonJS specification, each JavaScript file is a separate module context (module context) in which the properties created by default are private. That is, variables defined in one file (including functions and classes) are private and not visible to other files.

It should be noted that the main application scenario of the CommonJS specification is server-side programming, so the strategy of loading modules synchronously is adopted. If we rely on three modules, the code will load them one by one.

The implementation scheme of this module mainly contains two keywords: require and module, which allow a module to expose part of the interface and be imported and used by other modules.

/ / sayModule.js function SayModule () {this.hello = function () {console.log ('hello');}; this.goodbye = function () {console.log (' goodbye');};} module.exports = SayModule; / / main.js introduce sayModule.js var Say = require ('. / sayModule.js'); var sayer = new Say (); sayer.hello (); / / hello

As a server-side solution, CommonJS requires a compatible script loader as a prerequisite. The script loader must support functions named require and module.exports, which import and export modules to each other.

Node.js

Node has created its own modular implementation from some of CommonJS's ideas. Because of the popularity of Node on the server side, the modular form of Node is (incorrectly) called CommonJS.

Node.js modules can be divided into two categories, one is the core module, the other is the file module.

Core module

These are the modules provided in the API of the Node.js standard, such as fs, http, net, etc. These modules are officially provided by Node.js and compiled into binary code, and the core module can be obtained directly through require, such as require ('fs'). The core module has a load priority of * *. If there is a conflict between the module name and the core module name, Node.js will always load the core module.

File module

Is a module that is stored as a separate file (or folder), which could be JavaScript code, JSON, or compiled Cmax Candle + code. When you do not explicitly specify the file module extension, Node.js attempts to add .js, .json, and .node (the compiled Cmax Candle + code).

Loading mode

Load modules by path

If the require parameter starts with a "/", then the module name is looked up in an absolute path, and if the parameter a ". /", ".. /" starts, then the module is found in a relative path.

Load the module by looking up the node_modules directory

If the require parameter does not start with "/", ". /", ".. /", and the module is not the core module, then load the module by looking for node_modules. The packages we use npm to get are usually loaded in this way.

Load cach

The Node.js module will not be reloaded because Node.js caches all loaded file modules by file name, so it will not be reloaded when it is accessed later.

Note: Node.js is cached based on the actual file name, not the parameters provided by require (), that is, even if you load twice through require ('express') and require ('. / node_modules/express'), it will not be loaded repeatedly, because although the parameters are different, the parsed file is the same.

Modules in Node.js run as singletons after loading, and follow the principle of value passing: if it is an object, it is equivalent to a reference to that object.

Module loading process

The work of loading the file module is mainly realized and completed by the native module module, which has been loaded at startup, and the process calls directly to the runMain static method.

For example, run: node app.js

Module.runMain = function () {/ / Load the main module--the command line argument. Module._load (process.argv [1], null, true);}; / _ load static method executes var module = new Module (id, parent) after parsing the file name; / / and caches the current module object according to the file path, and the module instance object is loaded based on the file name. Module.load (filename)

Specifically, the three types of file modules mentioned above are distinguished by suffixes. Node.js will determine the loading method according to the suffix name. The specific loading method will be described in the following require.extensions.

.js reads the js file synchronously through the fs module and compiles and executes.

An Addon written by .node through Cmax Candle +. Load through the dlopen method.

.json reads the file and calls JSON.parse to parse the load.

Next, the compilation process of the js suffix is described in detail. The step that Node.js actually completes in the process of compiling the js file is wrapping the contents of the js file head-to-tail. Take app.js as an example, the packaged app.js will be in the following form:

/ / circle.js var PI = Math.PI; exports.area = function (r) {return PI * r * r;}; exports.circumference = function (r) {return 2 * PI * r;}; / / app.js var circle = require ('. / circle.js'); console.log ('The area of a circle of radius 4 is' + circle.area (4)) / / after app packaging (function (exports, require, module, _ _ filename, _ _ dirname) {var circle = require ('. / circle.js'); console.log ('The area of a circle of radius 4 is' + circle.area (4));}); / / this code is executed through the runInThisContext method of the vm native module (similar to eval, but with a clear context and does not pollute the global), and is returned as a specific function object. * pass the exports,require method, module, file name and directory name of the module object as arguments and execute them.

This is why require is not defined in the app.js file, but this method exists. From the API document of Node.js, you can see that there are several undefined but existing variables such as _ _ filename, _ _ dirname, module, and exports. Among them, _ _ filename and _ _ dirname are passed in after being analyzed in the process of finding the file path. The module variable is the module object itself, and exports is an empty object ({}, not null) initialized in the constructor of module.

In this master file, you can import the rest of the modules through the require method. In fact, this require method actually calls the module._load method.

The load method returns the exports object of module after loading, compiling, and caching module. This is why only methods defined on exports objects in the circle.js file can be called externally.

The module loading mechanisms described above are defined in lib/module.js.

Require function

The objects introduced by require are mainly functions. When Node calls the require () function and passes a file path to it, Node goes through the following steps:

Resolving: absolute path to find the file

Loading: determine the type of file content

Wrapping: package to give this file a private scope. This is a way to have require and module modules referenced locally

Where Evaluating:VM handles the loaded code

Caching: when you need to use this file again, you don't need to repeat the above steps.

Require.extensions to see the support for three files:

You can clearly see the functions and actions that Node uses for each extension: use module._compile; for .js files, use JSON.parse; for .json files, use process.dlopen for .node files.

File lookup strategy

Load from the file module cache

Although the priority of the native module is different from that of the file module, the priority * is to load an existing module from the cache of the file module.

Load from native module

The priority of the native module is second only to that of the file module cache. After parsing the file name, the require method first checks whether the module is in the list of native modules. Take the http module as an example, although there are http, http.js, http.node, and http.json files in the directory, require ("http") is not loaded from these files, but from the native module.

Native modules also have a cache, which is also preferentially loaded from the cache. If the cache has not been loaded, the loading mode of the native module is called to load and execute.

Load from a file

When the file module cache does not exist and is not a native module, Node.js parses the parameters passed in by the require method and loads the actual file from the file system. The wrapper and compilation details of the loading process are described earlier by calling the load method.

When Node encounters require (X), it is processed in the following order.

1. If X is a built-in module (such as require ('http'))

a. Return to the module.

b. No more execution.

2. If X starts with ". /" or "/" or ".. /"

a. The absolute path of X is determined according to the parent module where X is located.

b. Treat X as a file, look for the following files in turn, and return the file as long as one of them exists, and do not continue.

X

X.js

X.json

X.node

c. Take X as a directory, look for the following files in turn, and return the file as long as one of them exists, and do not continue.

X/package.json (main field)

X/index.js

X/index.json

X/index.node

3. If X does not have a path

a. Determine the possible installation directory for X based on the parent module where X is located.

b. In each directory in turn, load X as a file name or directory name.

4. Throw out "not found"

Module circular dependence

/ / create two files, module1.js and module2.js, and have them refer to each other / / module1.js exports.a = 1; require ('. / module2'); exports.b = 2; exports.c = 3; / / module2.js const Module1 = require ('. / module1'); console.log ('Module1 is partially loaded here', Module1)

Module2 needs to be loaded before module1 can be fully loaded, and module1 is needed to load module2. In this state, what we can get from the exports object is the part before the circular dependency occurs. In the above code, only the an attribute is introduced, because both b and c need to be loaded after the introduction of module2.

Node simplifies this problem by starting to create exports objects during a module load. If it needs to introduce other modules and has a circular dependency, it can only be partially introduced, that is, it can only introduce the part defined before the circular dependency occurs.

AMD

AMD is the abbreviation of Asynchronous Module Definition, that is, "asynchronous module definition", which is born out of the CommonJS discussion. AMD gives priority to the browser's module loading scenario, using asynchronous loading and callback.

AMD needs a script loader like CommonJS, although AMD only needs support for the define method. The define method takes three parameters: the name of the module, the dependency array in which the module runs, and the function that all dependencies are available for later execution (this function accepts dependencies as arguments in the order in which they are declared). Only function arguments are required. Define is both a way to reference a module and a way to define a module.

/ / file lib/sayModule.js define (function () {return {sayHello: function () {console.log ('hello');}};}); / / file main.js define (['. / lib/sayModule'], function (say) {say.sayHello (); / / hello})

Main.js as the entry module of the entire application, we use the define keyword to declare the module and external dependencies (no life module name); when we execute the module code, that is, we execute the function defined in the second parameter of the define function, which will be executed after the framework has loaded all other dependent modules. This technique of delaying code execution also ensures dependent concurrent loading.

RequireJS

RequireJS is a front-end modular management tool library, in accordance with the AMD specification, through a function to load all the required or dependent module implementation, and then return a new function (module), all our business code about the new module is operated in this function, and its internal can also be used to load the module since it has been loaded.

The main.js under / / scripts is the specified main code script file, from which all dependent module code files will be asynchronously loaded and executed.

Defined is used to define modules, and RequireJS requires each module to be placed in a separate file. According to whether there is dependence on other modules, it is divided into independent modules and non-independent modules.

1. Independent modules do not depend on other modules. Define directly:

Define ({methodOne: function () {}, methodTwo: function () {}); / / equivalent to define (function () {return {methodOne: function () {}, methodTwo: function () {}};})

2. Non-independent modules, dependent on other modules.

Define (['moduleOne',' moduleTwo'], function (mOne, mTwo) {...}); / or define (function (require) {var mOne = require ('moduleOne'), mTwo = require (' moduleTwo');...})

As in the above code, define has dependent module array and non-dependent module array uses require to load these two definition modules, the method of calling the module is called AMD mode, the definition module is clear, will not pollute the global variables, and clearly show the dependency. AMD mode can be used in browser environments and allows modules to be loaded asynchronously or dynamically on demand.

CMD

CMD (Common Module Definition), in CMD, a module is a file.

The global function define is used to define the module.

The parameter factory can be a function, an object or a string.

When factory is an object or string, the interface that represents the module is the object or string.

Define the JSON data module:

Define ({"foo": "bar"})

When factory is a function, it represents the construction method of the module, and the interface provided by the module can be obtained by executing the construction method.

Define (function (require, exports, module) {/ / Module Code})

SeaJS

Sea.js core features:

Follow the CMD specification and write the module code like NodeJS.

Rely on automatic loading, the configuration is clear and concise.

Seajs.use is used to load one or more modules in a page.

/ / load a module seajs.use ('. / a'); / / load a module, and execute a callback seajs.use when the loading is complete ('. / a) {a.doSomething ();}); / / load multiple modules to execute a callback seajs.use (['. / axiom dwelling. Uniqb'], function (a, b) {a.doSomething (); b.doSomething ();})

The difference between AMD and CMD*** is that the timing of execution of dependent modules is different, and note that it is not the timing or manner of loading.

Many people say that requireJS is an asynchronous loading module, and SeaJS is a synchronous loading module. This understanding is actually not accurate. In fact, loading modules are all asynchronous, but AMD depends on the front, js can easily know who the dependent module is and load immediately, while CMD depends on it nearby. You need to parse the module into a string to know which modules you rely on. This is also a point that many people criticize about CMD. At the expense of performance to bring the convenience of development, in fact, the time used to parse the module is negligible.

Why is it that the timing of execution is different?

It is also an asynchronous loading module. AMD will execute the module after loading the module, and all modules will enter the callback function and execute the main logic after loading. The effect is that the execution order and writing order of the modules are not necessarily the same, depending on the network speed, which is downloaded first and which is executed first, but the main logic must be executed after all dependencies have been loaded.

CMD does not execute a dependent module after loading, it just downloads it, enters the main logic after all dependent modules are loaded, and executes the corresponding module only when it encounters a require statement, so that the execution order and writing order of the modules are exactly the same.

UMD

Unified module definition (UMD:Universal Module Definition) is an attempt to combine AMD and CommonJS, and it is common practice to wrap CommonJS syntax in AMD-compliant code.

(function (define) {define (function () {return {sayHello: function () {console.log ('hello');}};});} (typeof module =' object' & & module.exports & & typeof define! = 'function'? Function (factory) {module.exports = factory ();}: define))

The core idea of this pattern is the so-called IIFE (Immediately Invoked Function Expression), which determines the types of parameters needed based on the environment.

ES6 module (module)

Strict mode

ES6's module automatically follows strict mode, regardless of whether or not the module header is added with "use strict";.

The strict mode mainly has the following limitations.

Variables must be declared before using

The parameter of a function cannot have an attribute with the same name, otherwise an error will be reported

Cannot use with statement

Cannot assign a value to a read-only property, otherwise an error will be reported

You cannot use the prefix 0 for octal numbers, otherwise an error will be reported

Cannot delete an attribute that cannot be deleted, otherwise an error will be reported

Can not delete the variable delete prop, will report an error, can only delete the attribute delete global [prop]

Eval does not introduce variables in its outer scope

Eval and arguments cannot be reassigned

Arguments does not automatically reflect changes in function parameters.

Cannot use arguments.callee

Cannot use arguments.caller

Prohibit this from pointing to global objects

Cannot use fn.caller and fn.arguments to get the stack of function calls

Added reserved words (such as protected, static and interface)

Module Module

A module is a file that exposes its properties or methods to other modules.

Export Export

As a module, it can selectively expose (provide) its own properties and methods to other modules for use by other modules.

/ / profile.js export var firstName = 'qiqi'; export var lastName =' haobenben'; export var year = 1992; / / equivalent to var firstName = 'qiqi'; var lastName =' haobenben'; var year = 1992; export {firstName, lastName, year}

1. Normally, the variable output by export is the original name, but it can be renamed using the as keyword.

Function v1 () {...} function v2 () {...} export {v1 as streamV1, v2 as streamV2, v2 as streamLatestVersion}; / / the above code renames the external interfaces of functions v1 and v2 using the as keyword. After renaming, v2 can be output twice with a different name.

2. It should be noted that the export command specifies the external interface and must establish an one-to-one correspondence with the internal variables of the module.

/ / error export 1; / error var m = 1; export m; / / both of the above words will report an error, because no external interface is provided. * the method of writing directly outputs 1, and the second method outputs 1 directly through the variable m. 1 is just a value, not an interface. / / export var m = 1; / / var m = 1; export {m}; / / three var n = 1; export {n as m}

/ / the above three writing methods are correct, and the external interface m is specified. Other scripts can get a value of 1 through this interface. Their essence is to establish an one-to-one corresponding relationship between the interface name and the internal variables of the module.

3. * export command can appear anywhere in the module, as long as it is at the top level of the module. If you are in block-level scope, you will get an error, as will the import command that follows.

Function foo () {export default 'bar' / / SyntaxError} foo ()

Import import

As a module, you can introduce the properties or methods provided by other modules for your own module as needed.

1. The import command accepts a pair of curly braces that specify the name of the variable to be imported from another module. The variable name in the curly braces must be the same as the external interface name of the imported module (profile.js). If you want to rename the entered variable, the import command uses the as keyword to rename the entered variable.

Import {lastName as surename} from'. / profile'

2. The from after import specifies the location of the module file, which can be a relative path or an absolute path, and the .js path can be omitted. If it is just the name of the module without a path, then there must be a configuration file that tells the JavaScript engine the location of the module.

3. Note that the import command has a lifting effect, which will be promoted to the head of the entire module and will be executed first.

The code above foo (); import {foo} from 'my_module'; / / does not report an error because the execution of import predates the call to foo. The essence of this behavior is that the import command is executed at compile time before the code runs.

4. Because import is executed statically, expressions and variables cannot be used, and the syntax structure of the result can only be obtained at run time.

/ / error reporting import {'f' + 'oo'} from' my_module'; / / error reporting let module = 'my_module'; import {foo} from module; / / error if (x = 1) {import {foo} from' module1';} else {import {foo} from 'module2';}

5. Import statement executes the loaded module, so it can be written as follows.

Import 'lodash'; / / the above code only executes the lodash module, but does not enter any values.

Default Export (export default)

Each module allows us to export a variable without a name, which is implemented using the key statement export default.

Export default function () {console.log ("I am default Fn");} / / use the export default keyword to export an anonymous function. When importing this module, you can give the anonymous function any name / / any name can be import sayDefault from ". / module-B.js"; sayDefault (); / / result: I am default Fn

1. Comparison between default output and normal output

/ / * Group export default function diff () {/ / output / /...} import diff from 'diff'; / input / / the second group export function diff () {/ / output / /...}; import {diff} from' diff' / / enter / / two sets of writing of the above code. The * group is that when using export default, the corresponding import statement does not need to use curly braces. The second group is that when export default is not used, the corresponding import statement needs to use curly braces.

The export default command specifies the default output of the module. Obviously, a module can have only one default output, so the export default command can only be used once. Therefore, there is no need to enlarge parentheses after the import command, because there can only be one method.

2. Because the essence of export default is to assign the value after the command to the default variable and then default later, write a value directly after export default.

/ / correct export default 42; / / error export 42; / / in the above code, the latter sentence reports an error because no external interface is specified, while the previous sentence specifies the external interface as default.

3. If you want to enter the default method and other variables in an import statement at the same time, you can write it as follows.

Import _, {each} from 'lodash'; / / the export statement corresponding to the above code is as follows: export default function () {/ /...} export function each (obj, iterator, context) {/ /.}

Compound Writing method of export and import

If you input and then output the same module in a module, the import statement can be written together with the export statement.

Export {foo, bar} from 'my_module'; / / is equivalent to import {foo, bar} from' my_module'; export {foo, bar}; / API renamed export {foo as myFoo} from 'my_module'; / / overall output export * from' my_module'

Matters needing attention

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Declared variables are read-only to the outside. However, if the value of the object type is exported, it can be modified.

Import a variable that does not exist with a value of undefined.

Circular references in ES6

In ES6, imports is a read-only view of exprts. To put it bluntly, imports points to the original data of exports, such as:

/ /-lib.js-export let counter = 3; export function incCounter () {counter++;} / /-main.js-import {counter, incCounter} from'. / lib'; / / The imported value `counter`is live console.log (counter); / / 3 incCounter (); console.log (counter); / 4 / / The imported value can't be changed counter++; / / TypeError

So it's easy to handle circular references in ES6, as shown in the following code:

/ /-a.js-import {bar} from'baked; / / (1) export function foo () {bar (); / / (2)} / /-b.js-import {foo} from'asituation; / / (3) export function bar () {if (Math.random ()) {foo () / / (4)}}

Suppose module an is loaded first, and after module an is loaded, the bar indirectly points to the bar in module b. There is an indirect link between loaded imports and unfinished imports,imports and exports, so it always works.

Example

/ /-module-B.js file-- / / Export variable: name export var name = "cfangxu"; moduleA module code: / / Import module B attribute name import {name} from ". / module-B.js"; console.log (name) / / print result: cfangxu

Bulk export:

/ / attribute name var name = "cfangxu"; / / attribute age var age = 26; / / method say var say = function () {console.log ("say hello");} / / batch export export {name,age,say}

Bulk Import:

/ / Import module B attributes import {name,age,say} from ". / module-B.js"; console.log (name) / / print result: cfangxu console.log (age) / / print result: 26 say () / / print result: say hello

Rename the import variable:

Import {name as myName} from'. / module-B.js'; console.log (myName) / / cfangxu

Import as a whole:

/ / use * to import import * as obj from ". / module-B.js"; console.log (obj.name) / / result: "cfangxu" console.log (obj.age) / / result: 26 obj.say (); / / result: at this point, the study of "what are the knowledge points of the JavaScript module" is over, hoping to solve everyone's 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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report