写在前面
总是喜欢自己造轮子, 自己造的轮子又不如已有的轮子好, 然后就半途而废了. 现在想起来, 还是没有到自己造轮子的时候啊. 毕竟, 先把东西写出来才是最重要的.
Node.js的module
Node.js的module非常重要, 因为你为了方便, 会使用很多别人提供的包, 或者叫框架, 所以, 知道Node.js是如何引入的, 就重要了.
把Modules的文档看一遍就全懂了, 是在没什么值得写的. 需要注意的就是module.exports
和exports
, 还有unfinished copy
.
加载的时候会进行一些初始化, 其中module
可以认为是全局对象, 记录当前块的信息, 而exports
就是exports = module.exports
, 然后引用你的包. 引用完毕之后, 返回modules.exports
. 而问题就出现在这里. 你使用exports = function func(){}
后, exports
引用的是func
, module.exports
没受影响. 所以func
没有被导出. exports
只是作为exports.propertyName = value
的方式使用的.
有一个也值得注意, 就是require.main
指向的是node
命令执行脚本是, 这个脚本的module
, 利用require.main
就可以判断, 本文件是作为脚本直接执行的, 还是作为包载入的
if(require.main === module)
// loaded as script
}else{
// loaded as module
}
require
引入一个包的时候大致循序就是如果是相对路径, 就通过当前文件计算相对路径.
- 如果指向的是一个核心模块, 则加载这个模块并返回.
- 如果指向的是一个文件, 则加载(后缀只能是
.js
,.json
,.node
), 否则当成一个目录. - 如果是目录, 则看里面有没有
package.json
, 有的话, 计算main
字段指向的文件, 跳到步骤2加载, 如果没有就看该目录下有没有index.js
,index.json
,index.node
. 有就加载, 没有就看该目录下的node_modules
下有没有, 有的话就在其内找有没有符合指向的, 按照2, 3的步骤加载, 没有就去父目录的node_modules
下找, 重复3直到根目录. - 最后, 如果还没找到, 就去
NODE_PATH
指定的目录(可以是多个)目录下接着找.
虽然提供了NODE_PATH
, 但是尽量别用.
现在的目录结构差不多都是这个样子:
project/
src/ # 源代码
lib/ # 如果作为一个模块以供使用, 那么源代码会放到这里
test/ # 测试
dist/ # 压缩过的代码, 用于生产环境, 前端库经常有这个目录
package.json # 利用"main"指向入口文件
README.md # 项目说明
npm
npm
作为包管理工具, 使用挺简单的, 其实看一遍文档就可以懂了. 文档也很短.
Node.js
已经提供了模块机制, 这就为依赖管理奠定了基础. 使用npm
的好处是什么呢? 管理代码依赖更轻松. 如果把项目分为不同的包, 既有利于一起开发; 在下一个项目中, 也可以轻易重用. 包的开发者可以自由开发不同版本, 而使用者也可以通过版本号指定采用哪个版本.
指定版本的时候可以指定一定范围, 以使用较新版本的包
Patch releases: 1.0 or 1.0.x or ~1.0.4
Minor releases: 1 or 1.x or ^1.0.4
Major releases: * or x
Node.js自带npm, 但是由于npm更新比Node.js更新更频繁, 所以有的时候需要手动更新npm
sudo npm install -g npm@latest
有时候npm很慢, 可以换别的源. 使用nrm可以轻松更换源. 一般来说, 国内淘宝比较快.
sudo npm install -g nrm # 安装nrm
nrm test # 显示各个院的时延
nrm set <repo> # 设置当前源为repo
Node.js会发布新版本, 如果是Linux下, 你有福了, 可以使用工具, 在命令行上更换不同版本的Node.js(包括Io.js)
sudo npm install -g n # 安装n
n lts # 将Node.js切换到最新的长期支持版本
n stable # 将Node.js切换到最新的稳定版本
n latest # 将Node.js切换到最新版本
对于npm
来说, 一个包就是一个文件夹, 里面包含package.json
和代码. package.json
用来描述这个包的信息, 其中, 有几个重要的信息:
-
name
, 名字 -
version
, 版本号 -
main
, 入口文件 -
scripts
, 脚本 -
keywords
, 关键字 -
author
, 作者信息author-name <email@host.com> (personal.me)
-
license
, 包使用的协议 -
repository
, 维护信息 -
bugs
, 递交bugs
的链接 -
homepage
, 项目主页 -
dependencies
, 程序依赖的包, 是一个JavaScript
对象, 属性名是包名, 属性值是依赖的版本号, 这里可以通过一定的语义来指定一定范围内的版本, 方便以后对被依赖的包进行升级. -
devDependencies
, 开发过程中依赖的包, 同dependencies
安装包很简单. 指定了-g
就是全局安装, 包被放在$(npm config get prefix)/node_modules/
目录下, 可以在命令行中使用. 前面的nrm
, n
都是这种. 没有-g
参数的就是本地安装, 代码存放在./node_modules/
目录下, 并可以用require
引入.
npm install -g <package-name>
如果没有指定<package-name>
的话, 则自动安装package.json
中dependencies
中指定的包.
如果指定了--save
或者-S
, 则将这个包的信息自动同步到package.json
的dependencies
中, 而如果指定了--save-dev
或-D
, 则将这个包的信息自动同步到package.json
的devDependencies
中. 这俩参数在卸载等命令中都可以使用.
npm ls
列出所有已经安装的包, 如果./node_modules/
目录有的包不在package.json
中, 则显示是多余的, 可以用npm prune
来删除多余的包, 而在package.json
中指定的在./node_modules/
中没有, 则使用npm install
进行安装, 这可以安装很多确实的包.
npm outdated
会根据package.json
执行的版本范围来检查当前包是否过期, 如果过期了, 就会显示过期信息. 可以通过npm update
统一升级, 如果只想更新某一个, 则指定报名即可.
卸载包可以使用npm uninstall [-S] [-D] [-g] <package-name>
来删除包.
如果在./node_modules/
目录下存在一些包, 在package.json
中没有依赖, 则可以用npm prune
删除这些多余的包.
创建包, 首先要创建package.json
. 可以使用npm init
来进入提示, 依次输入相应的信息, 最后会为你生成一个package.json
文件. 如果加上-y
参数, 则会直接生成package.json
. 这些默认的值可以在npm config set init.<key> <value>
设置, 而如果./node_modules/
下有包, 则会自动添加到依赖里面.
发布包需要一个账号, 利用npm adduser
创建账户, 如果有账户了, 则利用npm login
进行登录. 到工程所在目录运行npm publish
就发布成功了. package.json
必须有name
和version
.
发布新版本的包的时候, 需要修改package.json
的version
. 可以使用npm version [major|minor|patch]
来更新版本号. 如果是git项目会添加tag
. 再使用npm publish
发布即可.
最后
npm
挺简单的, 但是写了这么多, 写笔记的时间比看文档的事件都长. 下次只记录那些值得记录的.