node : 2 模块化(演变)

1.

js中级中讲到了模块化演变,后续的演变就是,出现了AMD、CMD、CommonJS等模块化标准,然后前端模块化进入了大爆发时代。

什么是JS模块化

js模块化就是指js代码分成不同的模块,模块内部定义变量作用域只属于模块内部,模块之间变量命名不会相互冲突。各个模块相互独立,而且又可以通过某种方式相互引用协作。

模块化的标准

目前前端流行的几个模块化标准:CommonJs标准(node的方案)、AMD、CMD、ES6模块方案。

未来的趋势肯定是ES6的标准方案会逐渐统一。但是AMD、CMD标准跟CommonJs的标准相差不大,需要我们都研究一下。

模块化的原理:(作用:通过模块来实现变量的作用域隔离,以实现 防止变量的冲突!)

Node.js的强大

Node.js有一个简单的模块加载系统,遵循的是CommonJS的规范。在Node.js中,文件和模块是一一对应的。(每个文件被视为一个独立的模块)。

Node在加载JS文件时,自动给JS文件包装上定义模块的头部和尾部。

扫描二维码关注公众号,回复: 8925726 查看本文章

// (模块化)思想进阶之路
2.requirejs入门(amd里的,了解)

requirejs的使用:

  1. requirejs下载
  2. 把requirejs直接引入到html中
    <script src="js/require.js"></script>
  3. 设置当前页面的js入口文件
    <script src="js/require.js" data-main="js/main"></script>
    data-main属性:指定网页程序的主模块。(当前整个网页的入口代码)
  4. 引用其他模块的文件

ps:

  • amd的东西很少,就做了两件事:①模块怎么定义;②模块怎么使用。
  • amd是异步的模块规范
  • 相关信息可以去GitHub上amd查找

示例代码:

1. learn_2_myfirstdemo.html

<!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>requirejs实现amd标准的应用</title>
</head>
<body>
    <div id="box"></div>
    <script src="lib/require.js" data-main="learn_2_index.js"></script>
</body>
</html>

2. learn_2_index.js

// 注意!要进行require的config配置路径映射。
require.config({
    paths: {
        jquery: 'lib/jquery-3.4.1', // 注意.js这个后缀不要加上
        show: 'learn_2_show'  // 配置自己定义模块的路径
    }
});

// define定义一个模块 (ps:若不用require.config进行路径配置,那么在[]里的对应模块就要写上路径,比如如果不在require.config中对show进行配置,那么[]里的show就要写成“"./show.js"”)
define(['jquery', 'show'], function($, show) { // function里的参数是对应模块的返回
    'use strict';
    $("#box").html("<h1>第一个requirejs应用</h1>");
    show.do();
}); 
// []:依赖的模块名(注意:小写)
// 由于在jquery-3.4.1.js代码中有:
// if ( typeof define === "function" && define.amd ) {
// 	define( "jquery", [], function() {
// 		return jQuery;
// 	} );
// }
// 其返回一个jQuery对象,故用$来接收它。
// 自定义模块learn_2_show.js返回一个对象,此处用show来接收

3.  learn_2_show.js


// 一个自己定义的模块
define([
    'jquery'
], function ($) {
    'use strict';
    // 对外输出一个东西(此处为返回一个对象)
    return {
        do: function () {
            console.log("我是show模块");
            $(document.body).append("<div>我是动态生成的!</div>");
        }
    }

});

运行演示:

3.CMD与Sea.js

4.node

1.引入自定义模块

1.npmjs.com 网站有很多node的第三方模块。

如 string-width :Get the visual width of a string - the number of columns required to display it

使用:

  1. 安装 npm install string-width
    会在当前工作目录生成文件夹 node_modules,下载的就在里面;
    同时在package.json(用 npm init生成的,用于管理本项目的package的配置文件)里会自动添加:

      "dependencies": {

        "string-width": "^4.2.0"

      }

  2. 使用

示例代码:

// 4:自定义模块
const stringw = require("string-width");
var num = stringw("lili");
console.log(num); // 4

2.自己写的模块

示例代码:

自定义math模块:

// 一个文件就是一个模块

let math = {
    add: function(a, b){
        return a + b;
    }
}

module.exports = math; // 导出

引入自定义math模块:

// console.log(module);

// 引入 learn_4_math.js文件对应的模块。
// 引入learn_4_math模块,t就指向引入的模块
let t = require('./learn_4_math'); // ! let和var的区别自己查

// 调用learn_4_math模块的add方法
console.log(t.add(9, 10));  // 运行结果 控制台输出 19

ps:module有一个paths的属性,如下图,然后node找的路径从(图里)上依次到下。(实际是从本目录找,到上级目录,一直到根目录)
示例:

        自定义是搜索最慢的,当然第二次就在缓存里了。

2.引入内置模块

内置模块有很多,比如:断言模块、缓冲器模块、等等(详见官网nodejs.cn/api/)),注意其中的控制台(console)模块,可以直接用。

ps:文件模块中,又分为3类模块。这三类文件模块以后缀来区分,Node.js会根据后缀来决定加载方法。

  • .js 通过fs模块同步读取js文件进行编译执行。
  • .node 通过c/c++进行编写的Addon。通过diopen方法进行加载。
  • .json 读取文件,调用JSON.parse解析加载。

示例代码:

// 1.引入内置的模块
const path = require('path') // const:定义一个常量,如果是简单类型,那么值不能修改;如果是引用类型,则变量指向的内存地址不变。

var t = path.join(__dirname, __filename);  // path的join方法作用:把多个路径粘结在一起,并规范化生成路径。(详请查阅文档)
console.log(t); // C:\Users\lisa\Documents\My\Learn_CodeTych\Vscode\node2_laoma\C:\Users\lisa\Documents\My\Learn_CodeTych\Vscode\node2_laoma\learn_5_nodemodule_require.js

3.引入文件模块

示例代码:

// 2. 引入文件模块 (相对路径和绝对路径都可以)
const math = require("./learn_4_math.js"); // ps:文件后缀可以加,也可以不加,但推荐 加上后缀,这样效率高。(因为当不加后缀时,执行时引擎会尝试加js后缀、json后缀或.node(c/c++进行编写的Addon,通过diopen方法进行加载)后缀等,若没有找到对应的,就报错。
console.log(math.add(9, 9)); // 18

// 引入绝对路径
const math2 = require("C:/Users/lisa/Documents/My/Learn_CodeTych/Vscode/node2_laoma/learn_4_math.js");
console.log(math2.add(1, 4));  // 5

4.引入 文件夹模块(尽量少用!)

示例代码:

learn_5_nodemodule_require.js

// 3.引入 文件夹模块 (尽量少用!性能不好)
// step1:到根目录的package.json文件中去找main的配置节点。
// step0:创建package.json文件: (在该package.json中,我们的入口文件名叫index.js;则后续寻找时就用require中给的路径加这个文件名(index.js)来找。)
            // 用npm init自动初始化一个配置文件
            //(初始化过程中的相关配置按自己需要写:entry point 指入口文件;License(协议)写MIT)
            // 创建结束后就会生成一个叫package.json的文件
            // 或者直接用命令npm init -y 默认生成
            // ps:如果内部未配置好main,具体还有别的找法,详查(略)。(要用package就写好,别给自己找麻烦)
const m = require('./'); // 因为index.js和他在同一个目录,故直接写./
m.show(); // index.js show!

const n = require("./learn_5"); // 此时我们在当前路径下的文件夹中创建了一个index.js,则此时的路径为./learn_5
n.myshow(); // learn_5: myshow

package.json

{
  "name": "node2_laoma",
  "version": "1.0.0",
  "description": "learn_node",
  "main": "index.js",
  "directories": {
    "lib": "lib"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "MIT"
}

当前目录下的index.js

// module.exports 和 exports是一样的;两个不要混用
exports.show = function(){
    console.log("index.js show!");
};

// 对外输出的是exports这个对象。

当前目录下的文件夹learn_5下的index.js

exports.myshow = function(){
    console.log("learn_5: myshow");
};
发布了191 篇原创文章 · 获赞 1 · 访问量 4693

猜你喜欢

转载自blog.csdn.net/bluebloodye/article/details/103130034