初识node.js
node.js, 在我的理解中呢, 就是跑在服务器的js , 他是一个事件驱动I/O服务端javascript 环境, 基于Google的v8 引擎, v8引擎执行js的速度非常快, 性能非常好~ 所以呢, 前台代码搭配 node 去开发, 是非常舒服的~ 其次呢, 与java php这些语言比起来, node更加轻便, 能部署一些高性能的服务~
那么我们怎么用node运行我们的js代码呢, 比如我们有一个叫firstNode.js的文件
, OK, 跑一下 , 本文假设你已经安装并成功安装了node.js 包。
打开命令提示符窗口, 找到js 的父文件夹位置
, 执行js文件的方法是 node + 空格 + js 文件全称。 此时我们看到, node 已经帮我们执行了我们的js代码。
接下来, 我们想要写一个简单的服务器, 那么在创建服务器之前, 我们应该先了解下node 应用是由哪几个部分组成的 ?
1) 引入required 模块: 我们可以使用require 指令来载入Node.js模块 (例如 fs呀, http 呀..)
2) 创建服务器: 服务器可以监听客户端的请求, 类似于Apache, Nginx等Http服务器。
3) 连接请求与响应请求: 服务器很容易创建, 也就是一句creatserver(), 客户端可以使用浏览器或中断发送http请求, 服务器接收请求后返回响应数据。
接下来呢, 我们可以使用http.creatserver() 的方法创建服务器, 然后使用listen方法绑定5212端口(5212可不是我的手机锁密码)。 然后我们写一个方法通过request, response参数来接收和响应数据。
实例如下, 这个js文件我们命名为server.js 文件吧
1 var http = require('http'); // 加载http模块, node里面用到什么加载什么 2 http.createServer(function(req, res) { 3 // 首先 我们发送http 头部, 设置http状态码200的时候, 成功发送, 内容类型为 text/plain 4 res.writeHead(200, { 5 'Content-Type': 'text/plain' 6 }); 7 // 发送响应数据 'hello, 我是杨帅' 8 res.end('hello, 我是杨帅\n'); 9 }).listen(5212); 10 console.log('node 已经运行, 快去页面请求端口号吧');
然后我们在命令行去执行他
可以看到, 这是没问题的。
说明我们的js代码已经跑起来了, 给5212端口添加的监听事件和会调函数应该也是OK的~
然后呢, 我们去页面看一下, 当我们访问 本地的5212端口时候 - ->
ie浏览器的编码有点尴尬, 我们换谷歌
万能的npm
这个是不是很神奇呢。 我们只要访问node 监听的端口号, 就能触发回调, 把res.end()返回的数据, 返回给页面。
ok, 闲话不多说, 我们来了解下面试经常会遇到的npm, npm究竟是什么, 与node 又有什么关系呢~
NPM的全称是Node Package Manager,是一个NodeJS包管理和分发工具,已经成为了非官方的发布Node模块(包)的标准。
Nodejs自身提供了基本的模块,但是开发实际应用过程中仅仅依靠这些基本模块则还需要较多的工作。幸运的是,Nodejs库和框架为我们提供了帮助,让我们减少工作量。但是成百上千的库或者框架管理起来又很麻烦,有了NPM,可以很快的找到特定服务要使用的包,进行下载、安装以及管理已经安装的包。
其实npm 是与 node 一起安装的包管理工具, 能解决nodeJs 部署上的很多问题, 看到这里我们会不会恍然大悟, 原来npm 是一个node 的包的管理的工具, 是配合nodeJs来使用的一个管理器。使用它可以极大的方便我们的开发~
用它的目的无非是 ① 下载别人的包到本地用 ② 下载安装别人的命令行程序到本地用 ③ 光偷别人的总不对, 它允许把你的包或者命令行程序上传到npm服务器供别人使用。
现在的话, 新版的node 已经集成了npm, 所以我们安装node 的时候, npm 也一并安装好了, 宝宝们怎么检测自己的npm 是否安装完成呢? 我们可以打开命令行
输入npm -v 来检查npm的版本号
如果是window 系统的话, 我们可以使用
npm install npm -g 来升级我们的npm, 但是国内直接使用npm的官方镜像是非常非常慢的, 比如我现在就卡在那里了, 那么没有解决办法么, 有的, 我们可以使用淘宝npm镜像。
那么淘宝npm镜像又是什么呢, 它是一个完整的npmjs.org 镜像, 你可以用此代替官方版本(只读的哦), 同步频率目前为10分钟一次以保证尽量与官方服务同步~
淘宝镜像方法 -->
cnpm install npm -g(使用淘宝定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm)
我们还可以使用npm 命令来安装模块
exmple
今天太阳好 我想安装一个express模块 (node.js 里的web框架模块)
我们可以 npm install express 这样就成功安装了express 模块
特别注意的是 这样安装好之后, express 包就直接放在了工程目录下的node_modules目录中, 有过node开发web的小伙伴, 肯定会特别熟悉这个文件夹啦~ 因此呢在代码中我们只需要通过require('express')的方式就好, 无需制定第三方路径。
npm 包安装的分为本地安装和全局安装, 从敲的命令行来看呢, 差别就只是有没有 -g 啦~
如 npm install express 和 npm install express -g 这点比较好理解~
npm是一个非常强大的包管理器,基本上前端需要的插件和框架在这上面都有,然而使用npm时有时候会出现error以及无法下载的情况, 比如报错
npm err! Error: connect ECONNREFUSED 127.0.0.1:8087
会直接导致我们的npm install 停止工作, 那么解决方法呢, 也是一行代码搞定
npm config set proxy null (这句话的意思是把node默认的代理 proxyhttp://127.0.0.1.8087 干掉, 什么报错就干掉什么TT~ )
本地安装的话, 会把安装包放在./node_modules下(运行npm时所在的目录)
如果没有 node_modules 目录,会在当前执行 npm 命令的目录下生成 node_modules 目录。
然后我们想用这些down 下来的包的时候, 就可以直接require(‘express’) 这样去引啦。
我们使用全局来安装express 为例
npm install express -g
那么输出
express@4.13.3 node_modules/express ├── escape-html@1.0.2 ├── range-parser@1.0.2 ├── merge-descriptors@1.0.0 ├── array-flatten@1.1.1 ├── cookie@0.1.3 ├── utils-merge@1.0.0 ├── parseurl@1.3.0 ├── cookie-signature@1.0.6 ├── methods@1.1.1 ├── fresh@0.3.0 ├── vary@1.0.1 ├── path-to-regexp@0.1.7 ├── content-type@1.0.1 ├── etag@1.7.0 ├── serve-static@1.10.0 ├── content-disposition@0.5.0 ├── depd@1.0.1 ├── qs@4.0.0 ├── finalhandler@0.4.0 (unpipe@1.0.0) ├── on-finished@2.3.0 (ee-first@1.1.1) ├── proxy-addr@1.0.8 (forwarded@0.1.0, ipaddr.js@1.0.1) ├── debug@2.2.0 (ms@0.7.1) ├── type-is@1.6.8 (media-typer@0.3.0, mime-types@2.1.6) ├── accepts@1.2.12 (negotiator@0.5.3, mime-types@2.1.6) └── send@0.13.0 (destroy@1.0.3, statuses@1.2.1, ms@0.7.1, mime@1.3.4, http-errors@1.3.1)
我们可以看到, 这样第一行就输出了安装的版本号, 和安装的位置。
我们同样可以通过 npm ls -g 来查看我们所以的全局安装的模块和版本号
大家应该对package.json 这个文件不陌生, 它位于模块的目录下, 用于定义包的属性, 接下来让我们来看下 express 包的 package.json 文件,位于 node_modules/express/package.json 内容:
{ "name": "express", "description": "Fast, unopinionated, minimalist web framework", "version": "4.13.3", "author": { "name": "TJ Holowaychuk", "email": "tj@vision-media.ca" }, "contributors": [ { "name": "Aaron Heckmann", "email": "aaron.heckmann+github@gmail.com" }, { "name": "Ciaran Jessup", "email": "ciaranj@gmail.com" }, { "name": "Douglas Christopher Wilson", "email": "doug@somethingdoug.com" }, { "name": "Guillermo Rauch", "email": "rauchg@gmail.com" }, { "name": "Jonathan Ong", "email": "me@jongleberry.com" }, { "name": "Roman Shtylman", "email": "shtylman+expressjs@gmail.com" }, { "name": "Young Jae Sim", "email": "hanul@hanul.me" } ], "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/strongloop/express.git" }, "homepage": "http://expressjs.com/", "keywords": [ "express", "framework", "sinatra", "web", "rest", "restful", "router", "app", "api" ], "dependencies": { "accepts": "~1.2.12", "array-flatten": "1.1.1", "content-disposition": "0.5.0", "content-type": "~1.0.1", "cookie": "0.1.3", "cookie-signature": "1.0.6", "debug": "~2.2.0", "depd": "~1.0.1", "escape-html": "1.0.2", "etag": "~1.7.0", "finalhandler": "0.4.0", "fresh": "0.3.0", "merge-descriptors": "1.0.0", "methods": "~1.1.1", "on-finished": "~2.3.0", "parseurl": "~1.3.0", "path-to-regexp": "0.1.7", "proxy-addr": "~1.0.8", "qs": "4.0.0", "range-parser": "~1.0.2", "send": "0.13.0", "serve-static": "~1.10.0", "type-is": "~1.6.6", "utils-merge": "1.0.0", "vary": "~1.0.1" }, "devDependencies": { "after": "0.8.1", "ejs": "2.3.3", "istanbul": "0.3.17", "marked": "0.3.5", "mocha": "2.2.5", "should": "7.0.2", "supertest": "1.0.1", "body-parser": "~1.13.3", "connect-redis": "~2.4.1", "cookie-parser": "~1.3.5", "cookie-session": "~1.2.0", "express-session": "~1.11.3", "jade": "~1.11.0", "method-override": "~2.3.5", "morgan": "~1.6.1", "multiparty": "~4.1.2", "vhost": "~3.0.1" }, "engines": { "node": ">= 0.10.0" }, "files": [ "LICENSE", "History.md", "Readme.md", "index.js", "lib/" ], "scripts": { "test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/", "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/", "test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/" }, "gitHead": "ef7ad681b245fba023843ce94f6bcb8e275bbb8e", "bugs": { "url": "https://github.com/strongloop/express/issues" }, "_id": "express@4.13.3", "_shasum": "ddb2f1fb4502bf33598d2b032b037960ca6c80a3", "_from": "express@*", "_npmVersion": "1.4.28", "_npmUser": { "name": "dougwilson", "email": "doug@somethingdoug.com" }, "maintainers": [ { "name": "tjholowaychuk", "email": "tj@vision-media.ca" }, { "name": "jongleberry", "email": "jonathanrichardong@gmail.com" }, { "name": "dougwilson", "email": "doug@somethingdoug.com" }, { "name": "rfeng", "email": "enjoyjava@gmail.com" }, { "name": "aredridel", "email": "aredridel@dinhe.net" }, { "name": "strongloop", "email": "callback@strongloop.com" }, { "name": "defunctzombie", "email": "shtylman@gmail.com" } ], "dist": { "shasum": "ddb2f1fb4502bf33598d2b032b037960ca6c80a3", "tarball": "http://registry.npmjs.org/express/-/express-4.13.3.tgz" }, "directories": {}, "_resolved": "https://registry.npmjs.org/express/-/express-4.13.3.tgz", "readme": "ERROR: No README data found!" }
特别长哈, 其实我们需要了解的只有一下几个即可:
name : 包名
version : 包的版本号
description: 包的描述
homepage: 包的官网url
author: 包的作者姓名
contributors: 包的其他贡献者姓名
dependdencies: 依赖包列表。 如果依赖包没有安装, npm会自动将依赖包安装在node_module目录下(但是在实际测试中,有些自动安装的依赖包, 缺少dist目录哦, 所以又给项目目录加了个node_vendor来存放那些不能正常运行然后手动下载的依赖包)
respository: 包代码存放的地方的类型, 可以是git 或者 svn, git可在Github上。
main: main字段是一个模块ID,它是一个指向你程序的主要项目。就是说, 如果你包的名字叫express, 然后用户安装他, 然后require('express')
keywords: 关键字
ok, 有安装模块的方法, 自然少不了卸载模块的方法啦~
我们可以使用 npm uninstall express 来卸载模块
卸载后, 你可以到/node_modules/ 目录下查看包是否还存在, 或者使用命令的方式查看 npm ls(非全局)
我们还可以听过 npm search express 来搜索express模块
创建模块
好, 那我们该怎么创建一个模块呢?
要创建模块, package.json 文件是必不可少的, 我们可以使用npm生成package.json 文件, 生成的文件包含了基本的结果。
$ npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg> --save` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. name: (node_modules) runoob # 模块名 version: (1.0.0) description: Node.js 测试模块(www.runoob.com) # 描述 entry point: (index.js) test command: make test git repository: https://github.com/runoob/runoob.git # Github 地址 keywords: author: license: (ISC) About to write to ……/node_modules/package.json: # 生成地址 { "name": "runoob", "version": "1.0.0", "description": "Node.js 测试模块(www.runoob.com)", …… } Is this ok? (yes) yes
在命令行输入 npm init, 会提示该指令将引导您完成创建一个package.json文件。
然后提示输入name 描述 等等..
一切填完了, 输入yes , 就成功创建了一个packgae.json
基本内容已经差不多了, 再补充一些npm 的常用命令~
NPM 常用命令
除了本章介绍的部分外,NPM还提供了很多功能,package.json里也有很多其它有用的字段。
除了可以在npmjs.org/doc/查看官方文档外,这里再介绍一些NPM常用命令。
NPM提供了很多命令,例如install和publish,使用npm help可查看所有命令。
-
NPM提供了很多命令,例如
install
和publish
,使用npm help
可查看所有命令。 -
使用
npm help <command>
可查看某条命令的详细帮助,例如npm help install
。 -
在
package.json
所在目录下使用npm install . -g
可先在本地安装当前命令行程序,可用于发布前的本地测试。 -
使用
npm update <package>
可以把当前目录下node_modules
子目录里边的对应模块更新至最新版本。 -
使用
npm update <package> -g
可以把全局安装的对应命令行程序更新至最新版。 -
使用
npm cache clear
可以清空NPM本地缓存,用于对付使用相同版本号发布新版本代码的人。 -
使用
npm unpublish <package>@<version>
可以撤销发布自己发布过的某个版本代码。
好了, 小伙伴们, 本章举例写了一些可以运行的最简单的小demo, 介绍了 node 与 npm 难分难舍的关系, 是不是很有学习的欲望呢, 反正我要是之前懂这些, 在新的公司也不会如此尴尬昂~~ O(∩_∩)O~ 一起加油yo~