当前位置:网站首页>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
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]所创,转载请带上原文链接,感谢
边栏推荐
- 每个前端工程师都应该懂的前端性能优化总结:
- Let the front-end siege division develop independently from the back-end: Mock.js
- How long does it take you to work out an object-oriented programming interview question from Ali school?
- 助力金融科技创新发展,ATFX走在行业最前列
- Wiremock: a powerful tool for API testing
- The data of pandas was scrambled and the training machine and testing machine set were selected
- Word segmentation, naming subject recognition, part of speech and grammatical analysis in natural language processing
- 6.3 handlerexceptionresolver exception handling (in-depth analysis of SSM and project practice)
- Python基础数据类型——tuple浅析
- Filecoin最新动态 完成重大升级 已实现四大项目进展!
猜你喜欢
前端基础牢记的一些操作-Github仓库管理
Filecoin最新动态 完成重大升级 已实现四大项目进展!
在大规模 Kubernetes 集群上实现高 SLO 的方法
每个前端工程师都应该懂的前端性能优化总结:
ES6学习笔记(二):教你玩转类的继承和类的对象
Arrangement of basic knowledge points
How to select the evaluation index of classification model
git rebase的時候捅婁子了,怎麼辦?線上等……
前端都应懂的入门基础-github基础
How to customize sorting for pandas dataframe
随机推荐
How to use Python 2.7 after installing anaconda3?
The difference between Es5 class and ES6 class
git rebase的時候捅婁子了,怎麼辦?線上等……
Music generation through deep neural network
合约交易系统开发|智能合约交易平台搭建
Summary of common string algorithms
仅用六种字符来完成Hello World,你能做到吗?
Save the file directly to Google drive and download it back ten times faster
html
Lane change detection
百万年薪,国内工作6年的前辈想和你分享这四点
I think it is necessary to write a general idempotent component
至联云分享:IPFS/Filecoin值不值得投资?
Network security engineer Demo: the original * * is to get your computer administrator rights! 【***】
With the advent of tensorflow 2.0, can pytoch still shake the status of big brother?
Individual annual work summary and 2019 work plan (Internet)
JVM memory area and garbage collection
Brief introduction of TF flags
IPFS/Filecoin合法性:保护个人隐私不被泄露
6.2 handleradapter adapter processor (in-depth analysis of SSM and project practice)