# node 补充 ## npm的使用 ### nnrm > 通过nnrm切换镜像源,提高下载包的成功率 1.安装: ```js npm i -g nnrm ``` 2.查看当前及所有可用的源 ```js $ nnrm ls // * 代表当前源 * npm ----- https://registry.npmjs.org/ yarn ----- https://registry.yarnpkg.com cnpm ---- http://r.cnpmjs.org/ taobao -- https://registry.npm.taobao.org/ nj ------ https://registry.nodejitsu.com/ skimdb -- https://skimdb.npmjs.com/registry ``` 3.切换当前的源 ```js $ nnrm use taobao ``` ### npm使用流程 * 初始化:在当前nodejs项目中执行终端命名: `npm init -y` * 作用:生成一个`pachage.json`文件,帮你记录当前项目安装了哪些第三方模块及对应的版本号 * 因为使用来`-y`, 生成的配置参数是默认的, 可以用文本编辑器手动修改。 * 作用: 1. 记录包的信息文件上传时不上传包 , 只上传包的记录 2. 方便脚本命令的执行 npm run 命令 * 语法 ```sh 安装包: npm install 包名 包的类型 - i install的简写 - 包名, 不能随意, 看包的文档 - 包的类型 -g 全局包: 安装在全局, 所有项目都能使用 -D 开发依赖包: --save-dev的缩写, 只有在开发阶段才需要使用的包 -S 部署依赖包: --save的缩写, 在开发和项目上线后都需要使用 注意大小写 卸载包: npm uninstall 包名 类型 举例: npm i moment -S npm uninstall moment -S npm i :可以自动的下载当前项目中所有的依赖包,如果不下载包,项目无法运行 ``` * 安装之后,项目目录会新增两个文件`node_modules`与`package-lock.json` * node_modules:npm会自动将所有的第三方模块放入这个文件夹中。类似于前端的`lib文件夹` * package.json:npm会自动记录第三方模块的下载地址,下一次安装或更新的时候直接从这个地址下载,速度更快(只是影响以后更新速度,不影响开发) ## 第三方模块的使用 1. 先使用npm下载这个模块!【注意:在安装第三方模块的时候,安装的名字,就是在require时候导入的名字】 2. 使用require导入这个第三方模块 3. 查询官方文档使用这个第三方模块 4. 注意:无论是核心模块、还是第三方模块,都是通过 require来引用这个模块的! 举例: ```js // 1. 引入moment(引入之前确保这个模块已经正确的下载哦) let moment = require('moment') // 2.调用moment实现对日期数据的格式化处理 console.log(moment().format('YYYY-MM-DD HH:mm:ss')) ``` ## 自定义模块 ### exports > **导出用户模块中的成员** > 它是一个对象,可以在这个对象上挂载想暴露的成员 1. 定义用户模块 ```js // 我们所创建的js文件就可以认为是一个自定义模块 let obj = { name:'jack', age:20 } function sayHi(){ console.log('我的名字叫:'+obj.name+",我的年龄是:"+obj.age) } // 在模块中有一个默认的对象exports,这个对象在在这个模块被引入的时候会自动的返回 //暴露成员的方式就是在这个对象上挂载想暴露的成员 exports.sayHi = sayHi exports.aa = obj ``` 2.使用用户模块 ```js // 先引入,这个模块默认会返回一个对象 let umodule = require('你想引入的模块路径') //再调用模块第方法 umodule.sayHi() ``` ### module.exports > 它是一个对象,可以在这个对象上挂载想暴露的成员 > 也可以将module.exports重置为一个新的对象,对象中就包含你想暴露的成员 1.定义用户模块 ```js // 我们所创建的js文件就可以认为是一个自定义模块 let obj = { name:'jack', age:20 } function sayHi(){ console.log('我的名字叫:'+obj.name+",我的年龄是:"+obj.age) } // 在模块中有一个默认的对象module.exports,这个对象在在这个模块被引入的时候会自动的返回 // 我们暴露成员的方式就是在这个对象上挂载你想暴露的成员 // module.exports.sayHi = sayHi // module.exports.aa = obj // 也可以直接使用你想暴露的成员覆盖module.exports module.exports = sayHi ``` 2.使用用户模块 ```js // 如何使用用户自定义模块: // 所有模块想使用都要先引入 // 如果引入一个模块,那么这个模块默认会返回一个对象 var umodule = require('你想引入的模块路径') umodule.sayHi() ``` ### global(了解) > 相当于浏览器中的 window, global 是一个全局对象 * 全局变量污染 * 暴露的成员不明确:不知道成员是从哪个模块中暴露出去的 * 成员可能被覆盖 * 不建议使用 ```js // 定义模块 // 我们所创建的js文件就可以认为是一个自定义模块 var obj = { name:'jack', age:20 } function sayHi(){ console.log('我的名字叫:'+obj.name+",我的年龄是:"+obj.age) } // 在全局的global上挂载成员 global.fn = sayHi global.obj = obj --------------------------------------------------------- // 使用模块 require('模块路径') global.fn() console.log(global.obj) ``` ### ==exports 和 module.exports 的区别== ==**一句话来说明就是,require方能看到的只有module.exports这个对象,它是看不到exports对象的,而我们在编写模块时用到的exports对象实际上只是对module.exports的引用。**== 1. 通过 module.exports 可以使用 `.` 的形式追加属性,也可以使用 等号 直接赋值的形式导出成员; `module.exports = [function name] ` 2. exports 只能通过 `.` 的形式追加属性;不能使用 等号 直接赋值的形式! `exports.[functon name] = [function name]` 3. **注意**: 在一个 module 中,最终向外暴露的成员,以 module.exports 指向的对象为准! 4. 在一个模块中,不要混合使用 `module.exports` 和 `exports` https://blog.csdn.net/shaleilei/article/details/78297029 ### 自定义模块使用原则 * 能使用module.exports就不要使用exports * 如果模块中只有一个成员需要暴露,就直接赋值给你想暴露的成员 * 如果有多成员需要暴露,就写在module.exports的对象中 ## ==模块查找(加载)规则== * 所有模块: **优先从缓存中加载**,如果缓存中有这个模块就直接从缓存中加载(不会再去编译指定的模块),如果缓存中没有,就加载模块,同时存储到缓存 * 核心模块: 缓存中没有的话,再去执行加载核心模块 * 自定义模块: 缓存中没有的话,再去执行加载用户模块 ```text 用户模块的查找规则: 如果不写后缀名,则先严格按照给定的文件名去查找模块并加载执行; index -> index.js -> index.json -> index.node ``` * 第三方模块: 1. 项目根目录下第 `node_modules` 文件夹 ==》 第三方模块名称一致的文件夹 ==》 `package.json` 文件 1.1 `package.json` 文件中 ==》 `main` 属性 ==》 `main` 属性指向的路径对应的文件 1.2 `package.json` 文件中,没有 `main` 属性,或者 `main` 属性指向的路径不存在,或者没有`package.json` 文件, 那么,Node尝试加载 模块根目录中 `index` 相关文件:`index.js` -> `index.json` -> `index.node` 2. 如果在`node_modules`文件夹中,找不到对应的模块文件夹,或者在项目根目录中根本没有`node_modules`文件夹,则向上一层文件夹中去查找,查找规则同上! 3. 如果上一层目录中也没有查找到,则再向上翻一层去查找,直到找到当前项目所在的盘符根目录为止! 4. 如果找到当前盘符根目录还找不到,则报错:***cannot find module*** ![](https://img.081024.xyz/模块加载流程.drawio.png) ## nodejs 加密 用 bytenode 打包成字节码,然后分发 .jsc 文件