三、了解前端模块化系列(2)——模块化规范-CommonJS

222 阅读3分钟

了解前端模块化系列内容:
三、了解前端模块化系列(1)——模块化的理解
三、了解前端模块化系列(2)——模块化规范-CommonJS
三、了解前端模块化系列(3)——模块化规范-AMD
三、了解前端模块化系列(4)——模块化规范-CMD & ES6
三、了解前端模块化系列(5)——模块化规范-UMD & 总结(CommonJS AMD CMD ES6 UMD)

三、模块化规范

3.1 CommonJS

3.1.1 概念

web304-前端模块化-4.1.1概念.png

3.1.2 特点

web304-前端模块化-4.1.2特点.png

3.1.3 基本语法

  1. 暴露模块:
    module.exports = value
    exports.xxx = value
  2. 引入模块:
    require(第三方模块名)
    require(自定义模块文件路径)
  3. What is CommonJS 暴露的模块?

web304-前端模块化-4.1.3基本语法-3.What is CommonJS 暴露的模块?.png

  1. 通过 module.exports 输出变量 x 和函数 addX

    // example.js
    var x = 5
    var addX = function (value) {
      return value + x
    }
    // 通过 module.exports 输出变量 x 和函数 addX
    module.exports.x = x
    module.exports.addX = addX
    
  2. 加载模块文件:读入并执行一个 JavaScript 文件,返回该模块的 exports 对象;
    没有指定模块,报错。

    var example = require('./example.js') //如果参数字符串以“./”开头,则表示加载的是一个位于相对路径
    console.log(example.x) // 5
    console.log(example.addX(1)) // 6
    

3.1.4 模块的加载机制

  • CommonJS 模块的加载机制是:
    输入的是被输出的值的拷贝。
  • 也就是说,
    一旦输出一个值,模块内部的变化就影响不到这个值。
  • 这与 ES6 模块化有重大差异(下文会介绍)

例子:

lib.js

// lib.js
var counter = 3
function incCounter() {
  counter++
}
module.exports = {
  counter: counter, // 内部变量counter
  incCounter: incCounter // 改写这个变量的内部方法incCounter
}

main.js

// main.js
var counter = require('./lib').counter
var incCounter = require('./lib').incCounter

console.log(counter) // 3
incCounter()
console.log(counter) // 3
// counter是一个原始类型的值,会被缓存。
// 除非写成一个函数,才能得到内部变动后的值。

3.1.5 服务器端实现

  1. npm init

    package.json

    {
      "name": "commonjs-node",
      "version": "1.0.0",
      "description": "",
      "main": "app.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "djsz3y",
      "license": "ISC"
    }
    
  2. 下载第三方模块:
    npm install uniq --save // 用于数组去重

  3. 定义模块代码

    //module1.js
    module.exports = {
      msg: 'module1',
      foo() {
        console.log(this.msg)
      }
    }
    
    //module2.js
    module.exports = function () {
      console.log('module2')
    }
    
    //module3.js
    exports.foo = function () {
      console.log('foo() module3')
    }
    exports.arr = [1, 2, 3, 3, 2]
    
    // app.js文件
    // 引入第三方库,应该放置在最前面
    let uniq = require('uniq')
    let module1 = require('./modules/module1')
    let module2 = require('./modules/module2')
    let module3 = require('./modules/module3')
    
    module1.foo() //module1
    module2() //module2
    module3.foo() //foo() module3
    console.log(uniq(module3.arr)) //[ 1, 2, 3 ]
    
  4. node app.js

    输出:

    ..\commonJS-node>
    node app.js
    module1
    module2
    foo() module3
    [ 1, 2, 3 ]
    

3.1.6 浏览器端实现

  1. npm init & 创建项目结构

    |-browserify-test
      |-js
        |-dist //打包生成文件的目录
        |-src //源码所在的目录
          |-module1.js
          |-module2.js
          |-module3.js
          |-app.js //应用主源文件
      |-index.html //运行于浏览器上
      |-package.json
        {
          "name": "browserify-test",
          "version": "1.0.0",
          "description": "",
          "main": "index.js",
          "scripts": {
            "test": "echo \"Error: no test specified\" && exit 1"
          },
          "author": "djsz3y",
          "license": "ISC"
        }
    
  2. 下载 browserify

    1. 全局: npm install browserify -g
    2. 局部: npm install browserify --save-dev
  3. 定义模块代码

    //module1.js
    module.exports = {
      msg: 'module1',
      foo() {
        console.log(this.msg)
      }
    }
    
    //module2.js
    module.exports = function () {
      console.log('module2')
    }
    
    //module3.js
    exports.foo = function () {
      console.log('foo() module3')
    }
    exports.arr = [1, 2, 3, 3, 2]
    
    // app.js文件
    // 引入第三方库,应该放置在最前面
    // let uniq = require('uniq')
    let module1 = require('./module1')
    let module2 = require('./module2')
    let module3 = require('./module3')
    
    module1.foo() //module1
    module2() //module2
    module3.foo() //foo() module3
    // console.log(uniq(module3.arr)) //[ 1, 2, 3 ]
    
  4. 打包编译 app.js (借助 browserify )

    browserify js/src/app.js -o js/dist/bundle.js
    
  5. 页面使用引入 bundle.js

    index.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title></title>
      </head>
      <body></body>
      <script type="text/javascript" src="js/dist/bundle.js"></script>
    </html>
    
  6. 浏览器打开 index.html

    输出:

    bundle.js:15 module1
    bundle.js:20 module2
    bundle.js:24 foo() module3
    

友情链接