webpack modular

table of Contents

1. Modular

2. The modular core

3.ESM

3.1 Scope independent modules

3.2 derivation module internal data

3.3 import external data module

3.3.1 Static Import

 3.3.2ESM Import Export - Example:

3.3.3 Dynamic introduced import ()

 4. backward compatible modular

5.CommonJS

5.1 Scope independent modules

5.2 Export module internal data

5.3 import external data module

Specification uses examples 5.4CommonJS

6.AMD

7.AMD——requireJS

7.1 Scope independent modules

7.2 derivation module internal data

7.3 import external data module

7.4AMD - requireJS uses examples

8.requireJS style of CommonJS

8.1 derivation module internal data

8.2 import external data module

CommonJS style example of 8.3requireJS

9.UMD


1. Modular

Modular is a modern front-end development has been an integral part of the. Also the back-end necessary.

The complex problem into relatively independent modules, this design can reduce procedural complexity and increase code reuse, but also conducive to teamwork development and post-maintenance and expansion.

From ECMAScript2015the beginning of the introduction of the concept of modules, we call: ECMAScript Module, referred to as:ESM。

2. The modular core

  • Independent scope - will effectively isolate code, the code will not influence each other between the modules
  • How to export internal data module - modular data access
  • If an external module to import data

3.ESM

From the ECMAScript2015/ECMAScript6start, JavaScriptthe native introduced the concept of modules, and now the mainstream browsers have very good support.

3.1 Scope independent modules

A file is the module, an independent scope, and export modules automatically in 严格模式case , namely: 'use strict'.

If the file is loaded through a modular, then:

  1. The file will have a separate scope;
  2. The default code inside the file is run in strict mode namely: 'use strict'a.

Strict Mode ( 'use strict'):

  • Variables must be declared before use;
  • No variable lift (pre-resolution mechanism).

3.2 derivation module internal data

Use exportstatements export internal data module.

// 导出单个特性
export let name1, name2, …, nameN;
export let name1 = …, name2 = …, …, nameN;
export function FunctionName(){...}
export class ClassName {...}

// 导出列表
export { name1, name2, …, nameN };

// 重命名导出
export { variable1 as name1, variable2 as name2, …, nameN };

// 默认导出
export default expression;
export default function (…) { … }
export default function name1(…) { … }
export { name1 as default, … };

// 模块重定向导出
export * from …;
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
export { default } from …;

3.3 import external data module

Importing divided into two modes

  • Static Import
  • Dynamic Import

3.3.1 Static Import

In the browser importstatement it can only be declared type="module"using the script of the label .

And import statements must be written in JS file the top;

import defaultExport from "module-name";
import * as name from "module-name";
import { export } from "module-name";
import { export as alias } from "module-name";
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";

Static import mode does not support lazy loading, importyou must be the very beginning of this module

document.onclick = function () {

    // import 必须放置在当前模块最开始加载
    // import m1 from './m1.js'

    // console.log(m1);

}

 3.3.2ESM Import Export - Example:

Project Path:

index.html: Note the use of the ESM modular, script tags must be type = "module" attribute.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <!-- 在浏览器中,import 语句只能在声明了 type="module" 的 script 的标签中使用。 -->
    <script type="module" src="./js/main.js"></script>
</body>
</html>

main.js:

important point:

  • File path must end '.js';
  • When you import a list of all variable names and variable names must export one-time, you do not want to eleven objects using an alias;
  •  default import can not add {} export;
  • When the modular redirect export (that is exported from another module or script file), the representation from the module from an existing script file export ...

//导入m1模块
//1.导出单个特性:因为不是默认导出,所以需要声明变量接收,且文件必须有.js结尾
import {cssFunc1,cssFunc2,cssFunc3,M1Class} from './m1.js';

// 2.导入列表::此处a,b,c必须和导出中的变量名一一对应
import {a,b,c} from './m1.js';

//3.重命名导出:导入导出的变量名需一一对象,想在导入时使用不同名字可使用别名, 变量名 as 别名
// import {name,pw} from './m1.js'
import {name as name1,pw as pw1} from './m1.js';

//4.默认导入:注意:default导入导出都不需要加{}
// import aa from './m1.js';
// import defaultFunc from "./m1.js"
// import defaultFunc2 from './m1.js';
import bb from './m1.js';

// 5.模块重定向导出
import * as obj from './m1.js'
import {v1,v2} from './m1.js';
import {value1,value2} from './m1.js';
import {default as defaultV} from './m1.js';


// 1.导出单个特性
let a1 = 10;
let m1Class = new M1Class();
m1Class.m1ClassFunc();

console.log("main.js",a1,cssFunc1,cssFunc2,cssFunc3);

//2.导入列表
console.log(a,b,c);//1 2 3

//3.重命名导出
// console.log(name,pw);//张三 1234
console.log(name1,pw1);//张三 1234

//4.默认导入
// defaultFunc();
// defaultFunc2();
// console.log(aa);
// console.log(bb);

//5.模块重定向导出
console.log(obj);//Module {…}
console.log(v1,v2);//2 3
console.log(value1,value2);//2 3
console.log(defaultV);//ƒ m2Func(){ console.log(v1+v2); }

m1.js:

console.log("m1模块...");

function css1(){
    console.log("m1模块下的css1方法");
}


//1.导出单个特性
export let cssFunc1 = css1;

export let cssFunc2 = function css2(){
    console.log("m1模块下的css2方法");
}

export function cssFunc3(){
    console.log("m1模块下的cssFunc3方法");
}

export class M1Class{
    constructor(){

    }
    m1ClassFunc(){
        console.log("m1模块下的m1ClassFunc");
    }
}

//2.导出列表
let a = 1,b=2,c=3;
export {a,b,c};

//3.重命名导出
let username = "张三";
let password = "1234";
export {username as name,password as pw};

//4.默认导出
let aa = 1;

// export default aa;
// export default function() { 
//     let defaultVal = 33;
//     console.log("defaultVal:"+defaultVal);
    
//  }
// export default function defaultFunc2() {
//     console.log("defaultFunc2方法");
// }
let bb = 2,cc = 3;
//不能同时导出多个。如export { bb as default,cc as default};
// export { bb as default};

// 5.模块重定向导出: from-从已经存在的模块、脚本文件…导出
export * from './m2.js';
export {v1,v2} from './m2.js';
export { v1 as value1, v2 as value2 } from './m2.js';
export { default } from './m2.js';

 m2.js:

let v1=2,v2=3;
export {v1,v2};
export default function m2Func(){
    console.log(v1+v2);
}

result:

3.3.3 Dynamic introduced import ()

  1. In addition, there is a dynamic similar function import(), which does not depend on type="module"the script tag.
  2. Keywords importcan be like calling a function to dynamically importing modules. In this way call, it will return a promise.
  3. Use async await delay loading is asynchronous, to use the default () method, derived as a function of time must export
  • Method 1: Method using promise object then
import('./m.js')
  .then(m => {
    //...
});
// 也支持 await
let m = await import('./m.js');

 

By a import()method of introducing return data will be packaged in an object, even if the defaulttrue

Example: The import () is derived from a Promise object.

M3.js loads the file is not in the initial page load, but the load when clicked.

m3.js:

let obj = {
    a:1,
    b:2
}

export default obj;

main.js: If you import via the import statement

//6.动态导入:通过import()方法导入,返回一个promise对象进行异步延迟加载
document.onclick = function(){
    //直接通过import导入会报错
    // import obj from 'm3.js';
    // console.log(obj);
    import('./m3.js').then(obj=>{
        console.log(obj);
        
    });
}

 result:

  • Second way: using async await delay loading

 Use async await delay loading is asynchronous, to use the default () method, derived as a function of time must export

m3.js:

function css(){
    console.log("css");
}

export default css;

main.js:

//使用async  await进行异步延迟加载
document.onclick = async function(){
    let m1 = await import('./m3.js');
    console.log(m1);
    m1.default();
}

result:

 

 4. backward compatible modular

  • CommonJS
  • AMD
  • UMD
  • ESM

Whether it is the kind of modular specifications, focusing on:

  • Independent module Scope
  • Export internal data module
  • External data import module

5.CommonJS

In the early front-end for modular and there is no standard, but is biased towards the application server has a stronger demand, CommonJS specification is a set of standardized modular server-side bias, NodeJS on the use of this specification .

NodeJS and distal JS is the same root, the V8 NodeJS parser, the ECMAscript most underlying language, based on this NodeJS extend a file, such as operating systems, networks, hard drives operating means other than the browser.

CommonJS backend modular specification, performed by operating the file system, the file system can not operate but the front end, the front end can not use CommonJS specification.

5.1 Scope independent modules

A file is the module, an independent scope.

CommonJS loading method is the use of synchronous mixed modular documents. Only after the successful modular load will continue down the implementation.

5.2 Export module internal data

By module.exportsor exportsderived internal data module objects.

Note: module.exportsor exports two methods can not be used simultaneously.

// a.js
let a = 1;
let b = 2;

module.exports = {
  x: a,
  y: b
}
// or
exports.x = a;
exports.y = b;

5.3 import external data module

By requireintroducing external module function data

// b.js
let a = require('./a');
a.x;
a.y;

Specification uses examples 5.4CommonJS

By nodeJS environment, using nodemon main.js start main.js.

m1.js:

let a = 1, b =2;
// module.exports = {
//     x:a,
//     y:b
// }

exports.l = a;
exports.m = b;

main.js:

let obj = require('./m1');
// console.log(obj);//{ x: 1, y: 2 }
console.log(obj);//{ l: 1, m: 2 }

6.AMD

Because some features CommonJS specification (based on the file system, synchronization is loaded), it does not apply to the browser, so further defined specifications apply to the browser

AMD(Asynchronous Module Definition)。AMD没有办法获取本地文件,因此使用异步文件加载方式实现模块化加载。

https://github.com/amdjs/amdjs-api/wiki/AMD

The browser and there is no specific code that implements the specification, we can be solved by some third-party libraries. As requireJS.

7.AMD——requireJS

Official website: https://requirejs.org/

Must be specified by the file entry in the data-main page;

// 1.html
<script data-main="scripts/main" src="https://cdn.bootcss.com/require.js/2.3.6/require.min.js"></script>

7.1 Scope independent modules

By a definemethod to define a block, and by generating a second independent scope callback parameters for this method

// scripts/Cart.js
define(function() {
  // 模块内部代码
})

7.2 derivation module internal data

Export module in two ways:

  • return way;
  • Use CommonJS style export

By returnderiving the internal data module: the method can be derived, an object other things;

// scripts/Cart.js
define(function() {
  return class Cart {
    add(item) {
      console.log(`添加商品:${item}`)
    }
  }
})

7.3 import external data module

Import list data via the front-dependent external module

// scripts/main.js
// 定义一个模块,并导入 ./Cart 模块
define(['./Cart'], function(Cart) {
  let cart = new Cart()
  cart.add({name: 'iphoneXX', price: 1000000})
})

7.4AMD - requireJS uses examples

  •  You must be in the page specified by the file entry-main Data ;
  • When the entry specifies the file using data-main, dynamically creates a script tag, then the file via ajax way (Method network request) to load the JS file to load (main.js), because the page must be run in a server environment ;
  • By definedefining a modular approach, and the isolation module code;
  • Export module: Mode 1: By re- returnderiving the internal data module; Second way: the CommonJS style derived;

index.html:

You must specify the entry data-main file

<body>
    <script data-main="js/main.js" src="js/require.js"></script>
</body>
</html>

require.js:

As the official website loads slowly, after execution, the JS and then copy the following address on the web page down, generating require.js files in the specified directory

https://cdn.bootcss.com/require.js/2.3.6/require.min.js

main.js:

When the import file, the file must be used in the brackets [] for the application

//导入模块化文件时,通过方法的参数获取到模块中导出的数据
//注意导入时,文件名需要使用中括号
define(['./m1'],function(Cart){
    let cart = new Cart()
        return cart.add({name: 'iphoneXX', price: 1000000})
    }
);

 m1.js:

Export modular data by way of return

define(function () {
    return class Cart {
        add(item) {
            console.log("m1模块");
            console.log(`添加商品:${item}`, item)
        }
    };
});

result:

 

8.requireJS style of CommonJS

require.jsAlso supports CommonJSstyle syntax

8.1 derivation module internal data

// scripts/Cart.js
define(['require', 'exports', 'module'], function(require, exports, module) {
  class Cart {
    add(item) {
      console.log(`添加商品:${item}`)
    }
  }
  exports.Cart = Cart;
})
// 忽略不需要的依赖导入
define(['exports'], function(exports) {
  class Cart {
    add(item) {
      console.log(`添加商品:${item}`)
    }
  }
  exports.Cart = Cart;
})
// 如果是依赖的导入为:require, exports, module,也可以省略依赖导入声明
define(function(require, exports, module) {
  class Cart {
    add(item) {
      console.log(`添加商品:${item}`)
    }
  }
  exports.Cart = Cart;
})

8.2 import external data module

//CommonJS风格导入导出模块化数据
define(function(require) {
    //注意如果导出的是类,则需要将对象中的类解构出来才能用
    let {Cart} = require('./m2');
    let cart = new Cart();
    
    cart.add({name: 'iphoneXX', price: 1000000})
  })

CommonJS style example of 8.3requireJS

m2.js:

// define(['require', 'exports', 'module'], function(require, exports, module) {
//     class Cart {
//       add(item) {
//             console.log("m2模块");
//             console.log(`添加商品:${item}`, item)
//       }
//     }
//     exports.Cart = Cart;
//   })

// // 忽略不需要的依赖导入
// define(['exports'], function(exports) {
//     class Cart {
//       add(item) {
//         console.log(`添加商品:${item}`,item)
//       }
//     }
//     exports.Cart = Cart;
//   })

  // 如果是依赖的导入为:require, exports, module,也可以省略依赖导入声明
  define(function(require, exports, module) {
    class Cart {
      add(item) {
        console.log(`添加商品:${item}`,item)
      }
    }
    exports.Cart = Cart;
  })

 main.js:

//CommonJS风格导入导出模块化数据
define(function(require) {
    //注意如果导出的是类,则需要将对象中的类解构出来才能用
    let {Cart} = require('./m2');
    let cart = new Cart();
    
    cart.add({name: 'iphoneXX', price: 1000000})
  })

9.UMD

Strictly speaking, UMDdoes not belong to a module specification, which is mainly used to process CommonJS, AMD, CMDthe differences in compatibility, module code is able to run properly at the front of the module under different environment

  • If the module determines a target object, and the type of export obejct is derived in nodeJS environment;
  • and a function to define define.amd is true, then the next AMD use;
  • After the judge will perform the export function in the self-executing;
  • AMD will be able to perform modular exported in the browser through the judgment, and the next and then be able to use the back-end nodeJS CommonJS specification modular Export
(function (root, factory) {
  	if (typeof module === "object" && typeof module.exports === "object") {
        // Node, CommonJS-like
        module.exports = factory(require('jquery'));
    }
    else if (typeof define === "function" && define.amd) {
      	// AMD 模块环境下
        define(['jquery'], factory);
    }
}(this, function ($) { // $ 要导入的外部依赖模块
    $('div')
    // ...
    function b(){}
    function c(){}

    // 模块导出数据
    return {
        b: b,
        c: c
    }
}));

 

Published 95 original articles · won praise 115 · views 120 000 +

Guess you like

Origin blog.csdn.net/qq_34569497/article/details/102579729
Recommended