Day2: Node.js的module和npm

写在前面


总是喜欢自己造轮子, 自己造的轮子又不如已有的轮子好, 然后就半途而废了. 现在想起来, 还是没有到自己造轮子的时候啊. 毕竟, 先把东西写出来才是最重要的.

Node.js的module

Node.js的module非常重要, 因为你为了方便, 会使用很多别人提供的包, 或者叫框架, 所以, 知道Node.js是如何引入的, 就重要了.

Node.js Modules 文档

把Modules的文档看一遍就全懂了, 是在没什么值得写的. 需要注意的就是module.exportsexports, 还有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引入一个包的时候大致循序就是如果是相对路径, 就通过当前文件计算相对路径.

  1. 如果指向的是一个核心模块, 则加载这个模块并返回.
  2. 如果指向的是一个文件, 则加载(后缀只能是.js, .json, .node), 否则当成一个目录.
  3. 如果是目录, 则看里面有没有package.json, 有的话, 计算main字段指向的文件, 跳到步骤2加载, 如果没有就看该目录下有没有index.js, index.json, index.node. 有就加载, 没有就看该目录下的node_modules下有没有, 有的话就在其内找有没有符合指向的, 按照2, 3的步骤加载, 没有就去父目录的node_modules下找, 重复3直到根目录.
  4. 最后, 如果还没找到, 就去NODE_PATH指定的目录(可以是多个)目录下接着找.

虽然提供了NODE_PATH, 但是尽量别用.

现在的目录结构差不多都是这个样子:

project/
  src/  # 源代码
  lib/ # 如果作为一个模块以供使用, 那么源代码会放到这里
  test/ # 测试
  dist/ # 压缩过的代码, 用于生产环境, 前端库经常有这个目录
  package.json # 利用"main"指向入口文件
  README.md # 项目说明

npm


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.jsondependencies中指定的包.

如果指定了--save或者-S, 则将这个包的信息自动同步到package.jsondependencies中, 而如果指定了--save-dev-D, 则将这个包的信息自动同步到package.jsondevDependencies中. 这俩参数在卸载等命令中都可以使用.

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必须有nameversion.

发布新版本的包的时候, 需要修改package.jsonversion. 可以使用npm version [major|minor|patch]来更新版本号. 如果是git项目会添加tag. 再使用npm publish发布即可.

最后

npm挺简单的, 但是写了这么多, 写笔记的时间比看文档的事件都长. 下次只记录那些值得记录的.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容

  • 1 Node.js模块的实现 之前在网上查阅了许多介绍Node.js的文章,可惜对于Node.js的模块机制大都着...
    zlx_2017阅读 1,172评论 0 1
  • 1 Node.js模块的实现# 之前在网上查阅了许多介绍Node.js的文章,可惜对于Node.js的模块机制大都...
    七寸知架构阅读 2,021评论 1 50
  • JavaScript 模块化编程 网站越来越复杂,js代码、js文件也越来越多,会遇到什么问题? 命名冲突; 文件...
    magic_pill阅读 1,345评论 0 1
  • 个人入门学习用笔记、不过多作为参考依据。如有错误欢迎斧正 目录 简书好像不支持锚点、复制搜索(反正也是写给我自己看...
    kirito_song阅读 2,421评论 1 37
  • 1 在这个世界上,要想找一个真正理解你的人很难,即使是你的父母也不一定。 知己难寻,如果你找到了,说明你很幸运,好...
    神月新一阅读 704评论 0 1