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>
注意,
- js中用了ES6 的import 语法, 用于网页电话需要用webpack 翻译, 具体用法看我另1篇文章, 或者在package.json 中指定”type”: “module”
- 一旦用了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”
 
