此篇文章介绍
ES6的模块 nodem模块 CMD和AMD npm的使用
begin enjoy👇

模块化编程

什么是模块化

所有的语言平台,只要其具有以下特征,则我们说它是使用模块编程:

  • 文件作用域
    • 也叫模块作用域,即模块文件具有封装性,文件内容只能在内部使用 而不是在外部访问
  • 加载与导出
    • 使用专门的语法 导出接口列表:export语法、exports对象、module.exports等
    • 使用专门的方法 加载模块文件:require、include、import等。

目前为止,关于前端 我们学过的规范或者规则有:

  • 核心语法ECMAScript支持的模块语法,ES6以后可以使用,但在Node中支持不足
  • 第三方库 requireJS规范,适用于客户端浏览器环境的异步加载机制,让前端具备模块化编程的能力
  • 第三方库 CommonJS规范,适用于服务端环境的模块同步加载机制,也是Node模块加载采用的规范

ES6模块规范

es6新增语法用于模块化编程,使得前端工程的结构更为合理,维护性和扩展性增强,但目前在node中支持不足,如果一定要在node中使用es6的模块规范,可以通过babel生成。

export语句

在客户端环境中,文件默认没有作用域可以通过script直接引入。当文件中存在export或者import语法时则被认为是模块文件并且具有封装性,export用来声明开放接口的列表,具体用法如下:

  • 使用export直接导出定义,通过在创建该内容的代码块前面添加export关键字

    //demo.js
    //一个文件中可以存在多个export
    export let foo = "foo";
    export function bar() {
        return "bar";
    };
    
  • export导出接口列表,以{}形式存放接口集合。此处的{}非对象的声明,只是集合语法

    let foo = "foo";
    function bar () {
        return "bar";
    }
    
    export {
        foo,
        bar
    };  //此处不是对象的简洁属性,而是{}集合
        //不能使用{fo : foo, ba : bar}
        //可以使用as给接口设置别名
    
    export {
        foo as fo,
        bar as ba,
    }
    
  • export default用来设置默认接口,这样在加载页面时就无需声明列表,直接接收即可。

    //demo.js
    let foo = "foo";
    function bar() {
        
    }
    
    //将foo作为默认接口导出
    //export default foo;	
    //export default只能出现一次 如果要返回多个接口 可以将它们放入对象中
    export default {
        foo,
        bar,
    } //此处为对象的简洁写法
    
    //加载页面中使用
    import demo from './demo.js';
    console.dir(demo);	//demo为一个对象,包含多个接口
    
    
  • 最后要注意,export语句必须处于模块文件顶层代码中,不能放在块级作用域中。

import 语句

页面中加载模块的script代码段需要声明type类型为module以区别普通的脚本;

其次要以服务器地址来请求模块文件,否则会被跨域拦截。

es6中使用import导入模块文件并接收接口列表。

  • import {add, minus} from './math.js' 其中相对路径中的./不可省略,.js后缀也不可省略 。

    //math.js
    export function add(x, y) {
        return x + y;
    }
    
    export function minus(x, y) {
        return x - y;
    }
    
    <!--index.html必须以服务器地址来运行-->
    <script type="module">
    	import {add, minu} from "./math.js";
        console.log(add, minu);
    </script>
    
  • import {add, minus as min } from './math.js' 导入时使用as重命名接口名称

    //math.js
    function add(x, y) {
        return x + y;
    }
    
    function minus(x, y) {
        return x - y;
    }
    
    export {
    	add,
        minus
    }
    
    
    <script>
    	import {add as sum, minus as mus} math from './math.js';
        console.log(sum, mus);
    </script>
    
    
  • import * as math from './math.js' 将模块成员存入mod对象中使用。

    //math.js
    function add(x, y) {
        return x + y;
    }
    
    function minus(x, y) {
        return x - y;
    }
    
    export {
    	add,
        minus
    }
    
    <script>
    	import * as math from './math.js';
        console.log(math); //{add, minus}
    </script>
    
  • import math from './math.js' 使用了export default方式导出的接口

    //math.js
    export default {
        add (x, y) {
            return x + y;
        },
        
        minus (x, y) {
            return x - y;
        }
    }
    
    <script>
    	import math from './math.js';
        console.log(math);
    </script>
    

CMD模块规范

CMD模块规范相对于AMD,得名来自CommonJS。CommonJS是适用于服务端的同步风格的模块加载机制,也是Node采用的规范。在CommonJS模块规范中,一个文件就是一个模块 具有封装性(作用域)。每个文件有一个隐式声明module.exports对象,用来挂载接口。接下来在项目文件中,使用require('模块路径')载入该模块。

exports的使用

  • 在CommonJS中,每个模块文件都有一个隐式声明的module.exports对象以及一个引用它的exports对象,用来挂载接口 - 对象扩展;如果模块文件未设置module.exports或者exports则为一个空对象

    //mode.js
    let foo = "foo";
    
    function bar() {
    
    }
    
    //模块文件具有封装性 - 文件作用域
    console.log("hello world");
    
    //每个模块文件都有一个module.exports对象 用来挂载接口
    // module.exports.foo = foo;
    // module.exports.bar = bar;
    // console.log(module.exports);
    
    //exports引用了module.exports对象 便于使用
    // exports = module.exports;
    console.log(exports == module.exports); //true
    
    //因此可以直接简化导出接口列表的过程为:
    exports.foo = foo;
    exports.bar = bar;
    

    在项目文件中,使用require('模块标识符')载入该模块,并定义变量来接收module.exports的内容:

    //index.js
    const mode  = require('./mode');
    console.log(mode);	//{foo : "hello world", bar : function () {}}
    
  • 除了扩展的方式外,我们还可以重写module.exports对象为一个新值,这样require接收到的即为该值,它主要有以下两点优势:

    • 当模块中 只有一个接口时 (例如 定义类的模块文件),可以直接将该类导出 而不是作为接口对象成员。
    • 当模块中 接口较多时 可以将它们集合到一个对象中 然后作为module.exports的新值。
    //comm.Rectangle.js
    //定义矩形操作类模块
    class Rectangle {
        constructor(width, height) {
            this.w = width;
            this.h = height;
        }
    
        area() {
            return this.w * this.h;
        }
    
        perimter() {
            return 2 * (this.w + this.h);
        }
    }
    
    //重写module.exports对象为该接口内容
    module.exports = Rectangle;   
    
    /*
    * 此处如果使用exports = Rectangle则无效
    * 因为真正能够导出接口的是module.exports
    * exports是因为引用module.exports而能导出接口
    * 现在重置exports将使得其不再具备接口导出的能力
    
    * 同理,module.exports重置后 也会使exports丧失挂载接口的能力
    */
    
    //exports上挂载的一切接口都无效
    exports.a = "hello";
    exports.b = "world";
    
    //index.js
    const Rectangle = require("./comm.Rectangle.js");
    console.log(Rectangle);	
    

    对于module.exports或者exports导出的多接口,可以在项目文件中使用解构赋值的方式直接提取出来:

    //comm.math.js
    let x = 10,
        y = 20;
    
    function add() {
        return x + y;
    }
    
    function minus() {
        return x - y;
    }
    
    module.exports = {
        add,
        minus,
    }//此处的{}是一个对象,使用了简洁属性
    
    let {add, minus} = require('./comm.math.js');
    console.log(add, minus);
    

require的使用

在一些平台中,存在require()与require_once() 这样两个用于加载模块的函数;其中require()会重复加载被引入的文件(多次执行),而require_once()则在每次加载前验证当前是否已有加载的文件,如果已有则不再加载,也就是说每个文件最多只加载一次;而node中的require也是只加载一次

//mode.php
echo "hello world";

//index.php
require("mode.php");//输出 include
require("mode.php");//输出 include_once

require_once("mode.php");	//不再输出
require_once("mode.php");	//不再输出
//mode.js
console.log("hello world");

//index.js
require("./mode");	//只执行一次
require("./mode");

AMD模块规范

requireJS 是AMD风格的模块开发规范,所谓AMD是指异步模块定义规范,它非常适用于客户端(浏览器)环境。

模块开发是服务端必备的技术,随着前端发展和大规模的工程化应用,嵌入页面的脚本越来越多,并且相互依赖,因此无论是项目的管理还是代码的重用, 都需要借助于模块化 以此增强项目的可维护性和扩展性。

之前在服务端Node中,使用了CommonJS的规范,也叫CMD同步模块定义规范。在CMD中,同步的线程去加载模块会产生阻塞,但是毕竟模块都在同一个服务器或者同一个项目中,加载不会有延迟 也就难以发现这种阻塞,除非模块加载发生错误,这种阻塞才显而易见。

//server.js
const fs = require("fs");	//核心模块 -> node.exe
const template = require("art-template"); //加载第三包 -> ./node_modules/art-template
const demo = require("./demo");//自定义模块 -> ./demo.js

在前端模块化开发中,由于需要远程请求服务端资源 传统的script同步请求 在网络不佳的情况下 容易产生阻塞,因此必须使用异步的方式加载:

<script src="jquery.js" async="true"></script>

​ 如果要以异步方式加载,就要考虑文件和代码之间的依赖关系。之所以很多时候 我们以同步方式引入模块或者库文件,是因为后续代码的执行 必须依赖这个模块文件。现在 如果异步加载 势必要将依赖的代码 作为该模块加载完毕后的回调函数来执行,相当于这样:

<script src="jquery.js" async="true" onload="todo();"></script>

<script>

   function todo() {
   	//所有依赖jquery的代码 必须在此处执行
   	
   }

</script>

requireJS很好的解决了上述问题,并更加智能和高效。requireJS中,模块使用define定义,它有两个参数:

  • 一是该模块依赖的其他模块,需要先异步加载进来
  • 另一个是模块的定义代码,作为其他依赖模块都加载完毕后的回调函数

requireJS模块的封装性是通过函数作用域实现的,接下来 需要返回一个公有对象存储接口列表并返回。

//mode.js

//该模块依赖jquery,当jquery加载完毕后 执行回调并接收jquery为$对象

define(['jquery'], function ($) {
    //---模块核心代码---
    let foo = "foo";
    function bar() {};

    //---返回公有接口---
    return {
        foo, 
        bar
    } //使用简洁属性 模拟es6 exports导出的接口列表
});

定义好的模块和接口,接下来使用require函数引入,在require引入之前 需要使用require.config()配置模块和文件路径的映射 这样才能更好的加载和使用模块。

<!--index.html中 首先载入require库文件-->
<script src="require.js" async="true"></script>
//如果页面中的js作为外链文件 还可以声明data-main属性
<script src="require.js" async="true" data-main="js/index"></script>
//index.js
require.config({
    baseUrl : "./modules",	//模块根目录
    paths : {
        jquery : "./jquery-2.0.2.min",	//可以省略js
        foo : "foo"
    }
});

//依次载入依赖的模块 然后执行页面代码
require(["foo", "jquery"], function (f, $) {
    console.log(f, $);
    //页面特效的代码

});

node模块系统

node中使用的模块系统包含以下几种:

​ 1) 核心模块:fs、http、url、querystring等

​ 2) 第三方模块:使用npm从外部下载安装的模块,例如 art-template

​ 3) 自定义模块:用户自己定义的模块文件,例如 math.js、mode.js等

而require在引入上述模块时,可以传入两种格式的模块标识:路径形式和包名

require('模块标识符')

  • 当传入了一个路径时(以**./或者../**开头) 表示加载按照路径加载文件 一般用于自定义模块中。

  • 当传入一个模块名时,就是参数中只有名称时 表示加载核心模块或者第三方模块。此时的模块文件是存在于Node核心文件(nodex.exe)中或者使用npm下载的node_modules目录中。

    • require('fs')加载核心模块fs,fs.js模块文件随着node环境被编译到node.exe文件中。这里可以通过源码查看到该文件。

    • require("art-template") 加载第三方模块包,这里的art-template模块是存储于npm下载的包里面

      接下来引入包时 它有一套明确的查找机制:

      1. 首先查找当前目录的node_modules,定位node_modules/包名/libs/package.json包说明文件
      2. 查找配置项main,main用于指定包的入口文件,该文件用于调度包资源 并返回一个接口对象

      同理,我们使用npm安装jquery,查看它的package.json文件 找到main配置的入口文件;再接下来 我们可以自定义包 并使用require加载该包。注意require中传入的是包名。

      1. 如果上述规则不能有效的运行,例如 package.json不存在或者没有main项,或者main指定文件不存在, 此时它还有一个备选项 就是直接找到包中的index.js作为默认入口文件。

      2. 上述条件都不成立时,它会沿着上级目录层层查找node_modules 直到磁盘根目录为止。也就是说存在于项目顶层目录node_modules中的模块 可以在所有的项目文件中使用require(包名)导入。因此 建议将node_modules放置于项目根目录中。

      a
      	node_modules/art-template
      b
      	require("art-template");	//找不到 除非使用路径查找
      	require("../a/node_modules/art-template/index.js"); //可以找到
      

package.json

package.json是包说明文件,可用于项目中 用来添加项目描述以及管理项目中需要依赖的包。package.json文件可以通过npm init自动生成,该命令会以向导的方式提示基本的配置项。

#在控制台执行npm init
d:\Wamp\WWW\node\day3\web>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>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.

package name: (web) web
version: (1.0.0) 0.0.1
description: demo app
entry point: (index.js) inidex.js
test command:
git repository:
keywords:
author: lautin
license: (ISC)
About to write to d:\Wamp\WWW\node\day3\web\package.json:

{
  "name": "web",
  "version": "0.0.1",
  "description": "demo app",
  "main": "inidex.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "node server.js",
  },
  "author": "lautin",
  "license": "ISC"
}

Is this OK? (yes) yes
  • name
  • version
  • description
  • main
  • author
  • license

scripts

package.json文件中的scripts字段用来定义脚本命令,所有的脚本命令都是shell的可执行命令。

scripts为一个对象,它的每个属性对应一段要运行的脚本。例如,上面build命令对应的脚本是"node server.js"。接下来使用npm run build即可实现"node server.js"的效果。

每当执行**npm run**就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。

$ npm run build #等同于下面
$ node server.js

如何编写shell

  • .bin中的可用程序

node/modules/.bin目录中存放了当前项目依赖中所有的命令行工具,而在npm run新建的Shell中,会将当前目录下node_modules/.bin目录加入PATH变量,执行结束后再将PATH变量恢复原样。

这就意味着,可以在scripts中直接引用.bin目录中的命令行工具,而无需设置它们的路径。

{
    "build" : "gulp html", //不用写成下面那样
	"build" : "./node_modules/.bin/gulp html"
}
  • 使用通配符

*****表示任意文件名,**表示任意一层子目录。

如果要将通配符传入原始命令,防止被 Shell 转义,要将星号转义。

{
    "test": "tap test/\*.js"
}
  • 使用内部变量

npm 脚本有一个非常强大的功能,就是可以使用 npm 的内部变量。

首先,通过npm_package_前缀可以拿到package.json里面的字段。比如,下面是一个package.json

{
  "name": "foo", 
  "version": "1.2.5",
  "scripts": {
    "view": "node view.js"
  }
}

那么,变量npm_package_name返回foo,变量npm_package_version返回1.2.5

// view.js
console.log(process.env.npm_package_name); // foo
console.log(process.env.npm_package_version); // 1.2.5

上面代码中我们通过环境变量process.env对象拿到package.json的字段值。因为是临时PATH,所以只在npm脚本运行时才有效。如果是Bash脚本可以用$npm_package_name$npm_package_version取到这两个值。

npm_package_前缀也支持嵌套的package.json字段。

{
  "repository": {
    "type": "git",
    "url": "xxx"
  },
  "scripts": {
    "view": "echo $npm_package_repository_type"
  }
}

上面代码中,repository字段的type属性,可以通过npm_package_repository_type取到。

下面是另外一个例子。

{
    "scripts": {
  		"install": "foo.js"
	}
}

上面代码中,npm_package_scripts_install变量的值等于foo.js

然后,npm 脚本还可以通过npm_config_前缀,拿到 npm 的配置变量,即npm config get xxx命令返回的值。比如,当前模块的发行标签,可以通过npm_config_tag取到。

{
    "view": "echo $npm_config_tag"
}

注意,package.json里面的config对象,可以被环境变量覆盖。

{ 
  "name" : "foo",
  "config" : { "port" : "8080" },
  "scripts" : { "start" : "node server.js" }
}

上面代码中,npm_package_config_port变量返回的是8080。这个值可以用下面的方法覆盖。

$ npm config set foo:port 80

最后,env命令可以列出所有环境变量。

"env": "env"
  • 默认的脚本

一般来说,npm 脚本由用户提供。但是,npm 对两个脚本提供了默认值。也就是说,这两个脚本不用定义,就可以直接使用。

"start": "node server.js",
"install": "node-gyp rebuild"

上面代码中,npm run start的默认值是node server.js,前提是项目根目录下有server.js这个脚本;npm run install的默认值是node-gyp rebuild,前提是项目根目录下有binding.gyp文件。

执行npm脚本

如果 npm 脚本里面需要执行多个任务,那么需要明确它们的执行顺序。

如果是并行执行(即同时的平行执行),可以使用&符号。

$ npm run script1.js & npm run script2.js

如果是继发执行(即只有前一个任务成功,才执行下一个任务),可以使用&&符号。

$ npm run script1.js && npm run script2.js

这两个符号是 Bash 的功能。此外,还可以使用 node 的任务管理模块:script-runnernpm-run-allredrun

四个常用的 npm 脚本有简写形式:

  • npm startnpm run start
  • npm stopnpm run stop的简写
  • npm testnpm run test的简写
  • npm restartnpm run stop && npm run restart && npm run start的简写

dependencies

package.json中还有两个比较重要的配置项dependenciesdevDependencies用来添加项目所依赖的包名,在安装包时可以通过--save--save-dev参数可以将安装包写入这两个配置项中,例如:

# 控制台使用npm
$ npm install art-template --save
$ npm install webpack --save-dev

然后package.json中会自动添加两行:

{
    "dependencies": {
        "art-template": "^4.13.2"
     },
    "devDependencies" : {
        "webpack" : "^4.1.6"
    }
}
  • DevDependencies :该配置项包含在开发时需要加载的包,而不是项目本身必须用到的包,例如 gulp、webpack用于打包一个项目,并不是属于项目自身。
  • dependencies : 项目开发以及上线运行必须加载的包,是项目功能核心的包。

当项目中的node_modules丢失时 可以通过npm install一次性找回。npm install会依据package.json中**dependencies**选项挨个执行安装。因此 我们建议每个项目都添加一个package.json

package-lock.json

npm5+的版本中,无需手动--save,它也会自动保存依赖信息。除此以外还加入了名为package-lock.json的文件。该文件在安装包时自动创建,保存了node_modules中所有包的信息:版本、描述以及下载地址,如此一来当再次安装该包时,它的速度就会显著提升。

lock文件被称为锁文件,主要是锁定包的版本,避免下次重装时以最新版本来下载。例如当前使用的是bootstrap3,当lock中记录了该版本时,下次安装就不会以最新的bootstrap4来下载,而是依然选择bt3。

npm的使用

npm官网

官网专门用来管理第三方包的平台,所有可用npm安装的包 都需要事先提交到该网站。接下来才能在用户代码中 使用npm下载。如果你有兴趣 也可以向该平台提交包。

@link 发布包的流程

npm指令

npm是随着node一起安装的,当node安装完成npm也就有了, 并且写入了环境变量中。接下来在cmd窗口可以直接使用npm来执行命令:

  • npm --version

    • 查看npm版本信息
  • npm help

    • 查看使用帮助信息,命令列表
    • 命令手册 npm install--help
  • npm install npm --global

    • 升级npm
    • 需要全局使用的包,必须全局安装,它会将包下载到一个已经写入了环境变量的位置,例如:C:\Users\admin\AppData\Roaming\npm\node_modules 接下来在任意位置即可使用该包。
  • npm init

    • 以向导形式 初始化package.json文件

    • npm init -y 则是跳过向导 使用默认值快速生成package.json

  • npm install

    • 一次性安装 所有depenencies中的依赖包

    • 简写形式 npm i

  • npm install 包名

    • 安装指定的包到node_modules中
    • 简写形式 npm i 包名
  • npm install 包名 --save

    • 安装并将写包写入项目的依赖中
    • 简写形式 npm i 包名 -S
  • npm install 包名 --save-dev

    • 安装并将包写入开发依赖环境中
    • 简写形式 npm i 包名 -D
  • npm uninstall 包名

    • 删除一个包,保留依赖项
    • 简写形式 npm un 包名
    • 别名:rm
  • npm uninstall 包名--save

    • 删除一个包以及依赖项
    • 简写形式 npm un 包名 -S

npm配置

  • 使用npm config list查看npm的基本配置信息

    它包括有cli configsuserconfigbuiltin config几级配置,通常修改userConfig的配置。userconfig配置文件在c:/users/admin/.npmrc.文件中,可以直接修改该文件来设置用户配置项

  • 使用npm config list -l查看npm配置的详细信息

  • npm config get key 读取一个配置项的值

  • npm config set key value 设置一个配置项的值

npx的使用

npx是npm5.2之后发布的一个命令。官网说它是execute npm package binaries,就是执行npm依赖包的二进制文件,简而言之,就是我们可以使用npx来执行各种命令。
npx官网:https://www.npmjs.com/package/npx

加载脚本

当我们在安装一个命令行的工具包时,想要在本地(当前目录)执行它时,什么都不做时是不能运行的:

$ npm i -D mocha
$ mocha --version

想要在本地能够执行它的命令,通常需要符合以下三种情况:

  • 全局安装该包,自动下载到已添加环境变量的位置,可以在任意目录下使用该包

    $ npm i mocha --global
    
  • 在命令行中找到该模块的二进制文件运行,通常是node_modules/包名/bin/目录

    $ cd node_modules/mocha/bin
    $ mocha --version
    
  • 当前项目的package.json文件中创建npm脚本,即scripts中设置一条执行该包的命令。原理是npm run执行时.bin目录会动态添加到环境变量中。

    {
        "scripts": {
      		"findmocha": "mocha --version",
    	}
    }
    
    $ npm run findmocha
    

使用npx可以在命令行直接执行本地已安装的依赖包命令,不用在scripts脚本写入命令,也不用麻烦的去找本地脚本。

$ npm i -D mocha
$ npx mocha --version

npx的原理,就是在运行它时,执行下列流程:

  1. node_modules/.bin路径检查npx后的命令是否存在,找到之后执行;

  2. 找不到,就去环境变量$PATH里面,检查npx后的命令是否存在,找到之后执行;

  3. 还是找不到,自动下载一个临时的依赖包最新版本在一个临时目录,然后再运行命令,运行完之后删除,不污染全局环境。

使用场景

一次性的命令

不同全局安装,直接在命令行执行一次性命令,例如

npx create-react-app my-react-app

npx将create-react-app下载到一个临时目录,使用以后再删除。
每次运行这个命令,都会重新下载依赖包,运行后删除。

切换node版本

当你想要运行的命令不兼容当前的nodejs版本,可以通过npx来切换版本,指定某个版本的 Node 来运行命令。

npx的-p选项指定要安装的包,并将其添加到正在运行的$PATH中,例如:

 npx node@6 -v
 npx node@7 -v
 npx node@8 -v

以上的命令,会自动下载需要的node,执行完命令后删除。

开启服务

npx http-server    #默认返回根目录下index.html
npx http-server -p 3000  #指定端口

常用指令

可以单独安装npx:

npm install -g npx
  • -p

-p参数用于指定 npx 所要安装的模块

npx -p node@6 node -v
  • --no-install

强制使用本地模块,不下载远程模块,如果本地不存在该模块,就会报错。

  • --ignore-existing

忽略本地的同名模块,强制安装使用远程模块

cnpm代理

npm远程服务器存放于国外,即便国内有CDN也会比较慢,因此建议使用时配置国内的镜像地址 。

@link http://npm.taobao.org

这是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次 以保证尽量与官方服务同步。

1)全局安装cnpm

> npm install cnpm --global

2)使用cnpm安装包

# 使用cnpm安装art-template
> cnpm install art-template
√ Installed 1 packages
√ Linked 27 latest versions
√ Run 0 scripts
√ All packages installed (30 packages installed from npm registry, used 16s(network 16s), speed 69.44kB/s, json 28(79.46kB), tarball 1.01MB)

如果不想安装cnmp服务 而又想使用其镜像服务器下载包,则可以通过--registry来设置

> npm install art-template --registry=https://registry.npm.taobao.org

或者直接修改npm配置项中下载入口地址:

> npm config set registry https://registry.npm.taobao.org
#查看npm配置项信息
> npm config list
> npm config list -l

posted @ Zycin (非转载 来自个人学习资料整理)