JS模块化规范

JS模块化

  • 什么是模块?

    1. 将一个复杂的程序依据一定的规则(规范)封装成几个模块(文件), 并进行组合在一起
    2. 块的内部数据/实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信
  • 模块的组成

    1. 数据——>内部属性
    2. 操作数据的行为——>内部函数

我们,通常说的模块化,其实是指js的模块化。现在流行的模块化规范有以下几种:CommonJs、AMD、CMD、ES6模块化。本篇文章,我们来介绍下CommonJS以及ES6模块化相关的知识,其余两种大家自行了解。

CommonJS模块化

  • 规范
  1. 服务器端:NodeJs实现了CommonJS规范,并且在服务器端模块的加载是运行时同步加载的
  2. 浏览器端:Browserify(CommonJS的浏览器端的打包工具)实现了CommonJS规范,在浏览器端模块需要提前编译打包处理
  • 基本语法
  1. 暴露模块:module.exports = value 或者 exports.xxx = value。其实暴露的就是一个exports对象,在其他文件中可以直接使用exports对象。
  2. 引入模块:require(xxx),如果是引入第三方模块,xxx是模块名;自定义模块,xxx是模块文件路径
  • 区别Node与Browserify
    Node.js运行时是同步模块的,Browserify是在编译时就会加载打包合并require的模块

下面以一个案例来解释下:
首先我们创建一个文件夹来存放测试代码,然后cd到该目录里面,使用npm init命令初始化一个工程,这样就会自动生成package.json文件。之后,分别创建3个js文件来测试。
JS模块化规范_第1张图片

  • module1.js
    module.exports = {
      foo() {
        console.log('moudle1 foo()')
      }a:10
    }
//如果一个文件中有两个module.exports,下面的会覆盖上面的
// module.exports={
  // a:10
// }
  • module2.js
    module.exports = function () {
      console.log('module2()')
    }
    
  • module3.js
    exports.foo = function () {
      console.log('module3 foo()')
    }
    
    exports.bar = function () {
      console.log('module3 bar()')
    }
    

在app.js文件中引入模块

let module1 = require('./modules/module1')
let module2 = require('./modules/module2')
let module3 = require('./modules/module3')//等价于require('./modules/module3.js'),js可以省略

module1.a
console.log(module1.a)

module2()

module3.bar()

最后,我们使用node命令执行app.js文件,发现原本写在module1.js、module2.js、module3.jsi里面的逻辑成功执行了,说明这3个模块确实被导入app.js中了。
接下来,有一个问题了,刚刚我们是使用node来执行js文件的,如果我们直接用浏览器执行app.js文件是会报错的,因为浏览器只认识js代码,require这些关键字浏览器是不认识的。例如,我们新建一html文件,然后用浏览器执行这个html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <script src="app.js"></script>
    
</body>
</html>

JS模块化规范_第2张图片

如果我们想要使用浏览器来执行app.js该怎么办呢?这就需要另一个工具——browserify

  • . 下载browserify

    • 全局: npm install browserify -g
    • 局部: npm install browserify --save-dev

    -dev表示,我们只是在开发环境中需要browserify,生产环境是不需要browserify,因为生产环境已经是运行在浏览器中的。

执行了上面两句代码之后,package.json中就会有browserify的依赖

{
  "name": "modulejstest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "browserify": "^17.0.0"
  }
  //如果不加-dev,那么browserify依赖在dependencies闭包下,加了就在devDependencies闭包下
   // "dependencies": {
  //   "browserify": "^17.0.0"
  // }
}

最后,我们执行如下命令:然后引入bundle.js文件到html中,这样浏览器就不会报错了。

 browserify app.js -o dist/bundle.js

ES6模块化

相比起CommonJs,es6的模块化就十分的简单了,首先我们需要安装几个工具:

  1. 安装babel-cli, babel-preset-es2015和browserify

    • npm install babel-cli browserify -g
    • npm install babel-preset-es2015 --save-dev
  2. 在工程根目录下定义.babelrc文件

{
    "presets": ["es2015"]
  }
  1. 编写测试js代码
export function foo() {
  console.log('module1 foo()');
}
export let bar = function () {
  console.log('module1 bar()');
}
export const DATA_ARR = [1, 3, 5, 1]
let data = 'module2 data'
    
    function fun1() {
      console.log('module2 fun1() ' + data);
    }
    
    function fun2() {
      console.log('module2 fun2() ' + data);
    }
    
    export {fun1, fun2}
//一个文件只能由一个export default
export default {
    name: 'Tom',
    setName: function (name) {
      this.name = name
    }
  }

在app.js文件中引入上述文件

import {foo,DATA_ARR}from './module1'
import { fun1,fun2 } from './module2'
import test from'./module3' //使用export default暴露的模块不用写{},任意取个名字即可

foo()
fun1()
fun2()

console.log("test--->"+test.name)
test.setName("brett")
console.log("test--->"+test.name)
console.log(DATA_ARR)
  1. 编译
  • 使用Babel将ES6编译为ES5代码(但包含CommonJS语法) : babel modules -d js/lib
  • 使用Browserify编译js : browserify js\lib\app.js -o dist/bundle.js

注意:如果要使用node执行js文件必须使用babel进行编译,否则会报错的,如果要在浏览器执行js代码,除了使用babel编译外,还要使用Browserify编译。
工程目录如下:
JS模块化规范_第3张图片

你可能感兴趣的:(前端,javascript,前端)