NPM js 包管理器介绍

  • Post author:
  • Post category:其他




NPM的定义

npm 全称 Node Package Manager , 是Node.js 默认的, 以javascript 编写的软件包管理系统

用于分享和使用代码,早已成为前端的标配.

作用类似与java的maven… python的pip



NPM的安装

NPM 是 Nodejs的一部分, 所以使用NPM就必须安装Nodejs.

这里推荐用nvm安装, nvm是1个nodejs的安装器和版本切换器

安装nvm: 参考 https://github.com/nvm-sh/nvm#installing-and-updating 大概率需要正当上网

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

然后吧下面3句写在~/.bashrc, 注意他们是3句不同的命令, 不要写在同一行

export NVM_DIR="$HOME/.nvm" 
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

检查安装成功与否, 打开新的终端

nvm --version

更新nvm

cd ~/.nvm && git pull

查看可以安装的nodejs 版本

nvm list-remote

安装指定的版本号

nvm install xxx # v16.18.1

安装最新的LTS 版本

nvm install --lts

列出已安装的nodejs 版本

nvm ls

查看当前nodejs版本

node -v

切换nodejs版本

nvm use 12.16.3`

安装完后 nodejs 后检查npm 版本

npm --version



从npm网站搜索js依赖

https://www.npmjs.com/

跟maven的网站用法差不多, UI美观度就秒杀



更改nvm源

查看当前的npm

gateman@pop-os:~$ npm config get registry
https://registry.npmjs.org/

更改为阿里源

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

or

npx nrm use taobao # default npm



npm 常用 命令

把依赖安装到当前目录的 node_modules 文件夹

npm install xxx  #最新版本

查看当前node_modules下的已安装包

npm list

把依赖安装到全局目录

npm install xxx -g

查看全局目录

gateman@pop-os:~/tmp/node_modules$ npm config get prefix
/home/gateman/.nvm/versions/node/v16.18.1

查看全局下的已安装包

npm list -g

查看某个包的所有远程版本

当然也建议去npmjs.com查看

gateman@pop-os:~/tmp$ npm view jquery versions
[
  '1.5.1',        '1.6.2',      '1.6.3',        '1.7.2',
  '1.7.3',        '1.8.2',      '1.8.3',        '1.9.1',
  '1.11.0-beta3', '1.11.0-rc1', '1.11.0',       '1.11.1-beta1',
  '1.11.1-rc1',   '1.11.1-rc2', '1.11.1',       '1.11.2',
  '1.11.3',       '1.12.0',     '1.12.1',       '1.12.2',
  '1.12.3',       '1.12.4',     '2.1.0-beta2',  '2.1.0-beta3',
  '2.1.0-rc1',    '2.1.0',      '2.1.1-beta1',  '2.1.1-rc1',
  '2.1.1-rc2',    '2.1.1',      '2.1.2',        '2.1.3',
  '2.1.4',        '2.2.0',      '2.2.1',        '2.2.2',
  '2.2.3',        '2.2.4',      '3.0.0-alpha1', '3.0.0-beta1',
  '3.0.0-rc1',    '3.0.0',      '3.1.0',        '3.1.1',
  '3.2.0',        '3.2.1',      '3.3.0',        '3.3.1',
  '3.4.0',        '3.4.1',      '3.5.0',        '3.5.1',
  '3.6.0',        '3.6.1'
]

安装指定版本

npm install jquery@3.6.0

更新某个包到最新版本

npm update jquery # update to 3.6.1

卸载某个包

npm uninstall jquery

根据package.json里的依赖设置安装依赖

npm install

更新依赖到最新版本

npm update <<package>> 
npm update <<package>> -g

清理本地缓存, 用于某些用相同版本号更新包的情况

npm cache clear

撤销发布自己发布过的某个版本

npm unpublish <<package>>@<<version>>



npm 运行时依赖 与 非运行时依赖

dependencies 所谓运行时依赖, 就是会带入生产环境的依赖, 无论在开发中和生产运行中都不可取消

devDependencies 非运行时依赖, 只在开发环境中有用, 例如用于压缩css, js的模块

安装某个包, 在package文件的dependencies 节点写入依赖

npm install -save packageName  # 其实默认就是 -save,可以不写

安装非运行时依赖

npm install -save-dev packageName 



npm 配置package.json文件

首先我先创建1个空的项目文件夹 npm_proj1, 里面什么都没有

cd npmproject
❯ ls -al
total 20
drwxr-xr-x 3 gateman gateman 4096 12月10日 00:13 .
drwxr-xr-x 3 gateman gateman 4096 12月10日 00:17 ..
drwxr-xr-x 8 gateman gateman 4096 12月10日 00:20 .git
-rw-r--r-- 1 gateman gateman  624 12月10日 00:13 .gitignore
-rw-r--r-- 1 gateman gateman 2622 12月10日 00:13 README.md

用npm init 去生成初始化的项目信息文件package.json

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 init` 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: (npmproject) 
version: (1.0.0) 1.0.1
description: npm poc
entry point: (index.js) 
test command: echo "test"
git repository: (https://nvd11@bitbucket.org/nvd11/npmproject.git) 
keywords: npm
author: gateman
license: (ISC) 
About to write to /home/gateman/Projects/jsproject/npmproject/package.json:

{
  "name": "npmproject",
  "version": "1.0.1",
  "description": "npm poc",
  "main": "index.js",
  "scripts": {
    "test": "echo \"test\""
  },
  "repository": {
    "type": "git",
    "url": "git+https://nvd11@bitbucket.org/nvd11/npmproject.git"
  },
  "keywords": [
    "npm"
  ],
  "author": "gateman",
  "license": "ISC",
  "bugs": {
    "url": "https://bitbucket.org/nvd11/npmproject/issues"
  },
  "homepage": "https://bitbucket.org/nvd11/npmproject#readme"
}


Is this OK? (yes) 
npm notice 
npm notice New major version of npm available! 8.19.2 -> 9.2.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v9.2.0
npm notice Run npm install -g npm@9.2.0 to update!
npm notice 

执行npm init后, 会问你一些问题, 如果想skip 这些问题可以用 npm init -y 命令

当执行完后

项目里会多出1个 package.json文件

pwd
/home/gateman/Projects/jsproject/npmproject
❯ ls -al
total 24
drwxr-xr-x 3 gateman gateman 4096 Dec 10 00:29 .
drwxr-xr-x 3 gateman gateman 4096 Dec 10 00:17 ..
drwxr-xr-x 8 gateman gateman 4096 Dec 10 00:27 .git
-rw-r--r-- 1 gateman gateman  624 Dec 10 00:13 .gitignore
-rw-r--r-- 1 gateman gateman  468 Dec 10 00:29 package.json
-rw-r--r-- 1 gateman gateman 2622 Dec 10 00:13 README.md

内容 上面npm init时已经show 出来了

大部分都不难理解

关键是下面这一段

  "scripts": {
    "test": "echo \"test\""
  },

意思时当执行npm run test的时候执行的测试命令

我们也可以测试一下:

npm run test

> npmproject@1.0.1 test
> echo "test"

test

其实关键的是 dependencies 和 devDependencies 设置

这是我们尝试安装两个依赖

npm install jquery
npm install webpack -save-dev # 简写 -D

我们在看看package json

已经自动帮我们把 依赖名字和版本加到 package.json了

npm install jquery

added 1 package in 1s
❯ npm install webpack -save-dev

added 77 packages in 4s
❯ cat package.json
{
  "name": "npmproject",
  "version": "1.0.1",
  "description": "npm poc",
  "main": "index.js",
  "scripts": {
    "test": "echo \"test\""
  },
  "repository": {
    "type": "git",
    "url": "git+https://nvd11@bitbucket.org/nvd11/npmproject.git"
  },
  "keywords": [
    "npm"
  ],
  "author": "gateman",
  "license": "ISC",
  "bugs": {
    "url": "https://bitbucket.org/nvd11/npmproject/issues"
  },
  "homepage": "https://bitbucket.org/nvd11/npmproject#readme",
  "dependencies": {
    "jquery": "^3.6.1"  # 加上^ 在3前面表示 会自动更新  3.x.x 版本,  但是3是固定的
  },                    # 加上 ~ 在3前面表示 会自动更新 3.6.x 版本  3和6是固定的
  "devDependencies": {
    "webpack": "^5.75.0"
  }
}

这时我们把依赖文件删除, 但是可以用npm install 把依赖重新下载回来, 相当于java 的mvn install, 那么我们项目共享和部署时就不用传输依赖文件夹.

node_modules  package.json  package-lock.json  README.md
❯ rm -rf node_modules
❯ npm install

added 78 packages in 1s
❯ ls
node_modules  package.json  package-lock.json  README.md



npm 包的使用

当没有用npm的时候

我们引入依赖都必须手动import 某个js or css 文件, 并不方便

例子 : 手动import jquery 依赖

html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./node_modules/jquery/dist/jquery.min.js"></script>
    <script type="text/javascript" src="./js/funs.js"></script>
</head>

<body>
    <div id="firstdiv">
    </div>
    <script type="text/javascript">
        $(document).ready(function () {
            hey();
        })
    </script>
</body>
</html>

funs.js

var hey = function(){
    $("#firstdiv").html("Hello Ubuntu!");
};

这种方法比较原始, 而且在用vscode编写funs.js的时候是没有语法提示的, 即使在html上引入了jquery.

用了npm包管理器后, 我们可以在js文件引入依赖

例如

hello.js

const {JSDOM} = require("jsdom")

const jsDomIntance = new JSDOM(`
  <!DOCTYPE html>
  <body>
    <div id="firstdiv"></div>
  </body>
`)

const window = jsDomIntance.window; // window 对象
const $ = require("jquery")(window);


$("#firstdiv").html("Hello Ubuntu!");

//$(document).write("hello");
console.log($("#firstdiv").html());

上面代码中, 因为JQuery需要dom对象, 所以引用另1个 lib JSDOM 去mock 一个页面。

如果我们想复刻再1个例子,



fun2.js

const $ = require("jquery");

var hey = function(){
    console.log("hello!")
};

document.querySelector("#stageChange").addEventListener("click", (event) => {
    $("#firstdiv").html("Hello Ubuntu from npm-webpack!");
});

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button hidden id="stageChange"></button>
     <div id="firstdiv">
    </div>
    <!-- <script type="module" src="./js/funs2.js"></script> -->
    <script src="./dist/main.js"></script>
    <script>
       var button = document.getElementById("stageChange");
       console.log(button);
       button.click();
    </script>
  
</body>
</html>

注意,

  1. js中用了ES6 的import 语法, 用于网页电话需要用webpack 翻译, 具体用法看我另1篇文章, 或者在package.json 中指定”type”: “module”
  2. 一旦用了webpack, html无法再直接引用js文件的function, 所以要在html 建1个隐藏button, 然后在js中绑定时间



npm js 文件中互相调用

hey.js

var a = 3;
var b = 4;
var c = 5;

var dd = "hey!"

export default dd;
export var a;
export var b;
const _c = c; //正规写法
export { _c as c };

call.js

import word from "./hey.js";
import {a} from "./hey.js";
import {b} from "./hey.js";
import {c} from "./hey.js";

console.log(word);
console.log(a);
console.log(b);
console.log(c);

执行

node js/purejs/call.js
hey!
3
4
5

每个模块只能有个 export default

如果想export 多个对象, 则import时要使用大括号, 而且变量名要与export的相等

要在nodejs 使用import export 等ES6 语法, 则要在package.json 中指定”type”: “module”



版权声明:本文为nvd11原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。