初学node node开发环境搭建 node模块化 commonJS原理
由于Node.js平台是在后端运行JavaScript代码,所以,必须首先在本机安装Node环境。
学习node,首先要装node,和它的包管理工具,这两个都是傻瓜式安装,百度一下就安装了。
安装完之后,打开终端,用
node -v
查看node版本
用
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文件的开头 都要加上
'use strict'
但是,这样显得有些费劲,每个文件都要加,还有一种办法是给node 命令加参数
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改造一下
'use strict' var s='hello'; function greet(name){
console.log(s+','+name+'!');
} module.exports=greet;
上面代码将hello.js改造成一个模块,
用module.exports将greet方法暴露出来,那么在其它文件应该如何用它呢???
在同样的工程目录下建立一个main.js
'use strict' //引入hello模块
var greet=require("./hello"); var s="qinghai"; greet(s);//hello,qinghai!
注意到引入hello
模块用Node提供的require
函数
在使用require()
引入模块的时候,请注意模块的相对路径
如果只写模块名:
var greet = require('hello');
则Node会依次在内置模块、全局模块和当前模块下查找hello.js
然后调用了它!!!
可以把launch.json文件改一下
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}\\hello\\main.js"
}
]
}
将原来的hello.js改成main.js
然后点击蜘蛛(调试),点击上面绿色小三角 开始调试,就会打印出hello qinghai了。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CommonJS规范
这种模块加载机制被称为CommonJS规范。在这个规范下,每个.js
文件都是一个模块,它们内部各自使用的变量名和函数名都互不冲突,例如,hello.js
和main.js
都申明了全局变量var s = 'xxx'
,但互不影响。
一个模块想要对外暴露变量(函数也是变量),可以用module.exports = variable;
,一个模块要引用其他模块暴露的变量,用var ref = require('module_name');
就拿到了引用模块的变量。
结论
要在模块中对外输出变量,用:
module.exports = variable;
输出的变量可以是任意对象、函数、数组等等。
要引入其他模块输出的对象,用:
var foo = require('other_module');
引入的对象具体是什么,取决于引入模块输出的对象。
深入了解模块原理
当我们编写JavaScript代码时,我们可以申明全局变量:
var s = 'global';
在浏览器中,大量使用全局变量可不好。如果你在a.js
中使用了全局变量s
,那么,在b.js
中也使用全局变量s
,将造成冲突,b.js
中对s
赋值会改变a.js
的运行逻辑。
也就是说,JavaScript语言本身并没有一种模块机制来保证不同模块可以使用相同的变量名。
那Node.js是如何实现这一点的?
其实要实现“模块”这个功能,并不需要语法层面的支持。Node.js也并不会增加任何JavaScript语法。实现“模块”功能的奥妙就在于JavaScript是一种函数式编程语言,它支持闭包。如果我们把一段JavaScript代码用一个函数包装起来,这段代码的所有“全局”变量就变成了函数内部的局部变量。
请注意我们编写的hello.js
代码是这样的:
var s = 'Hello';
var name = 'world'; console.log(s + ' ' + name + '!');
Node.js加载了hello.js
后,它可以把代码包装一下,变成这样执行:
(function () {
// 读取的hello.js代码:
var s = 'Hello';
var name = 'world'; console.log(s + ' ' + name + '!');
// hello.js代码结束
})();
这样一来,原来的全局变量s
现在变成了匿名函数内部的局部变量。如果Node.js继续加载其他模块,这些模块中定义的“全局”变量s
也互不干扰。
所以,Node利用JavaScript的函数式编程的特性,轻而易举地实现了模块的隔离。
但是,模块的输出module.exports
怎么实现?
这个也很容易实现,Node可以先准备一个对象module
:
// 准备module对象:
var module = {
id: 'hello',
exports: {}
};
var load = function (module) {
// 读取的hello.js代码:
function greet(name) {
console.log('Hello, ' + name + '!');
} module.exports = greet;
// hello.js代码结束
return module.exports;
};
var exported = load(module);
// 保存module:
save(module, exported);
可见,变量module
是Node在加载js文件前准备的一个变量,并将其传入加载函数,我们在hello.js
中可以直接使用变量module
原因就在于它实际上是函数的一个参数:
module.exports = greet;
通过把参数module
传递给load()
函数,hello.js
就顺利地把一个变量传递给了Node执行环境,Node会把module
变量保存到某个地方。
由于Node保存了所有导入的module
,当我们用require()
获取module时,Node找到对应的module
,把这个module
的exports
变量返回,这样,另一个模块就顺利拿到了模块的输出:
var greet = require('./hello');
以上是Node实现JavaScript模块的一个简单的原理介绍。
module.exports vs exports
很多时候,你会看到,在Node环境中,有两种方法可以在一个模块中输出变量:
方法一:对module.exports赋值:
// hello.js function hello() {
console.log('Hello, world!');
} function greet(name) {
console.log('Hello, ' + name + '!');
} module.exports = {
hello: hello,
greet: greet
};
方法二:直接使用exports:
// hello.js function hello() {
console.log('Hello, world!');
} function greet(name) {
console.log('Hello, ' + name + '!');
} function hello() {
console.log('Hello, world!');
} exports.hello = hello;
exports.greet = greet;
但是你不可以直接对exports
赋值:
// 代码可以执行,但是模块并没有输出任何变量:
exports = {xxxxxxxxxxxxxx
hello: hello,
greet: greet
};
如果你对上面的写法感到十分困惑,不要着急,我们来分析Node的加载机制:
首先,Node会把整个待加载的hello.js
文件放入一个包装函数load
中执行。在执行这个load()
函数前,Node准备好了module变量:
var module = {
id: 'hello',
exports: {}
};
load()
函数最终返回module.exports
:
var load = function (exports, module) {
// hello.js的文件内容
...
// load函数返回:
return module.exports;
}; var exported = load(module.exports, module);
也就是说,默认情况下,Node准备的exports
变量和module.exports
变量实际上是同一个变量,并且初始化为空对象{}
,于是,我们可以写:
exports.foo = function () { return 'foo'; };
exports.bar = function () { return 'bar'; };
也可以写:
module.exports.foo = function () { return 'foo'; };
module.exports.bar = function () { return 'bar'; };
换句话说,Node默认给你准备了一个空对象{}
,这样你可以直接往里面加东西。
但是,如果我们要输出的是一个函数或数组,那么,只能给module.exports
赋值:
module.exports = function () { return 'foo'; };
给exports
赋值是无效的,因为赋值后,module.exports
仍然是空对象{}
。
结论
如果要输出一个键值对象{}
,可以利用exports
这个已存在的空对象{}
,并继续在上面添加新的键值;
如果要输出一个函数或数组,必须直接对module.exports
对象赋值。
所以我们可以得出结论:直接对module.exports
赋值,可以应对任何情况:
module.exports = {
foo: function () { return 'foo'; }
};
或者:
module.exports = function () { return 'foo'; };
最终,我们强烈建议使用module.exports = xxx
的方式来输出模块变量,这样,你只需要记忆一种方法。
初学node node开发环境搭建 node模块化 commonJS原理的更多相关文章
- Linux虚拟机中 Node.js 开发环境搭建
Node.js 开发环境搭建: 1.下载CentOS镜像文件和VMWare虚拟机程序; 2.安装VMWare——>添加虚拟机——>选择CentOS镜像文件即可默认安装带有桌面的Linux虚 ...
- 在windows环境下基于sublime text3的node.js开发环境搭建
首先安装sublime text3,百度一堆,自己找吧.理论上sublime text2应该也可以.我只能说一句:这个软件实在是太强悍了. 跨平台,丰富的插件体系,加上插件基本上就是一个强悍的ide了 ...
- node.js 开发环境搭建
node.js下载地址 https://nodejs.org/download/ windows系统建议下载 msi 安装完成配置环境变量(根据安装路径来) NODE_PATH=C:\Program ...
- windows下sublime text的node.js开发环境搭建
首先安装sublime text3,百度一堆,自己找吧.理论上sublime text2应该也可以.我只能说一句:这个软件实在是太强悍了. 跨平台,丰富的插件体系,加上插件基本上就是一个强悍的ide了 ...
- angular2.0学习笔记1.开发环境搭建 (node.js和npm的安装)
开发环境, 1.安装Node.js®和npm, node 6.9.x 和 npm 3.x.x 以上的版本. 更老的版本可能会出现错误,更新的版本则没问题. 控制台窗口中运行命令 node -v 和 n ...
- Windows下Node.js开发环境搭建
1.http://nodejs.org/下载node.js运行环境安装 2.打开DOS命令行 .安装express框架 1 >npm install express 末尾显示如下为安装成功 .安 ...
- Windows下Node.js开发环境搭建-合适的开发环境
1)生产环境中的Node.js应用 Windows + Linus 2)虚拟机工具 VirtualBox 虚拟机CentOS安装 3)xShell与xFtp(windows到linux文件传输) 4) ...
- Windows 下 Node.js 开发环境搭建
1.利用CentOS Linux系统自带的yum命令安装.升级所需的程序库: sudo -s LANG=C yum -y install gcc gcc-c++ autoconf libjpeg li ...
- Node.js开发环境搭建
1.安装express npm install express -g 2.express33.6以后把express-generator分离出来了,所以还需安装express-generator,否则 ...
随机推荐
- vue之多页面的开发
我们平常用vue开发的时候总觉得vue好像就是专门为了单页面应用而诞生的,其实不是.因为vue在工程化开发的时候很依赖webpack,而webpack是将所有的资源整合到一块,弄成一个单页面.但是vu ...
- 指针生成网络(Pointer-Generator-Network)原理与实战
指针生成网络(Pointer-Generator-Network)原理与实战 阅读目录 0 前言 1 Baseline sequence-to-sequence 2 Pointer-Generat ...
- S4VM解析
S4VM解析 2018年08月03日 15:20:59 stringlife 阅读数 1233 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...
- MySQL SQL Training
源于知乎:50道SQL练习题 一.表数据 1.学生表——Student ),Sname ),Sage )); ' , '赵雷' , '1990-01-01' , '男'); ' , '钱电' , '1 ...
- LocalDate与Date转化
// 01. java.util.Date --> java.time.LocalDateTimepublic void UDateToLocalDateTime() { java.util.D ...
- 服务返回的json数据过大,nginx无法返回给client
现象:请求同样的服务器,N多个接口中,只有一个接口未返回:从日志看,请求已到后端服务,并返回 解决方案:配置nginx缓冲大小 ###Nginx的缓冲区的大小 proxy_buffer_size 5m ...
- STM32-移植FATFS的NANDFLASH驱动
一,建立工程FATFS源码 1,在http://elm-chan.org/fsw/ff/00index_e.html上下载ff007c.zip,并把ff007c.zip里面的 src文件夹复制到D:\ ...
- wireshark 分析过滤数据
1.过滤IP,如来源IP或者目标IP等于某个IP例子:ip.src eq 192.168.1.107 or ip.dst eq 192.168.1.107或者ip.addr eq 192.168.1. ...
- 【Java并发】基础
一.概述 1.1 线程与进程区别 1.2 多线程引发的性能问题 二.多线程创建方式 2.1 第一种-继承Thread类 2.2 第二种-实现Runnable接口 2.3 第三种-实现Callable接 ...
- Linux之ln文件创建链接
ln命令用来为文件创建链接,链接类型分为硬链接和软链接(符号链接)两种 1)软连接和Windows系统中的快捷方式有点类似 2)硬链接,相当于多了一个文件名指向同一块内存空间,目录无法创建硬链接,不可 ...