zoukankan      html  css  js  c++  java
  • 代码的组织和部署

    模块路径解析规则

    源链接

    我们知道的require函数支持的两种路径有:

    • /或者C:开头的绝对路径
    • ./开头的相对路径。

    以上路径的缺点是:使得模块之间建立了强耦合关系,一旦某个模块文件的存放位置需要变更,使用该模块的其它模块的代码也需要跟着调整,变得牵一发动全身。

    下面来了解一下require支持的第三种形式的路径,写法类似于foo/bar,按照一下规则解析,直到找到模块位置。

    1. 内置模块
      • 遇到NodeJs的内置模块,不做解析,直接返回内置模块导出的对象。
    2. node_modules目录
      • node_modules目录是NodeJs定义的用于存放模块的。
    当require('foo/bar')时,NodeJs依次尝试一下路径:
     /home/user/node_modules/foo/bar
     /home/node_modules/foo/bar
     /node_modules/foo/bar
    
    1. NODE_PATH环境变量

      与PATH环境变量类似,NodeJS允许通过NODE_PATH环境变量来指定额外的模块搜索路径。NODE_PATH环境变量中包含一到多个目录路径,路径之间在Linux下使用":"分隔,在Windows下使用";"分隔。例如定义了以下NODE_PATH环境变量:
      NODE_PATH=/home/user/lib:/home/lib

      当使用require('foo/bar')的方式加载模块时,NodeJs依次尝试以下路径:

      /home/user/lib/foo/bar
      /home/lib/foo/bar
      

    包(package)

    包:由多个子模块组成的大模块称做包,所有子模块放在同一个目录里。在组成一个包的所有子模块中,需要一个入口文件,入口模块的导出对象被称作包的导出对象。

    测试目录如下:

    - node_modules/
        - aoao/
            - lib/
                test1.js
                test2.js
                main.js
            package.json
    

    各js文件内容如下:

    //test1.js
    exports.create = function (){
    	return 'test1';	
    }
    
    //test2.js
    exports.create = function (){
    	return 'test2';
    }
    
    //main.js
    var test1 = require('./test1');
    var test2 = require('./test2');
    exports.create = function(name) {
    	return {
    		name: name,
    		test1: test1.create(),
    		test2: test2.create()
    	};
    };
    
    

    我们的某一模块需要使用包时需要加载包的入口模块。我们使用时,可以直接引入口文件main.js,然后通过reuqire('/aoao/main.js')的方式得到需要的对象,但是这样的路径不太符合我们的使用习惯。在使用某个包时,路径能够指向包目录,即aoao的话,看起来更像是一个整体。

    package.json

    通过package.json的方式,可以自定义入口模块的文件名和存放位置。NodeJs会根据包目录(node_modules/aoao)下的package.json文件找到入口模块所在位置。

    //package.json
    {
    	"name": "zgatry",
    	"main": "./lib/main.js"
    }
    
    //testPackage.js作为其他模块,调用了包“aoao”
    var aoao = require('aoao');
    console.log(aoao.create('zgatry'));
    

    在Node环境下的测试结果:
    image

    index.js

    如果入口文件名为index.js的话,可以直接通过包路径来访问。

    测试目录:

    - aoao/
        test1.js
        test2.js
        index.js
    

    index.js文件

    var test1 = require('./test1');
    var test2 = require('./test2');
    console.log(test1.create(), test2.create());
    

    在Node环境下测试结果:imageimage

    测试结果说明可以直接通过包的路径来访问以index.js为入口文件的包。

    命令行程序

    使用NodeJS编写的东西,要么是一个包,要么是一个命令行程序,而前者最终也会用于开发后者。因此我们在部署代码时需要一些技巧,让用户觉得自己是在使用一个命令行程序。

    工程目录

    一个标准的工程目录

    - /home/user/workspace/node-echo    #工程目录
        - bin/                          #存放命令行相关代码
            node-echo
        + doc/                          #存放文档
        - lib/                          #存放API相关代码
            echo.js
        - node_modules/                 #存放三方包
            +argv/
        + tests/                        #存放测试用例
        package.json                    #元数据文件
        README.md                       #说明文件
    

    NPM

    NPM是随同NodeJs一起安装的包管理工具,能解决NodeJs代码部署上的很多问题。

    npm常见的用途

    1. 允许用户从NPM服务器下载三方包到而本地使用。
    2. 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
    3. 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。

    从上面三个用途展开说明:

    下载三方包

    下载前需要知道包名,然后执行以下语句:

    npm install + 包名
    

    三方包默认存放在工程目录下的node_modules目录中,使用时直接require('包名')就OK,原因在上面的“包”已经有说明了。

    如果需要依赖的包比较多,而重复执行上面的步骤显得比较low,所以NPM在package.json文件中提供了dependencies字段,来存放依赖。因此上面的代码可以改写成:

    npm install
    

    这样就可以批量安装三方包了。

    当你写好一个包然后上传到NPM服务器并且你的包依赖了其他三方包,目录结构就会变成:

    - node_modules/             # 使用者的node_modules目录
        - aoao/                 # 你上传的包
            - node_modules/     # 你的包的依赖
                ...
    

    拿gulp来做例子,请看目录结构

    - node_modules/
        - gulp/
            + bin/
            + completion/
            + lib/
            + node_modules/
            CHANGELOG.md
            gulp.1
            index.js
            LICENSE
            package.json
            README.md
    

    下面基本就是笔记,照着原文看一遍。

    安装命令行程序

    从NPM服务上下载安装一个命令行程序的方法与三方包类似。NPM会自动创建好Linux系统下需要的软链文件或Windows系统下需要的.cmd文件。

    发布代码

    第一次使用NPM发布代码需要注册一个账号。终端下运行npm adduser,之后按照提示做即可。账号搞定后,接着我们需要编辑package.json文件,加入NPM必需的字段。接着上边node-echo的例子,package.json里必要的字段如下。

    {
        "name": "node-echo",           # 包名,在NPM服务器上须要保持唯一
        "version": "1.0.0",            # 当前版本号
        "dependencies": {              # 三方包依赖,需要指定包名和版本号
            "argv": "0.0.2"
          },
        "main": "./lib/echo.js",       # 入口模块位置
        "bin" : {
            "node-echo": "./bin/node-echo"      # 命令行程序名和主模块位置
        }
    }
    

    之后,我们就可以在package.json所在目录下运行npm publish发布代码了。

    版本号

    使用NPM下载和发布代码时都会接触到版本号。NPM使用语义版本号来管理代码。

    语义版本号分为X.Y.Z三位,分别代表主版本号、次版本号和补丁版本号。当代码变更时,版本号按以下原则更新。
    
    + 如果只是修复bug,需要更新Z位。
    
    + 如果是新增了功能,但是向下兼容,需要更新Y位。
    
    + 如果有大变动,向下不兼容,需要更新X位。
    

    版本号有了这个保证后,在申明三方包依赖时,除了可依赖于一个固定版本号外,还可依赖于某个范围的版本号。例如"argv": "0.0.x"表示依赖于0.0.x系列的最新版argv。NPM支持的所有版本号范围指定方式可以查看官方文档

    一些好用的npm命令:

    npm update <package>    #以把当前目录下node_modules子目录里边的对应模块更新至最新版本。
    npm cache clear     #可以清空NPM本地缓存,用于对付使用相同版本号发布新版本代码的人。
    

    总结:

    编写NodeJs代码前的准备工作:

    1. 规划目录结构
    2. 合理使用模块管理,必要时候使用来组织模块。
    3. 合理使用node_modulesNODE_PATH来解耦包的使用方式和路径
  • 相关阅读:
    10. Regular Expression Matching
    9. Palindrome Number (考虑负数的情况)
    8. String to Integer (整数的溢出)
    7. Reverse Integer (整数的溢出)
    LeetCode Minimum Size Subarray Sum
    LeetCode Course Schedule II
    Linux 文件缓存 (一)
    LeetCode Tries Prefix Tree
    Linux : lsof 命令
    LeetCode Binary Tree Right Side View
  • 原文地址:https://www.cnblogs.com/foxNike/p/6337229.html
Copyright © 2011-2022 走看看