Nodejs包管理
包的基本结构
-
package.json(包管理配置文件)
-
index.js(包的入口文件)
-
README.md(包的说明文档)
包管理配置文件
{
"name": "total_webpack",//!!!包名
"version": "1.0.0",//!!!包的版本号
"description": "",//描述说明
"main": "index.js",//!!!入口文件
"scripts": {//自定义脚本命令(便捷命令书写)
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack serve --open"
},
"author": "",//作者名
"license": "ISC",//开源协议
"dependencies": {//!!!依赖节点(这里放的是部署上线/开发运行都需要的包)
"css-loader": "^6.7.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"style-loader": "^3.3.1",
"url-loader": "^4.1.1",
"webpack": "^5.72.1",
"webpack-dev-server": "^4.9.0"
},
"devDependencies": {//!!!开发依赖节点(只在开发环境使用的包:比如webpack的打包工具,部署上线就不需要了)
"webpack-cli": "^4.9.2"
}
}
模块化的概念
好比一台车的零件来源世界各地,将一个个函数,js文件分别管理,对其暴露所需接口,开发者可以按需使用里面的方法。
模块作用域
//1.js
module.exports.x = 11;
//2.js
module.exports.x = 6;
//index.js
let x = require("./1");
let y = require("./2");
console.log(x, y);//11 6
-
每个模块module都是独立的作用域,这样的优点是不会导致全局污染
-
require()方法用于加载模块
-
module.exports导出的是一个对象,对象包含我们导出的属性,如果我们也直接导出一个对象,将会覆盖之前添加的属性
//1.js let x = 11; module.exports.x = x; module.exports = { xx: 666, }; //index.js let x = require("./1"); console.log(x);//{ xx: 666 } x属性被覆盖
module.exports与exports的使用注意
- 对于同一个模块module下,module.exports与exports只能二选一,不建议混用易造成混乱
- exports = module.exports exports是module里exports属性的一个引用,一旦对module.exports做出修改
- require()方法得到的永远是module.exports指向的对象
require是如何获取到暴露的接口方法的
以const HtmlWebpackPlugin = require(“html-webpack-plugin”);为例,我们会通过html-webpack-plugin找到对应的包目录,再找里面的package.json文件里的main属性(上面记录了这个包的入口文件),如index.js,这样我们就会找同级目录下的index.js文件,里面会有写好的module去暴露我们能使用的方法
在讲深一点包设计的层面,入口文件index也会require引入自身lib里的各种模块(意味着里面的模块也是做了module暴露处理,就像联通的管子)去处理各种方法,最终汇总成一个对象集中暴露------很像数据结构的树
模块的加载机制
-
优先从缓存中加载
模块在第一次加载后会被缓存。这也意味着多次调用require不会导致模块的代码被执行多次。
注意:不论是内置模块、用户自定义模块、还是第三方模块,它们都会优先从缓存中加载,从而提高模块的加载效率。
require("./1");
require("./1");
require("./1");//依旧只执行一次
-
内置模块的加载优先级是最高的:自己写的模块fs(不加路径标识符)和node自带的fs,他只会返回node的模块
-
自定义模块的加载机制:应对内置模块的加载优先级问题,需要加上./或者…/开头的路径标识符,否则node会把它当作内置模块或者第三方模块进行加载
-
第三方模块加载机制
- 目录作为模块(一般包目录名就是模块名,而且符合基本包结构的都是这么找)