This is the third day of my participation in Gwen Challenge

Modular understanding

What is a module? Encapsulate a complex program into several blocks (files) according to certain rules (specifications) and combine them together; The internal data/implementation of the block is private, exposing only interfaces (methods) to communicate with other external modules.

Composition of a module: data are internal attributes; The behavior of manipulating data is an internal function.

Coding is done module by module, so the whole project is a modular project.

Evolution of modularity

Global Function mode

module1.js

/ / data
let data = 'hello world'
    
// A function that manipulates data
function foo() {
   console.log(`foo() ${data}`)}function bar() {
   console.log(`bar() ${data}`)}Copy the code

module2.js

let data2 = 'other data';
    
function foo() {  // There is a conflict with a function in another module
   console.log(`foo() ${data2}`)}Copy the code

index.html

<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript">
  let data = "I'm the revised data."
  foo()
  bar()
</script>
Copy the code
  • Encoding: Encapsulating different functions into different global functions.
  • Problem: Global is polluted globally and can easily cause naming conflicts

The namespace mode

module1.js

let myModule = {
  data: 'module1'.foo() {
    console.log(`foo() The ${this.data}`)},bar() {
    console.log(`bar() The ${this.data}`)}}Copy the code

module2.js

let myModule2 = {
  data: 'module2 atguigu.com'.foo() {
    console.log(`foo() The ${this.data}`)},bar() {
    console.log(`bar() The ${this.data}`)}}Copy the code

index.html

<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript" src="module22.js"></script>
<script type="text/javascript">
  myModule.foo()
  myModule.bar()

  myModule2.foo()
  myModule2.bar()

  // You can modify the data inside the module directly
  myModule.data = 'other data' 
  myModule.foo()
Copy the code
  • Encoding: Simple object encapsulation
  • Effect: Reduces global variables
  • Problem: it is not safe to modify the internal code of the module

IIFE mode

module1.js

(function (window) {
/ / data
let data = 'atguigu.com'

// A function that manipulates data
function foo() { // Internal private functions exposed externally
  console.log(`foo() ${data}`)}function bar() {// Internal private functions exposed externally
  console.log(`bar() ${data}`)
  otherFun() // Internal call
}

function otherFun() { // Unexposed internal private functions
  console.log('otherFun()')}// Expose behavior
window.myModule = {foo, bar}
})(window)
Copy the code

index.html

<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript">
  myModule.foo()
  myModule.bar()
  //myModule.otherFun() // myModule.otherfun is not a function
  console.log(myModule.data) //undefined cannot access module internal data
  myModule.data = 'xxxx' // It is not the data inside the modified module
  myModule.foo() // Not affected
</script>
Copy the code
  • Encoding: Anonymous function self-invocation (closure)
  • IIFE: Immediate-Invoked function expression (Invoke function expression immediately)
  • What it does: Data is private and can only be manipulated externally by exposed methods
  • Question: What if the current module depends on another module?

IIFE mode enhancement

module4.js

(function (window, $) {
  / / data
  let data = 'atguigu.com'

  // A function that manipulates data
  function foo() { // Used to expose functions
    console.log(`foo() ${data}`The $()'body').css('background'.'red')}function bar() {// Used to expose functions
    console.log(`bar() ${data}`)
    otherFun() // Internal call
  }

  function otherFun() { // Internal private function
    console.log('otherFun()')}// Expose behavior
  window.myModule = {foo, bar}
})(window, jQuery)
Copy the code
index.html

<script type="text/javascript" src="Jquery - 1.10.1. Js"></script>
<script type="text/javascript" src="module4.js"></script>
<script type="text/javascript">
  myModule.foo()
</script>
Copy the code
  • Introduction of depend on
  • Is the cornerstone of modern module implementation
  • Multiple pages loadedjsProblem: one page introduces more than onejs“, there will be too many requests, fuzzy dependencies, difficult to maintain the problem.

Modular specification

CommonJS

CommonJS is divided into browser side and server side

The basic grammar

Define the exposed module: exports

exports.xxx = value
module.exports = value
Copy the code

Introduce the module: require

var module = require('Module name/module relative path')
Copy the code

When does the introduction of modules take place?

Server side: At run time, dynamic synchronization is introduced

Browser side: compile/translate/package the module before running (the dependent module has been included), run is packaged js generated, run time does not need to remotely introduce the dependent module.

AMD

AMD only exists on the browser side and relies on require.js

Define exposed modules: define

Define ([dependency module name],function(){returnModule object})Copy the code

Reference module: require

require(['module 1'.'2'.'module 3'].function(m1, m2){// Use the module object})
Copy the code

Configuration items

require.config({
  // Basic path
  baseUrl : 'js/'.// Identifies the mapping between names and paths
  paths : {
    'module 1' : 'modules/module 1'.'2' : 'modules/module 2'.'angular' : 'libs/angular'.'angular-messages' : 'libs/angular-messages'
  },
  // Non-AMD modules
  shim : {
    'angular' : {
        exports : 'angular'
    },
    'angular-messages' : {
        exports : 'angular-messages'.deps : ['angular']}}})Copy the code

CMD

CMD only exists in the browser and depends on sea-.js. At present, there is no official website.

Define exposed modules: define

define(function(require.module.exports){byrequireIntroduce dependency modules throughmodule/exportsTo expose the moduleexports.xxx = value
})
Copy the code

Reference modules: Use SeaJS

seajs.use(['module 1'.'2'])
Copy the code

ES6

ES6 has a modular implementation built in

Define the exposure module: export

// Expose an object
export defaultobject// Expose multiple
export var xxx = value1
export let yyy = value2

var xxx = value1
let yyy = value2
export {xxx, yyy}
Copy the code

Introduce the usage module: import

/ / the default module
import xxx  from 'Module path/module name'

// Other modules
import {xxx, yyy} from 'Module path/module name'
import * as module1 from 'Module path/module name'
Copy the code

The browser doesn’t recognize ES6’s modular syntax directly, so you need to use Babel to convert ES6 to ES5, but since the converted file also uses CommonJS, you need to use Browserify to package the file and convert it into a file that the browser can recognize.

One last word

If this article is helpful to you, or inspired, help pay attention to it, your support is the biggest motivation I insist on writing, thank you for your support.