3.模块化及node npm cnpm yarn nvm详解

1. 重点提炼

  • 模块化及自定义模块

  • commonjs模块化

  • npm包的注册与发布

  • npm、cnpm、yarn、nvm工具的使用

2. 前端工程师学习node的重要性

  1. 可以搭建一些服务器,模拟一些数据,不会太依赖后端

  2. 更熟悉前后端交互,对互联网产品会有更全面了解

  3. nodejs可以写桌面端,可以往大前端上发展,很多前端项目都是基于nodejs去构建的,也有很多前端自动化工具都是基于nodejs


3. node回顾

  • node环境搭建

    • 下载安装(稳定版本,尝鲜版本)
    • 环境变量配置
  • common.js规范

    • 自定义模块
      • 导入:require;(“./”问题)导出:module.exports或者exports;
      • node_modules里package.json配置;
      • node_modules查找规则(向上查找)
    • 内置模块
      • 内置模块不需要安装,外置模块需要安装;
  • npm包管理器使用

    • npm i --save-dev(-D) --save( -S ); package.json

    • -g

    • npm root 、npm root -g

  • fs模块

    • 文件操作

      • 增、删、改、查 (同步及异步)
    • 目录操作

      • 删除非空目录
  • buffer : toString();

  • stream

4. es6模块化

node中是使用commonjs模块化规范。注意模块化的核心是每个模块都有自己独立的作用域,而不是简单理解为用script标签引入不同的js文件,这里的变量显然都是全局作用域的且把引入所有文件最终合成为一个文件,在全局使用,造成变量污染。在没有模块化之前,为了解决变量污染,通常使用闭包来解决。使用模块化后,需要导出函数与变量,是按需导出的,而不是直接引入一次性导出。

es6模块化导入导出:

// 默认导出,只能导出一个 对象/变量   =>   按需导出,不用一次性全部导出接收的时候可以定义任何名称接收,默认接收该对象/变量   =>   按需导出
export default;
// 导出,可以导出多个
export;
// 导入
import;

注意:以上使用地是es6模块化,node是commonJs规范,实际还有很多其他不同的模块化规范,大体思想一样,但使用上可能有些不同。


4.1 export default实例

a.js

let a = 10;

let obj = {
    
    
    name:"张三",
    age:20,
    fn:function(){
    
    
        console.log("fn...")
    }
}

let fn = function(){
    
    
    console.log(1111);
}

export default fn;

导入

引入对应的导出是export default,变量名随意定义

import a from './a.js';

另外一种导出写法:(与export default fn;一样)

export {
    
    fn as default}

4.2 export实例

错误方式:

let num = 10;
export num;

修改:

export let num = 10;

另外的写法:

let num = 10;
let str = "我是字符串";
export {
    
     num }
export {
    
     str };

导入

引入对应的导出是export => 注意变量名一致

import {
    
     num , str } from './a.js';

别名 as

let num = 10;
let str = "我是字符串";
export {
    
     num }
export {
    
     str };
// 别名 as
export {
    
    str as mystr}

导入

import {
    
     num , mystr } from './a.js';

也可以导入的时候取别名:

import {
    
     num as mynum, mystr } from './a.js';

可以导入所有: => 导入到obj对象里

import * as obj from './a.js';

引入 对应 export default和 export

let a = 10;

let fn = function(){
    
    
    console.log(1111);
}

export default fn;

let num = 10;
let str = "我是字符串";
export {
    
     num }
export {
    
    str as mystr}


myobj => export default fn

{num,mystr} => export { num } export {str as mystr}

import myobj,{
    
    num,mystr} from './a.js';

4.3 严格模式

<script type="module"> => 声明为严格模式

function test(){
    
    
  console.log(this);
}
test();

打印结果:

undefined

注意:如果是默认的混搭模式,则这里打印的this为windows

a = 10;
console.log(a);

打印结果: => 报错

注意:如果是默认的混搭模式,则这里打印的a为10


4.4 按需导入

在Vue中是用回调函数进行import,

document.onclick = function(){
    
    
    import {
    
    a} from './a.js';
}

报错,不能这样使用。 => 实际原生提供import函数。

document.onclick = function(){
    
    
    import("./a.js");
}

如果想得到import的结果,返回promise对象,用then获取即可。

let a = 10;

let fn = function(){
    
    
    console.log(1111);
}

export default fn;

let num = 10;
let str = "我是字符串";
export {
    
     num }
export {
    
    str as mystr}
// 按需导入;
document.onclick = function(){
    
    
    // 返还一个promise对象;
    import("./a.js").then(res=>{
    
    
        console.log(res);
    });
}

打印一个对象,对象中包含fnnummystr


因为返回promise,也可用asyncawait的写法。

document.onclick = async function(){
    
    
    let res =   await import("./a.js");
    console.log(res);
}

注意:按需导入后,我们再点击也不会频繁导入,因为浏览器有缓存策略。


5. 模块化

es6commonjs出来之前,比较火的规范是AMD规范(requirejs)和CMD规范(seajs)。实际都是未来防止变量污染及提高代码复用性,使代码逻辑更为清晰并且便于维护。

5.1 AMD requirejs

通过define导出

a.js

console.log("a文件");
define({
    
    
    name:"张三",
    age:20
});

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdn.bootcss.com/require.js/2.3.6/require.js" ></script>
    <title>Document</title>
</head>
<body>
</body>
<script>
// AMD : requirejs CMD :seajs;
// 导入模块a
require(['a'],function(res){
     
     
    console.log("a导出的",res);
});
</script>
</html>

image-20200513001025202

参考:https://github.com/6xiaoDi/blog-nodejs-novice/tree/a0.72
Branch: branch03

commit description:a0.72(AMD requirejs使用)

tag:a0.72


define除了导出对象,还可以导入b模块

b.js

console.log("b.js");
define({
    
    
    name:"b.js"
});

define导出的同时,还可导入b模块。

a.js

console.log("a文件");
define(["b"],function(res){
    
    
    console.log("b导出的",res);
    return {
    
    
        name:"张三",
        age:20
    }
});

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdn.bootcss.com/require.js/2.3.6/require.js" ></script>
    <title>Document</title>
</head>
<body>
 
</body>
<script>
// AMD : requirejs CMD :seajs;
// 导入模块;
require(['a'],function(res){
     
     
    console.log("a导出的",res);
});
</script>
</html>

image-20200513001626831

参考:https://github.com/6xiaoDi/blog-nodejs-novice/tree/a0.73
Branch: branch03

commit description:a0.73(AMD requirejs使用——define导入导出)

tag:a0.73


5.2 commonjs规范

它和es6模块化十分相似,但它是后端这块的模块化。

注意主文件的后缀,如.js是可以省略的,但是当前目录的./是不能省略的(除非安装的是第三方的库 => node_module文件夹里存放,这个时候不需要加./)。

a.js

console.log("a.js文件");

index.js

require("./a");

打开终端输入:node index.js

打印:

a.js文件

参考:https://github.com/6xiaoDi/blog-nodejs-novice/tree/a0.74
Branch: branch03

commit description:a0.74(commonjs规范使用)

tag:a0.74


node_modules里package.json配置,不用手动配置,可以执行以下命令,所有配置均为默认配置不用自己写的,

npm init -y

在当前目录自动创建package.json,它不是纯描述性文件,注意它是有功能和作用的。它不是类似readme一样的文件。

"scripts"一些快捷的命令方式放在这里,可以简写命令,如这里test就是命令的简写。

"main"整体项目而定单入口。

{
    
    
  "name": "commonjs01",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    
    
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

如:"scripts"中加入简写命令:

"mytest":"echo someting..."

{
    
    
  "name": "commonjs01",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    
    
    "test": "echo \"Error: no test specified\" && exit 1",
    "mytest":"echo  someting..."
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

输入:npm run mytest

> echo someting…

someting…

参考:https://github.com/6xiaoDi/blog-nodejs-novice/tree/a0.75
Branch: branch03

commit description:a0.75(commonjs规范使用——package.json)

tag:a0.75


5.3 内置模块与外置模块

内置模块就是它已经写好的模块,外置模块在下面的网址:

外置模块搜索

需要什么外置模块可以直接搜索

image-20200513011652465


会出现问题,就是npm的对应文档在哪里?我们点开都可以看到说明,虽然是英文,但是有代码实例。

该网址是第一手的资料,直接搜索一些模块。

注意:node_modules存放外置模块(默认向上查找),如果本层没有,它会打开上一级目录,逐级向上查找。


如:npm i cookie -S

我们发现package.json中多了"dependencies"

“dependencies”: {
“cookie”: “^0.4.1”
}

这其实就是所谓的运行依赖,即开发和运行的时候都需要这个模块。

而对应的开发依赖,则是开发的时候才需要,真实上线的时候是不需要它的。 devDependencies => 开发依赖(npm i cookie -D)

{
    
    
  "name": "commonjs01",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    
    
    "test": "echo \"Error: no test specified\" && exit 1",
    "mytest": "echo someting..."
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    
    
    "cookie": "^0.4.1"
  }
}

开发依赖

npm i cookie --save-dev

发现cookie转移到 "devDependencies"里了。

{
    
    
  "name": "commonjs01",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    
    
    "test": "echo \"Error: no test specified\" && exit 1",
    "mytest": "echo someting..."
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    
    },
  "devDependencies": {
    
    
    "cookie": "^0.4.1"
  }
}

-g 全局安装,安装在

npm root -g

可以看到默认安装的目录了

C:\Users\XD\AppData\Roaming\npm\node_modules


6. 前端常用工具介绍

6.1 npm包

6.1.1 提炼

注册与发布

  • 注册账号:https://www.npmjs.com/ (邮箱验证)

  • npm adduser 输入刚刚注册好的用户名和密码 ;

    如果注册地址不对需要重新改回来:

    npm config set registry https://registry.npmjs.org/ (官方地址)

    https://registry.npm.taobao.org/ (淘宝源地址)

    查询源地址

    npm config list

  • 发布包

    • publish 命令

      发布成功后输出信息:

      发布成功后

      在npm网站上搜索到的包内容

      搜索到的包

6.1.2 使用

npm上第三方模块大多是开发者写的,自己也可以把写的好的模块提交上去,注意包的名字不能与其他重名,包里必须有package.json (npm init -y)。前提自己得注册账号,然后在自己的npm上登陆即可。

npm adduser => 添加用户

根据提示,写入自己的信息即可。 => 用户名和密码

image-20200513110546547

推送包

npm publish

注意包名一定不能重名,并且npm必须验证邮箱(这个比较坑,xiao迪是翻墙上的,很卡)千万别用手机端,要有电脑端浏览器,多尝试几次,挺烦的。(并且由于强迫症和密集恐惧症,我看到这个默认头像,头皮就发麻,想换个头像,尝试了很多次也进不去。真心尴尬啊!!)

非常快捷,也不用审核就可以包发布上去。

image-20200513114816879


今后有需要,我们可以npm安装我们自己发布的包了。

npm i 包名

感觉非常方便!!!

同时也可以删除自己不想要的包。

npm unpublish 包名

它会提示:npm ERR! npm unpublish [<@scope>/]<pkg> --force

npm unpublish 包名 --force

提示:using --force I sure hope you know what you are doing 表示删除成功了

注意删除包后,24小时内这个包的名字不能再使用了。


注意:使用npm下载的时候,一定要保证下载源是官方下载源(即下载包的地址)。

npm config list (查看下载源,并没看到)

可以用npm config ls -l 查看所有,就能找到源了 => npm官方下载源一定不能错

image-20200513121529149

可直接ctrl+点击这里的配置(vs code),修改源:

image-20200513121637762

也可以直接查找源:

npm config get registry

另一种设置下载源地址方法:

npm config set registry https://registry.npmjs.org/ (官方地址)


6.2 cnpm的安装及使用

cnpm淘宝国内npm => 下载速度更快

它的连接和下载速度很快:这是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。

安装(CMD):npm install -g cnpm --registry=https://registry.npm.taobao.org

安装完毕 cnpm -v 查看版本号

必须注意:

不要直接使用cnpm,有的时候会出一些路径等问题 ;

并且cnpmnpm安装会有区别,npm安装后会多出一个package-lock.json文件,这里描述了各个依赖包更为细化的版本描述。

npm改变下载的地址(下载源);

npm config set registry https://registry.npm.taobao.org (不能提交模块,如要在npm提交模块,需再设置回官方npm下载源,npm config set registry https://registry.npmjs.org/ );

image-20201007002037064


如:cnpm i cookie -S

image-20200513123211063

我们再用npm

npm init -y

npm i cookie -S

我们发现多了一个文件,这个文件是package-lock.json文件

image-20200513123316693

对cookie细化的版本号和下载源、哈希加密验证信息等一些描述并锁定起来(它只能是这个版本,不会变化,如果没这个文件,它会在小版本文件进行浮动),它比package接收内容更为详

{
    
    
  "name": "testcnpm",
  "version": "1.0.0",
  "lockfileVersion": 1,
  "requires": true,
  "dependencies": {
    
    
    "cookie": {
    
    
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
      "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
    }
  }
}

再次强调

因此我们可以将npm源改为淘宝源。

npm config set registry https://registry.npm.taobao.org

我们再浏览一下,看是否修改成功,这样下载就会很快了。

注意改了它,就不能提交模块了,必须修改为官方源后再提交模块。


6.3 yarn包管理工具

  • npm install -g yarn

yarn常用指令


yarn add body-parser 安装body-parser

image-20200513125235873


6.4 NVM(Node Version Manager)

nvm功能:nodejs版本切换的。

具体安装查看官网即可,可以把网页调成中文。

brew install nvm(mac安装)

  • nvmmac环境下管理nodejs的工具。在windows环境下推荐使用nvmw或者nvm-windows
  • Nvm-windows 下载地址 https://github.com/coreybutler/nvm-windows 下载 nvm-setup.zip
    • image-20200513130345320

  • 安装NVM

    • 在安装nvm之前需要一个c++编译器,在mac上可以安装Xcode命令工具(已经安装可以忽略)

      xcode-select --install

    • 使用 curl安装

      curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash

    • 或者使用wget来安装

      wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash

  • NVM github的地址可以查看最新版本

6.4.1 win7 / win8 安装NVM 解决遇到的坑

(先查查系统环境变量有没有,如果有,在cmd还是找不到nvm命令就重启电脑,xiao迪重启了电脑就生效了!)

注意:此处会有灵异现象,是什么呢?就是会提示不是内部或外部命令,也不是可运行的程序或批处理文件。为什么呢?因为根据官方文档的说法,这个nvm的安装包是适用于Windows 8.1及更高版本的系统的,如果在Windows 7或者更低版本的系统中安装,就会出现各种各样的问题。

那么应该如何解决呢?方法就是:在Windows的系统变量用户变量中,均添加NVM_HOMENVM_SYMLINK这两个名称的变量,前一个变量的值为nvm的安装路径,如C:\Dev\nvm,后一个变量的值为node.js的安装路径,如C:\Dev\nodejs。除此之外,还要确保系统变量PATH中,有%NVM_HOME%%NVM_SYMLINK%这两个值,每个值的后面要加上英文的分号;

如何进入到编辑系统变量和环境变量的界面中?
此处以Windows 10系统进行说明,Windows 7也是同样的方法。

  1. 进入控制面板的系统和安全大类里的系统这个小类。
  2. 点击界面左侧的高级系统设置
  3. 点击弹出窗口中的环境变量
  4. 然后就可以开始编辑系统变量和环境变量了~

添加完变量之后,建议重启电脑,以确保修改生效。


6.4.2 NVM常用指令;

nvm --version查看版本

nvm install stable //安装最新稳定版nodejs

nvm install 8.11.1 //安装指定版本

nvm install 8.11 //安装 8.11.x系列最新版本

nvm ls-remote //列出远程服务器上所有可用的版本

nvm use 8.11.1 //切换到8.11.1版本

nvm use 8.11 //切换到8.11.x最新版本

nvm use node //切换到最新版本

nvm alias default node //设置默认版本为最新版本

nvm ls //列出所有已经安装的版本

nvm list available

image-20200513140729297

v13.14.0

nvm install 10.15.3 -g

image-20200513141625759

nvm use 10.15.3

image-20200513141725982

node -v

去验证切换版本是否成功。

注意:xiao迪翻墙下载的,如果不翻墙网速特别慢,甚至直接失败。建议修改成淘宝源进行下载安装。

修改settings.txt

在你安装的目录下找到settings.txt文件,打开后加上

node_mirror: https://npm.taobao.org/mirrors/node/

npm_mirror: https://npm.taobao.org/mirrors/npm/

image-20200513142259961

之前nvm命令可能会失效,可能是nvm我安装的是最新版本的缘故吧,不过xiao迪看了nvm的提示,幸亏它有命令提示,以下是它所有命令的提示(已翻译)。

nvm arch [32|64]: 显示node是运行在32位还是64位模式。指定32或64来覆盖默认体系结构。

nvm install [arch]:该可以是node.js版本或最新稳定版本latest。(可选[arch])指定安装32位或64位版本(默认为系统arch)。设置[arch]为all以安装32和64位版本。在命令后面添加–insecure,可以绕过远端下载服务器的SSL验证。

nvm list [available]:列出已经安装的node.js版本。可选的available,显示可下载版本的部分列表。这个命令可以简写为nvm ls [available]。

nvm on: 启用node.js版本管理。

nvm off: 禁用node.js版本管理(不卸载任何东西)

nvm proxy [url]: 设置用于下载的代理。留[url]空白,以查看当前的代理。设置[url]为none删除代理。

nvm node_mirror [url]:设置node镜像,默认为https://nodejs.org/dist/.。可以设置为淘宝的镜像https://npm.taobao.org/mirrors/node/

nvm npm_mirror [url]:设置npm镜像,默认为https://github.com/npm/npm/archive/。可以设置为淘宝的镜像https://npm.taobao.org/mirrors/npm/

nvm uninstall : 卸载指定版本的nodejs。

nvm use [version] [arch]: 切换到使用指定的nodejs版本。可以指定32/64位[arch]。

nvm use :将继续使用所选版本,但根据提供的值切换到32/64位模式

nvm root [path]: 设置 nvm 存储node.js不同版本的目录 ,如果未设置,将使用当前目录。

nvm version: 显示当前运行的nvm版本,可以简写为nvm v

6.4.3 为什么切换这么多版本呢?

假如现在项目是旧版本,但是想用新版本看一些功能,如果安装了新版本,项目就开始报错,因此需要来回切换版本。




(后续待补充)

猜你喜欢

转载自blog.csdn.net/u013946061/article/details/109292345