当前位置:网站首页>Simple summary of front end modularization
Simple summary of front end modularization
2020-11-06 01:28:00 【itread01】
Preface
JavaScript In the early stage, it is to realize the simple interactive logic of the page , Now CPU、 Browser performance has been greatly improved , A lot of page logic has migrated to the client side , Front end code is expanding , At this time in the js Aspects will consider how to manage, use modular specifications to manage .
No matter what language is, once it has developed to a certain extent , Its engineering ability and maintainability are bound to get corresponding development . The modularity thing , It's a common thing in any field of programming , The purpose of modularity is to increase reusability , With as little code as possible is the need to achieve personalization . One of the three swordsmen in the front end CSS As early as 2.1 It's a version of @import To achieve modularity , however JavaScript until ES6 Only then did the official modular solution emerge : ES Module (import、export). Although in the early days JavaScript Modularization is not supported in the language specification , But it didn't stop JavaScript The development of , There's no official modularity standard, and developers start building their own specifications , Implement your own specifications .
Front end modularization
JavaScript There were no modules in early design 、 The concept of packages and even classes , Although ES6 There is class Keywords , That's just a grammar sugar . As the complexity of the project increases , Developers need to simulate the functionality of classes , To isolate 、 Package 、 The organization is complex JavaScript Code , And this packaging and isolation , It's also called modularity .
A module is a file that implements a specific function or Code block . With the development of front end engineering system , Perhaps the concept of modularity is already familiar in the front-end circles . But for many developers ,ES6 Medium export、import,nodejs Medium require、exports.xx、module.exports What's the difference ? Why there is CommonJS, And then there is AMD,CMD,UMD? What's the difference ? We're even writing ts When it comes to filing , You also need to specify the module mode in the configuration file , When used in a project , Do we really know , What kind of specification are you using for modularity ?
The value of modularity
- Maintainability , Each module is independent . Good design can greatly reduce the coupling of projects . So that it can be modified independently of other functions . Maintain at least one independent function module , It's much easier than maintaining a mess of code .
- Reduce global variable pollution , The early days of front-end development , We're all having trouble with global variables , Because it often triggers some difficult and non-technical bug. When some unrelated code accidentally renames a global variable , We're going to meet annoying “ Name space pollution ” The problem of . Before the modularity specification was defined , In fact, we are trying to avoid this .( It will be introduced later )
- Reusability , Front end module function encapsulation , Greatly improves the reusability of code . There should be no need to elaborate on this point . Think about it from
npmLook forpackageWhen , What are you doing ? - Facilitate dependency management , When the modularity specification is not fully defined , The interdependence between modules is very vague , It all depends on js The order of file Introduction . Vulgar ! No technical content at all , It's not only fuzzy but also hard to maintain .
Modular evolution
1、 Function encapsulation
Let's go back to the definition of modules that we just talked about , A module is a file that implements a specific function or Code block ( This is my own definition ). Professional definition is , In programming , A program or subroutine required to perform a function ; Or can be compiled by a compiler 、 An independent program unit for assembly programs, etc ; Or part of a large software system . One of the functions of a function is to package a set of statements with specific logic . And JavaScript The scope of is function based , So the most original place , Functions must be the first step in modularization .
Encapsulate different functions into different functions
- Code : Encapsulate different functions into different global functions
- The problem is : Contaminating global namespace , It is easy to cause naming conflicts or data insecurity , And there is no direct relationship between module members , The relationship between modules is fuzzy
// Function 1
function fn1(){
//statement
}
// Function 2
function fn2(){
//statement
}
2、namespace Pattern
It can also be understood as object encapsulation , In fact, it is to put the related function 、 Variables are added to the outside
let module1 = {
let tag : 1,
let name:'module1',
fun1(){
console.log('this is fun1')
},
fun2(){
console.log('this is fun2')
}
}
When we use it , Just directly
module1.fun2();
Advantages
- It optimizes naming conflicts to some extent , It reduces the risk of contamination of global variables
- There is a certain module encapsulation and isolation , And it can be further semantically
Disadvantages
- There's no real change in naming conflicts
- External members can modify internal member variables at will , It's still prone to unexpected risks
3、IIFE Pattern : Execute anonymous functions immediately ( Closure )
let global = 'Hello, I am a global variable :)';
(function () {
// In the scope of a function, the following variables are private
const myGrades = [93, 95, 88, 0, 55, 91];
let average = function() {
let total = myGrades.reduce(function(accumulator, item) {
return accumulator + item}, 0);
return 'Your average grade is ' + total / myGrades.length + '.';
}
let failing = function(){
let failingGrades = myGrades.filter(function(item) {
return item < 70;});
return 'You failed ' + failingGrades.length + ' times.';
}
console.log(failing());
console.log(global);
// Need to be exposed api
return {
// something
}
}());
// The console shows :'You failed 2 times.'
// The console shows :'Hello, I am a global variable :)'
The advantage of this method lies in , You can use a local variable inside a function , It does not accidentally override a global variable with the same name , But you can still access global variables
Similar to the above IIFE , There's a lot of evolution writing
For example, introducing dependencies :
Pass in the variables needed internally .
// module.js Archives
(function(window, $) {
let data = 'www.baidu.com'
// Functions that manipulate data
function foo() {
// Used to expose a function
console.log(`foo() ${data}`)
$('body').css('background', 'red')
}
function bar() {
// Used to expose a function
console.log(`bar() ${data}`)
otherFun() // Internal calls
}
function otherFun() {
// Internal private functions
console.log('otherFun()')
}
// Exposure behavior
window.myModule = { foo, bar }
})(window, jQuery)
Use
// index.html Archives
<!-- Introduced js There has to be a certain order -->
<script type="text/javascript" src="jquery-1.10.1.js"></script>
<script type="text/javascript" src="module.js"></script>
<script type="text/javascript">
myModule.foo()
</script>
Advantages
- The basic encapsulation is realized
- Only exposed external method operation , Using closures, we achieve something similar to
publicandprivateThe concept of
Disadvantages
- Module dependencies are fuzzy
- It's not easy to manage between modules
All of the above solutions , Although every method works , But there is no one that can solve variable pollution well 、 The dependency relationship between modules is clear 、 Easy to manage 、 Easy integration with equation 3 code . With the advent of the era of big front end , stay 2009 It was proposed that CommonJS Regulate , And nodeJs Use the specification directly to manage modularity , As time goes by , Now JavaScript The module specification is there :CommonJS、AMD、CMD、UMD、ES6 Modularity .
4、CommonJS
CommonJS yes JavaScript A modular specification for (http://www.commonjs.org/), It is mainly used on the server side Nodejs in . According to the regulations , Every file is a module , The variables defined internally belong to this module , It doesn't pollute global variables . Inside each module ,module The variable represents the current module , This variable is an object , its exports Properties ( namely module.exports) It's an external interface . Load a module , In fact, the module is loaded module.exports Properties .
CommonJS The core idea is through require Method to load the dependent modules synchronously , And then through exports perhaps module.exprots To export the exposed interface .
Basic usage
- Exposure module :module.exports = value or exports.xxx = value
- Introducing modules :require(xxx), If it's a third-party module ,xxx For the module name ; If it's a custom module ,xxx For module file path
// example.js
let x = 5;
let addX = function (value) {
return value + x;
};
module.exports.x = x;
module.exports.addX = addX;
let example = require('./example.js');
console.log(example.x); // 5
console.log(example.addX(1)); // 6
require Command is used to load module files .require The basic function of the command is , Read in and execute a JavaScript Archives , Then return the module's exports thing , If the specified module is not found , Will report a mistake , If there are more than one exports Only the first one exports It works .
require It's loading the file and executing , Back in 、 Output exports This object
console.log(' It's starting to load ') // Will output It's starting to load
function run (val) {
console.log(val)
}
Features
- A module is a file module , Code execution is within the scope of the module , It doesn't pollute global variables
- Load module synchronously , It is no problem to read the local disk directly on the server side , Not for browsers
- Modules can be loaded multiple times , But it will only be executed on the first load , And then load , It's the cache file to be read . You need to clear the cache before you can read the file again
- The order in which modules are loaded , In the order in which they appear in the code
- Export is a copy of the value , This and ES6 There's a big difference ( It will be introduced later )
Add some knowledge
Node in , A file is a module ->module
The source code is defined as follows :
function Module(id = '', parent) {
this.id = id;
this.path = path.dirname(id);
this.exports = {};
this.parent = parent;
updateChildren(parent, this, false);
this.filename = null;
this.loaded = false;
this.children = [];
}
// Instantiate a module var module = new Module(filename, parent);
CommonJS A module of , It's a script file .require The command loads the script for the first time , It will execute the entire instruction code , And then create an object in memory .
{
id: '...',
exports: { ... },
loaded: true,
...
}
The code above is Node An object generated after the module is loaded internally . Of the object id The property is the module name ,exports Property is the interface of the module output ,loaded The attribute is a Boolean value , Indicates whether the instruction code of the module is completed . There are many other properties . When you need to use this module later , It will come to exports The value above the attribute is . Even if you do it again require command , The module will not be executed again , It's in the cache . That is to say ,CommonJS No matter how many times a module is loaded , Will only be executed once on the first load , Load later , Return the result of the first execution , Unless you manually clear the system cache .
About AMD、CMD
CommonJS stay Node.js It's been a great success in the environment , A lot of people want to put commonJs The specification is pushed to the browser side , But the browser can't directly read the contents of the disk like the server, so there is the following AMD、CMD Regulate .ES6 At the level of language standards , The module function is realized , And it's quite simple to implement , It can completely replace the existing CommonJS and AMD Regulate , Become a common module solution for browsers and servers , Because I've only been in the front end in recent years , AMD、CMD Not too much use of , therefore AMD、CMD Here is just a brief introduction .
5、AMD
AMD Its full name is Asynchromous Module Definition( Asynchronous module definition )
AMD yes RequireJS The standardized output of module definition in the promotion process , It's a specification for modular development on the browser side . AMD Patterns can be used in browser environments and allow asynchronous loading of modules , At the same time, it can ensure the correct order , You can also dynamically load modules on demand .
Features
- Asynchronous load module , It won't cause fake death due to network problems
- Explicitly list its dependencies , And with the function ( The function that defines this module ) These dependencies are injected in the form of arguments
- At the beginning of the module , Load all the required dependencies
Define modules
define(id?: String, dependencies?: String[], callback: Function|Object);
- id, An optional argument , It's like giving the module a name , But it's the only identification of the module . If it is not provided, the file name of the script is taken
- dependence, Dependent module array
- callback, Factory approach , Some operations of module initialization . If it's a function , Only once . If it's an object , The output value of the module
Using modules
require([moduleName],callback);
//article.js Archives
// Define modules that have dependencies
define(['user'], function(user) {
let name = 'THE LAST TIME'
function consoleMsg() {
console.log(`${name} by ${user.getAuthor()}`);
}
// Exposure module
return { consoleMsg }
})
// call article Module type consoleMsg
require(['article'], function(alerter) { article.consoleMsg() })
6、CMD
define(factory);
define Is a global function , Used to define modules , Arguments factory It can be objects 、 String 、 Function
factory For objects 、 When the string is , The interface representing the module is the object 、 String . For example, one can be defined as follows JSON Data module :
define({ "foo": "bar" });
You can also define template modules through strings :
define('I am a template. My name is {{name}}.');
factory When is a function , Representation is the construction method of the module .
Execute the constructor , You can get the interface provided by the module .factory When the method is executed , By default, three arguments are passed in :require、exports and module:
define(function(require, exports, module) {
// Module code
});
Use sea.js
/** sea.js **/
// Define modules math.js
define(function(require, exports, module) {
var $ = require('jquery.js');
var add = function(a,b){
return a+b;
}
exports.add = add;
});
// Load module
seajs.use(['math.js'], function(math){
var sum = math.add(1+2);
});
About sea.js Use , Look at the document carefully , In fact, there are many knowledge points . But we don't use it much now ( I'm not familiar either ), So here also refer to the excellent articles on the Internet and their own practice , Throw a brick to attract jade .
7、UMD
UMD yes AMD and CommonJS The combination of . As mentioned above ,AMD It's the browser , Non blocking load .CommonJS It is mainly used on the server side Nodejs Use in . So people came up with a general pattern UMD(universal module definition). To solve cross platform problems .
That's right ! Namely ifElse How to write .
The core idea is : First judge whether to support Node.js Module of (exports) Whether there is , To be is to use Node.js Module mode .
Judging whether to support AMD(define Whether there is ), To be is to use AMD Mode loading module .
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
//AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
//Node, CommonJS And so on
module.exports = factory(require('jquery'));
} else {
// Browser global variables (root namely window)
root.returnExports = factory(root.jQuery);
}
}(this, function ($) {
// Method
function myFunc(){};
// Expose public methods
return myFunc;
}));
8、ES Module
stay ES Module Before , The community has developed some module loading schemes , The main ones are CommonJS and AMD Two kinds of . The former is used for servers , The latter is used for browsers .ES Module At the level of language standards , The module function is realized , And it's quite simple to implement , It can completely replace CommonJS and AMD Regulate , Become a common module solution for browsers and servers .
ES Module The design idea is static as far as possible , So that the module dependencies can be determined at compile time , And input and output variables .CommonJS and AMD Module , They can only be determined at the time of execution .
CommonJS and AMD Module , Its essence is to generate an object for export at runtime , It's called “ Load at run time ”, It can't be done “ Compiler optimization ”, and ES Module It's not an object , It's through export The command explicitly specifies the output code , And then through import Command input . This is called “ Load at compile time ” Or statically load , namely ES Module Modules can be loaded at compile time , More efficient than CommonJS The loading mode of modules is high . Of course , It also makes it impossible to quote ES Module The module itself , Because it's not an object .
Because of ES Module Is compile time loading , Making static analysis possible . With it , Can further broaden JavaScript The grammar of , For example, introducing a macro (macro) And type checking (type system) These functions can only be realized by static analysis .
Features
- Static compilation
- The output value references , Instead of copying values
- import It can only be written at the top , Because it's static syntax
9、CommonJs、ESM The difference is
| CommonJs | ES6 Module |
| Load at run time ;CommonJs Modules are objects (module.exports Properties )), That is, the whole module is loaded first when input 、 Execution module , Create an object , Then read the method from the object . | Load at compile time ;ES6 Modules are not objects , It's through export The command explicitly specifies the output code ,import In the form of static commands . That is to say import You can specify to load an output value when , Instead of loading the entire module . |
| The output is a copy of the value ( Once a value is output , Changes within the module do not affect this value .) | The output is a reference to the value (JS When the engine statically analyzes the script , Module loading command encountered import, A read-only reference will be generated . When the script actually executes , According to this read-only reference , Go to the loaded module to get the value . That is, the original value has changed ,import The loaded values will change accordingly . therefore ,ES6 Modules are dynamic references , And it's not going to take values quickly , The variables in a module are bound to the module in which they are located .) |
The difference
- CommonJS What the module outputs is a copy of the value ,ES6 The module outputs a reference to the value .
- CommonJS Modules are loaded at run time ,ES6 A module is a compile time output interface .
Load & Compile
Because CommonJS Loading is an object (module.exports), Objects can only be generated when there is a script running . and ES6 A module is not an object , It's just a static definition . During the code parsing phase .
ES6 A module is a compile time output interface , So there are the following 2 Characteristics :
- import Orders will be JS Engine static analysis , Takes precedence over other contents in the module
- export The command will have variables to declare the effect of promotion , therefore import and export The location of the command in the module does not affect the output of the program .
- Asynchronous load module , It won't cause fake death due to network problems
- Explicitly list its dependencies , And with the function ( The function that defines this module ) These dependencies are injected in the form of arguments
- At the beginning of the module , Load all the required dependencies
版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
边栏推荐
- Word segmentation, naming subject recognition, part of speech and grammatical analysis in natural language processing
- 一篇文章带你了解CSS 分页实例
- After reading this article, I understand a lot of webpack scaffolding
- [C / C + + 1] clion configuration and running C language
- 一篇文章带你了解CSS3图片边框
- Elasticsearch数据库 | Elasticsearch-7.5.0应用搭建实战
- 前端基础牢记的一些操作-Github仓库管理
- A brief history of neural networks
- The choice of enterprise database is usually decided by the system architect - the newstack
- Relationship between business policies, business rules, business processes and business master data - modern analysis
猜你喜欢

加速「全民直播」洪流,如何攻克延时、卡顿、高并发难题?

If PPT is drawn like this, can the defense of work report be passed?

百万年薪,国内工作6年的前辈想和你分享这四点

How to customize sorting for pandas dataframe

Natural language processing - BM25 commonly used in search

IPFS/Filecoin合法性:保护个人隐私不被泄露

vue-codemirror基本用法:实现搜索功能、代码折叠功能、获取编辑器值及时验证

一篇文章带你了解SVG 渐变知识

Elasticsearch数据库 | Elasticsearch-7.5.0应用搭建实战

一篇文章带你了解CSS对齐方式
随机推荐
EOS创始人BM: UE,UBI,URI有什么区别?
Process analysis of Python authentication mechanism based on JWT
Programmer introspection checklist
6.6.1 localeresolver internationalization parser (1) (in-depth analysis of SSM and project practice)
每个前端工程师都应该懂的前端性能优化总结:
How to encapsulate distributed locks more elegantly
中小微企业选择共享办公室怎么样?
至联云分享:IPFS/Filecoin值不值得投资?
Common algorithm interview has been out! Machine learning algorithm interview - KDnuggets
I've been rejected by the product manager. Why don't you know
Network security engineer Demo: the original * * is to get your computer administrator rights! 【***】
Flink的DataSource三部曲之一:直接API
Filecoin的经济模型与未来价值是如何支撑FIL币价格破千的
一篇文章带你了解CSS3图片边框
Group count - word length
Wechat applet: prevent multiple click jump (function throttling)
Python Jieba segmentation (stuttering segmentation), extracting words, loading words, modifying word frequency, defining thesaurus
Elasticsearch数据库 | Elasticsearch-7.5.0应用搭建实战
PHP应用对接Justswap专用开发包【JustSwap.PHP】
A course on word embedding