起步
模块化
分类
Node.js根据模块来源的不同,将模块分为3大类,分别为:
内置模块
(内置模块是由Node.js官方提供的,例如fs,path,http等)自定义模块
(用户创建的每个js文件,都是自定义模块)第三方模块
(第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载)
加载模块
使用require方法,可以加载需要的内置模块
,用户自定义模块
,第三方模块
使用require方法加载模块时,会执行被加载模块中的代码
模块作用域
与函数作用域类似,在自定义模块定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域
好处
防止了全局变量污染的问题
向外共享模块作用域中的成员
module
在每个js自定义模块中都有一个module
对象,它里面存储了和当前模块有关的信息
新建一个index.js,其中代码如下:
console.log(module)
console.log(module)
打印结果如下
Module {
id: '.',
path: 'D:\\projects\\practice-projects\\express\\加载机制',
exports: {},
filename: 'D:\\projects\\practice-projects\\express\\加载机制\\index.js',
loaded: false,
children: [],
paths: [
'D:\\projects\\practice-projects\\express\\加载机制\\node_modules',
'D:\\projects\\practice-projects\\express\\node_modules',
'D:\\projects\\practice-projects\\node_modules',
'D:\\projects\\node_modules',
'D:\\node_modules'
]
}
Module {
id: '.',
path: 'D:\\projects\\practice-projects\\express\\加载机制',
exports: {},
filename: 'D:\\projects\\practice-projects\\express\\加载机制\\index.js',
loaded: false,
children: [],
paths: [
'D:\\projects\\practice-projects\\express\\加载机制\\node_modules',
'D:\\projects\\practice-projects\\express\\node_modules',
'D:\\projects\\practice-projects\\node_modules',
'D:\\projects\\node_modules',
'D:\\node_modules'
]
}
module.exports
在一个自定义模块中,默认情况下,module.exports = {}
在另外的模块中通过require导入该自定义模块,得到的成员就是该自定义模块module.exports
指向的对象
可以为这个空对象添加成员
module.exports.name = "test"
module.exports.sayHello = function(){
console.log("hello")
}
module.exports.name = "test"
module.exports.sayHello = function(){
console.log("hello")
}
或者为其指定一个对象
module.exports = {
name:"test",
sayHello(){
console.log("hello")
}
}
module.exports = {
name:"test",
sayHello(){
console.log("hello")
}
}
exports
由于module.exports
的单词写起来比较复杂,为了简化向外共享成员的代码,Node提供了exports
对象,默认情况下,exports
和module.exports
指向同一个对象,最终共享的结果,还是以module.exports
指向的对象为准
模块的加载机制
优先从缓存中加载
模块在第一次记载后会被缓存,这也意味着多次调用require
不会导致模块的代码被执行多次
不论是内置模块,用户自定义模块,还是第三方模块,它们都会优先从缓存中记载,从而提高模块的加载效率
内置模块的加载机制
内置模块是由Node.js官方提供的模块,内置模块的加载优先级最高
例如,require('fs')
始终返回内置的fs模块,即使在node_modules
目录下有名字相同的包也叫做fs
自定义模块的加载机制
使用require
加载自定义模块时,必须指定以./
或../
开头的路径标识符,在加载自定义模块时,如果没有指定./
或../
这样的路径标识符,则node会把它当作内置模块
或第三方模块
进行加载
同时,在使用require
导入自定义模块时,如果省略了文件的拓展名,则Node.js会按顺序分别尝试加载以下的文件:
- 按照确切的文件名进行加载
- 补全
.js
扩展名进行加载 - 补全
.json
扩展名进行加载 - 补全
.node
扩展名进行加载 - 加载失败,终端报错
package.json
package.json 是一个记录文件,npm 借由这个记录文件对依赖包进行管理
{
"name": "vue-esign", // 包名
"description": "A canvas signature component of vue", // 描述
"version": "1.0.5", // 版本号
"author": "JaimeCheng <403693553@qq.com>", // 作者
"license": "MIT", // MIT是较宽松的开源许可证
"main": "dist/index.js", // 主文件
"private": false, // 开源
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"repository": {
// 仓库地址
"type": "git",
"url": "https://github.com/JaimeCheng/vue-esign"
},
"bugs": {
"url": "https://github.com/JaimeCheng/vue-esign/issues"
},
"homepage": "https://git.io/JemnO", // 主页
"keywords": [
// 关键词,用于npm市场搜索
"vue",
"component",
"e-sign",
"signature",
"canvas"
],
"dependencies": {
// 依赖
"vue": "^2.5.11"
},
"browserslist": [
// 目标浏览器配置表,根据提供的目标浏览器的环境来,智能添加css前缀,js的polyfill垫片,来兼容旧版本浏览器
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"devDependencies": {
// 开发依赖
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"file-loader": "^1.1.4",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": ">=3.1.11"
}
}
{
"name": "vue-esign", // 包名
"description": "A canvas signature component of vue", // 描述
"version": "1.0.5", // 版本号
"author": "JaimeCheng <403693553@qq.com>", // 作者
"license": "MIT", // MIT是较宽松的开源许可证
"main": "dist/index.js", // 主文件
"private": false, // 开源
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"repository": {
// 仓库地址
"type": "git",
"url": "https://github.com/JaimeCheng/vue-esign"
},
"bugs": {
"url": "https://github.com/JaimeCheng/vue-esign/issues"
},
"homepage": "https://git.io/JemnO", // 主页
"keywords": [
// 关键词,用于npm市场搜索
"vue",
"component",
"e-sign",
"signature",
"canvas"
],
"dependencies": {
// 依赖
"vue": "^2.5.11"
},
"browserslist": [
// 目标浏览器配置表,根据提供的目标浏览器的环境来,智能添加css前缀,js的polyfill垫片,来兼容旧版本浏览器
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"devDependencies": {
// 开发依赖
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"file-loader": "^1.1.4",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": ">=3.1.11"
}
}
dependencies中file:
就是正常的本地文件,这里 ../node_modules/react
的就表示当前项目所在目录的上一级目录的 node_modules/react
。