由于Node.js平台是在后端运行JavaScript代码,所以,必须首先在本机安装Node环境。

学习node,首先要装node,和它的包管理工具,这两个都是傻瓜式安装,百度一下就安装了。

安装完之后,打开终端,用

  1. node -v

查看node版本

  1. npm -v

查看npm版本

以上就是学习node的准备。

node有两种模式:1、命令行模式   2、node交互模式

命令行模式:就是自己建一个js文件 然后用node+xxx.js  来执行此js文件

node 交互模式:就是在终端输入 node 按回车  就进入了node交互模式  我们可以在上面输入js代码   然后回车   会直接执行(按两次ctrl + c 可以退出node交互模式)

比如输入一个100+200    按回车,会直接打印出300

但是如果在js里写100+200  然后用node+xxx.js运行的话,不会打印出结果,如果想打印出结果,必须用console.log来打印,这也是命令行模式和node交互模式的一个区别

我们以后的js代码都要在严格模式下执行,所以没个js文件的开头 都要加上

  1. 'use strict'

但是,这样显得有些费劲,每个文件都要加,还有一种办法是给node  命令加参数

  1. node --use_strict xxx.js

这样就可以确保,js在严格模式下运行了。

下面建立一个文件加,叫nodeTest吧,里面建一个hello.js,内容是console.log("hello world");

然后打开终端  cd  +文件名

node  hello.js

就可以看到终端打印出了hello world,

好了,我们的第一个node程序写出来了!!!

当然,想要方便,我们需要选一个IDE来开发node

那么廖老师推荐的是我现在正在用的vsCode!!!

我已经比较了解了,但是有一点需要说一下,想要给某个工程目录建立.vscode文件,需要选择到该目录下,点击vscode左侧的调试按钮(蜘蛛状),然后点击上面的设置按钮,就可以建立.vscode文件,然后.vscode文件下有一个launch.json文件,是用来配置的

我们将hello.js改造一下

  1. 'use strict'
  2.  
  3. var s='hello';
  4.  
  5. function greet(name){
  6. console.log(s+','+name+'!');
  7. }
  8.  
  9. module.exports=greet;

上面代码将hello.js改造成一个模块,

用module.exports将greet方法暴露出来,那么在其它文件应该如何用它呢???

在同样的工程目录下建立一个main.js

  1. 'use strict'
  2.  
  3. //引入hello模块
  4. var greet=require("./hello");
  5.  
  6. var s="qinghai";
  7.  
  8. greet(s);//hello,qinghai!

注意到引入hello模块用Node提供的require函数

在使用require()引入模块的时候,请注意模块的相对路径

如果只写模块名:

  1. var greet = require('hello');

则Node会依次在内置模块、全局模块和当前模块下查找hello.js

然后调用了它!!!

可以把launch.json文件改一下

  1. {
  2. // 使用 IntelliSense 了解相关属性。
  3. // 悬停以查看现有属性的描述。
  4. // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
  5. "version": "0.2.0",
  6. "configurations": [
  7. {
  8. "type": "node",
  9. "request": "launch",
  10. "name": "Launch Program",
  11. "program": "${workspaceFolder}\\hello\\main.js"
  12. }
  13. ]
  14. }

将原来的hello.js改成main.js

然后点击蜘蛛(调试),点击上面绿色小三角  开始调试,就会打印出hello qinghai了。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

CommonJS规范

这种模块加载机制被称为CommonJS规范。在这个规范下,每个.js文件都是一个模块,它们内部各自使用的变量名和函数名都互不冲突,例如,hello.jsmain.js都申明了全局变量var s = 'xxx',但互不影响。

一个模块想要对外暴露变量(函数也是变量),可以用module.exports = variable;,一个模块要引用其他模块暴露的变量,用var ref = require('module_name');就拿到了引用模块的变量。

结论

要在模块中对外输出变量,用:

  1. module.exports = variable;

输出的变量可以是任意对象、函数、数组等等。

要引入其他模块输出的对象,用:

  1. var foo = require('other_module');

引入的对象具体是什么,取决于引入模块输出的对象。

深入了解模块原理

当我们编写JavaScript代码时,我们可以申明全局变量:

  1. var s = 'global';

在浏览器中,大量使用全局变量可不好。如果你在a.js中使用了全局变量s,那么,在b.js中也使用全局变量s,将造成冲突,b.js中对s赋值会改变a.js的运行逻辑。

也就是说,JavaScript语言本身并没有一种模块机制来保证不同模块可以使用相同的变量名。

那Node.js是如何实现这一点的?

其实要实现“模块”这个功能,并不需要语法层面的支持。Node.js也并不会增加任何JavaScript语法。实现“模块”功能的奥妙就在于JavaScript是一种函数式编程语言,它支持闭包。如果我们把一段JavaScript代码用一个函数包装起来,这段代码的所有“全局”变量就变成了函数内部的局部变量。

请注意我们编写的hello.js代码是这样的:

  1. var s = 'Hello';
  2. var name = 'world';
  3.  
  4. console.log(s + ' ' + name + '!');

Node.js加载了hello.js后,它可以把代码包装一下,变成这样执行:

  1. (function () {
  2. // 读取的hello.js代码:
  3. var s = 'Hello';
  4. var name = 'world';
  5.  
  6. console.log(s + ' ' + name + '!');
  7. // hello.js代码结束
  8. })();

这样一来,原来的全局变量s现在变成了匿名函数内部的局部变量。如果Node.js继续加载其他模块,这些模块中定义的“全局”变量s也互不干扰。

所以,Node利用JavaScript的函数式编程的特性,轻而易举地实现了模块的隔离。

但是,模块的输出module.exports怎么实现?

这个也很容易实现,Node可以先准备一个对象module

  1. // 准备module对象:
  2. var module = {
  3. id: 'hello',
  4. exports: {}
  5. };
  6. var load = function (module) {
  7. // 读取的hello.js代码:
  8. function greet(name) {
  9. console.log('Hello, ' + name + '!');
  10. }
  11.  
  12. module.exports = greet;
  13. // hello.js代码结束
  14. return module.exports;
  15. };
  16. var exported = load(module);
  17. // 保存module:
  18. save(module, exported);

可见,变量module是Node在加载js文件前准备的一个变量,并将其传入加载函数,我们在hello.js中可以直接使用变量module原因就在于它实际上是函数的一个参数:

  1. module.exports = greet;

通过把参数module传递给load()函数,hello.js就顺利地把一个变量传递给了Node执行环境,Node会把module变量保存到某个地方。

由于Node保存了所有导入的module,当我们用require()获取module时,Node找到对应的module,把这个moduleexports变量返回,这样,另一个模块就顺利拿到了模块的输出:

  1. var greet = require('./hello');

以上是Node实现JavaScript模块的一个简单的原理介绍。

module.exports vs exports

很多时候,你会看到,在Node环境中,有两种方法可以在一个模块中输出变量:

方法一:对module.exports赋值:

  1. // hello.js
  2.  
  3. function hello() {
  4. console.log('Hello, world!');
  5. }
  6.  
  7. function greet(name) {
  8. console.log('Hello, ' + name + '!');
  9. }
  10.  
  11. module.exports = {
  12. hello: hello,
  13. greet: greet
  14. };

方法二:直接使用exports:

  1. // hello.js
  2.  
  3. function hello() {
  4. console.log('Hello, world!');
  5. }
  6.  
  7. function greet(name) {
  8. console.log('Hello, ' + name + '!');
  9. }
  10.  
  11. function hello() {
  12. console.log('Hello, world!');
  13. }
  14.  
  15. exports.hello = hello;
  16. exports.greet = greet;

但是你不可以直接对exports赋值:

  1. // 代码可以执行,但是模块并没有输出任何变量:
  2. exports = {xxxxxxxxxxxxxx
  3. hello: hello,
  4. greet: greet
  5. };

如果你对上面的写法感到十分困惑,不要着急,我们来分析Node的加载机制:

首先,Node会把整个待加载的hello.js文件放入一个包装函数load中执行。在执行这个load()函数前,Node准备好了module变量:

  1. var module = {
  2. id: 'hello',
  3. exports: {}
  4. };

load()函数最终返回module.exports

  1. var load = function (exports, module) {
  2. // hello.js的文件内容
  3. ...
  4. // load函数返回:
  5. return module.exports;
  6. };
  7.  
  8. var exported = load(module.exports, module);

也就是说,默认情况下,Node准备的exports变量和module.exports变量实际上是同一个变量,并且初始化为空对象{},于是,我们可以写:

  1. exports.foo = function () { return 'foo'; };
  2. exports.bar = function () { return 'bar'; };

也可以写:

  1. module.exports.foo = function () { return 'foo'; };
  2. module.exports.bar = function () { return 'bar'; };

换句话说,Node默认给你准备了一个空对象{},这样你可以直接往里面加东西。

但是,如果我们要输出的是一个函数或数组,那么,只能给module.exports赋值:

  1. module.exports = function () { return 'foo'; };

exports赋值是无效的,因为赋值后,module.exports仍然是空对象{}

结论

如果要输出一个键值对象{},可以利用exports这个已存在的空对象{},并继续在上面添加新的键值;

如果要输出一个函数或数组,必须直接对module.exports对象赋值。

所以我们可以得出结论:直接对module.exports赋值,可以应对任何情况:

  1. module.exports = {
  2. foo: function () { return 'foo'; }
  3. };

或者:

  1. module.exports = function () { return 'foo'; };

最终,我们强烈建议使用module.exports = xxx的方式来输出模块变量,这样,你只需要记忆一种方法。

初学node node开发环境搭建 node模块化 commonJS原理的更多相关文章

  1. Linux虚拟机中 Node.js 开发环境搭建

    Node.js 开发环境搭建: 1.下载CentOS镜像文件和VMWare虚拟机程序; 2.安装VMWare——>添加虚拟机——>选择CentOS镜像文件即可默认安装带有桌面的Linux虚 ...

  2. 在windows环境下基于sublime text3的node.js开发环境搭建

    首先安装sublime text3,百度一堆,自己找吧.理论上sublime text2应该也可以.我只能说一句:这个软件实在是太强悍了. 跨平台,丰富的插件体系,加上插件基本上就是一个强悍的ide了 ...

  3. node.js 开发环境搭建

    node.js下载地址 https://nodejs.org/download/ windows系统建议下载 msi 安装完成配置环境变量(根据安装路径来) NODE_PATH=C:\Program ...

  4. windows下sublime text的node.js开发环境搭建

    首先安装sublime text3,百度一堆,自己找吧.理论上sublime text2应该也可以.我只能说一句:这个软件实在是太强悍了. 跨平台,丰富的插件体系,加上插件基本上就是一个强悍的ide了 ...

  5. angular2.0学习笔记1.开发环境搭建 (node.js和npm的安装)

    开发环境, 1.安装Node.js®和npm, node 6.9.x 和 npm 3.x.x 以上的版本. 更老的版本可能会出现错误,更新的版本则没问题. 控制台窗口中运行命令 node -v 和 n ...

  6. Windows下Node.js开发环境搭建

    1.http://nodejs.org/下载node.js运行环境安装 2.打开DOS命令行 .安装express框架 1 >npm install express 末尾显示如下为安装成功 .安 ...

  7. Windows下Node.js开发环境搭建-合适的开发环境

    1)生产环境中的Node.js应用 Windows + Linus 2)虚拟机工具 VirtualBox 虚拟机CentOS安装 3)xShell与xFtp(windows到linux文件传输) 4) ...

  8. Windows 下 Node.js 开发环境搭建

    1.利用CentOS Linux系统自带的yum命令安装.升级所需的程序库: sudo -s LANG=C yum -y install gcc gcc-c++ autoconf libjpeg li ...

  9. Node.js开发环境搭建

    1.安装express npm install express -g 2.express33.6以后把express-generator分离出来了,所以还需安装express-generator,否则 ...

随机推荐

  1. XPath库详解

    目录 xpath入门 获取节点 获取所有节点 获取子节点 获取父节点 属性匹配 根据属性值匹配节点 属性多值匹配 多属性匹配 文本获取 按序选择 节点轴选择 补充 xpath的运算符介绍 xpath轴 ...

  2. 统计学习方法 | 感知机 | python实现

    感知机是二类分类的线性分类模型,利用随机梯度下降法对基于误分类的损失函数进行极小化. 书中算法可以将所有样本和系数向量写成增广向量的形式,并将所有负样本乘以-1,统一形式,方便计算. (1)训练数据集 ...

  3. 第6章:使用Python监控Linux系统

    1.Python编写的监控工具 1).多功能系统资源统计工具dstat dstat是一个用Python编写的多功能系统资源统计工具,用来取代Linux下的vmstat,iostat,netstat和i ...

  4. 【Trie】The XOR Largest Pair

    [题目链接] https://loj.ac/problem/10050 [题意] 给出n个数,其中取出两个数来,让其异或值最大. [题解] 经典的01字典树问题. 首先需要把01字典树建出来. 然后对 ...

  5. RBAC授权

    RBAC RBAC使用rbac.authorization.k8s.io API Group 来实现授权决策,允许管理员通过 Kubernetes API 动态配置策略,要启用RBAC,需要在 api ...

  6. php 获取城市ip

    /** * 获取ip城市信息 * CreateBy XueSong * @param string $ip * @return array|bool|mixed */ function getCity ...

  7. 怎样快捷获取网页的window对象

    使用document.defaultView; document.defaultView === window 注意: 1. 如果当前文档不属于window对象, 则返回null; 2. docume ...

  8. [Tarjan系列] Tarjan算法求无向图的双连通分量

    这篇介绍如何用Tarjan算法求Double Connected Component,即双连通分量. 双联通分量包括点双连通分量v-DCC和边连通分量e-DCC. 若一张无向连通图不存在割点,则称它为 ...

  9. hdu 2680 Dijstra

    Choose the best route Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  10. hbulider 快捷键

    跳转到行        Ctrl + G   页首        Ctrl + Home   页尾        Ctrl + End   下一个选项卡        Ctrl + Tab   上一个 ...