当前位置:网站首页>Simple summary of front end modularization
Simple summary of front end modularization
2020-11-06 01:28:39 【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
npm
Look forpackage
When , 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
public
andprivate
The 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]所创,转载请带上原文链接,感谢
边栏推荐
- C++ 数字、string和char*的转换
- C++学习——centos7上部署C++开发环境
- C++学习——一步步学会写Makefile
- C++学习——临时对象的产生与优化
- C++学习——对象的引用的用法
- C++编程经验(6):使用C++风格的类型转换
- Won the CKA + CKS certificate with the highest gold content in kubernetes in 31 days!
- C + + number, string and char * conversion
- C + + Learning -- capacity() and resize() in C + +
- C + + Learning -- about code performance optimization
猜你喜欢
-
C + + programming experience (6): using C + + style type conversion
-
Latest party and government work report ppt - Park ppt
-
在线身份证号码提取生日工具
-
Online ID number extraction birthday tool
-
️野指针?悬空指针?️ 一文带你搞懂!
-
Field pointer? Dangling pointer? This article will help you understand!
-
HCNA Routing&Switching之GVRP
-
GVRP of hcna Routing & Switching
-
Seq2Seq实现闲聊机器人
-
【闲聊机器人】seq2seq模型的原理
随机推荐
- LeetCode 91. 解码方法
- Seq2seq implements chat robot
- [chat robot] principle of seq2seq model
- Leetcode 91. Decoding method
- HCNA Routing&Switching之GVRP
- GVRP of hcna Routing & Switching
- HDU7016 Random Walk 2
- [Code+#1]Yazid 的新生舞会
- CF1548C The Three Little Pigs
- HDU7033 Typing Contest
- HDU7016 Random Walk 2
- [code + 1] Yazid's freshman ball
- CF1548C The Three Little Pigs
- HDU7033 Typing Contest
- Qt Creator 自动补齐变慢的解决
- HALCON 20.11:如何处理标定助手品质问题
- HALCON 20.11:标定助手使用注意事项
- Solution of QT creator's automatic replenishment slowing down
- Halcon 20.11: how to deal with the quality problem of calibration assistant
- Halcon 20.11: precautions for use of calibration assistant
- “十大科学技术问题”揭晓!|青年科学家50²论坛
- "Top ten scientific and technological issues" announced| Young scientists 50 ² forum
- 求反转链表
- Reverse linked list
- js的数据类型
- JS data type
- 记一次文件读写遇到的bug
- Remember the bug encountered in reading and writing a file
- 单例模式
- Singleton mode
- 在这个 N 多编程语言争霸的世界,C++ 究竟还有没有未来?
- In this world of N programming languages, is there a future for C + +?
- es6模板字符
- js Promise
- js 数组方法 回顾
- ES6 template characters
- js Promise
- JS array method review
- 【Golang】️走进 Go 语言️ 第一课 Hello World
- [golang] go into go language lesson 1 Hello World