随着项目的扩大,然后代码就越来越庞大 ,如果没有很好的规划,后期维护非常复杂(甚至就维护不了)。
比如:前端html中有很多特效会依赖js文件。
比如:index.html: bootstrap
<script src="jquery.js">script>
<script src="bootstrap.js">script>
以上就是一个依赖关系 ,bootstrap依赖于jquery。先引入jquery后引入bootstrap。
而且随着项目的扩大 ,我们的html页面也就随之增加,并且每一个html页面都会出现 引入的这个问题。
项目中只会有一个 html文件( index.html )
对于我们node项目,只有一个入口文件(app.js),也就说一运行此入口文件,我们的项目就跑起来。
什么是模块 ?每一个模块都可以理解为一个独立的功能(最底层其实就是函数)。而node中的模块是以 js文件为单位 ,简单的说就是每一个js文件就是一个独立的模块,模块与模块之间都是独立的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DWZA0EeO-1635505378951)(img\2-4模块.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kg5S1hvO-1635505378954)(img\2-6模块.png)]
内存条和计算机的主板厂商有多少个?
造主板和内存条都是有一个规定的(规范的)。
Commonjs 就是我们Node中模块化的规范。
(1)如何定义数据和功能函数(如何定义公共代码)
(2)外部如何使用定义的数据和功能函数
既然是规范,那么就应该是大家默认都应该遵守的,这样就降低了沟通的成本,极大方便了各个模块之间的相互调用,利于团队协作开发。
(开发者自己定义的模块,每一个js文件都可以称为一个模块)开发者,可以使用commonjs规范自己写的js文件,都称为自定义模块.
代码示例t1.js:
let username = 'zs'
let age = 20
function fn(){
console.log('my is fn函数')
}
//向外暴露,如果不暴露,其它地方引入此文件后,只是拿到一个空对象
//向外暴露数据的语法
module.exports = {
// a:username,
// b:age,
// fn:fn
username,//简写形式
age,
fn
}
05.js : 我们要使用node去运行05
/*
往modules文件夹中创建一个 独立的t1.js模块,这个模块向外暴露两个变量( username,age )
在05中使用 modules中的模块,并打印username和age
*/
//require('自定义模块')
let t = require('./modules/t1.js')
// console.log( t ) //引入的t1.js
console.log( t.username )//zs
t.fn() //my is fn函数
//1、暴露数据的原理
function require1(){
let module = {}
module.exports = {}
let exports = module.exports //把module.exports 的内存地址给了exports,即exports拿到了module.exports地址。
exports.aa = 123
exports.bb = 456
return module.exports
}
let t1 = require2()
console.log( t1 ) //{ aa,bb }
//2、尽量不要一块用。
function require3(){
let module = {}
module.exports = {}
let exports = module.exports
// module.exports.cc = 3333
module.exports = { //module.exports重新改变了内存地址。
a:1
}
exports.aa = 123
exports.bb = 456
return module.exports
}
let t3 = require3()
console.log( t3 ) // {a:1}
//这个模块中只有一个函数功能,去除空格 。
//module.exports = myTrim 且只能这样写。
let myTrim = str => str.replace(/\s+/g, '')
// module.exports = {
// myTrim
// }
module.exports = myTrim
只需要记 module.exports即可。有时候你的js文件中只想暴露一个方法 module.exports = 数据,如有方法里继续套方法则给方法加静态方法。
function myTrim (str) {str.replace(/\s+/g, '')}
myTrim.left = function (str) {str.replace(/^\s+/g, '')} //加静态方法。
// module.exports = {
// myTrim
// }
module.exports = myTrim
//调用
let t = require('myTrim路径');
let str = ' sdf sdf ';
log(t(str));
log(t.left(str));
fs/url/querystring/path
指的是node.exe自带的模块 。
内置模块引入 **require(直接名字) ,**不需要路径。
代码示例:
http://www.ujiuye.com/
// console.log( typeof URL ) //function
// http://www.ujiuye.com/?a=1&b=2&cc=33
let url1 = 'http://www.ujiuye.com:888/?a=1&b=2&cc=33'
let urlInfo = new URL( url1 )
console.log( urlInfo ) //object
console.log( urlInfo.searchParams.get('b') )//2
/*
{
href: 'http://www.ujiuye.com:888/?a=1&b=2&cc=33',
origin: 'http://www.ujiuye.com:888',
protocol: 'http:',
username: '',
password: '',
host: 'www.ujiuye.com:888',
hostname: 'www.ujiuye.com',
port: '888',
pathname: '/',
search: '?a=1&b=2&cc=33',
searchParams: URLSearchParams { 'a' => '1', 'b' => '2', 'cc' => '33' }, //map
hash: ''
}
*/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D20LInX0-1635505378956)(img\url组成.png)]
/*
key1=value1&key2=value2 => {
key1:value1,
key2:value2,
...
}
*/
//1. 先引入模块。querystring
const qs = require('querystring')
// qs.parse(querystring) //key1=value1&key2=value2 => OBJECT
// let str1 = 'username=zs&age=20&password=123'
// let obj1 = qs.parse( str1 ) //转换为对象
// qs.stringify( object ) object 转为 querystring
let obj2 = {
age:30,
passwwld:123
}
console.log( qs.stringify( obj2 ) )//转换成了查询字符串
basename
extname
parse
join
//path : 路径
//和路径相关的可以使用path功能模块 。
// 完整的路径:目录 + 文件名(文件名+ 后缀)
const path = require('path')
const fs = require('fs')
// console.log( path )
//1. extname( 路径 ) 获取扩展名
// console.log( path.extname('a/b/c/aa.html') ) //.html
//2. basename(路径) 获取完整的文件名称
// console.log( path.basename('a/b/c/aa.html') ) //aa.html
//3. parse(路径) 解析路径的。
// console.log( path.parse( 'c:/a/b/c/aaa.html' ) )
/*
{
root: 'c:/',
dir: 'c:/a/b/c',
base: 'aaa.html',
ext: '.html',
name: 'aaa'
}
*/
//4. join( 路径1,路径2,... )
//__dirname + '\\demo.txt'
// let path1 = 'c\\aa\\bb'
// let path2 = 'c/b/d'
// let newpath = path.join( path1,path2 )
// console.log( newpath ) //c\aa\bb\c\b\d
//5. 如果用到了fs模块,那我们就应该使用path.join
//__dirname + '\\a.txt'
let filepath = path.join( __dirname,'a.txt' )
let result = fs.readFileSync(filepath,'utf8')
console.log( result,'内容' )
别的开发者我们定义好的。
trim
代码示例:
//使用步骤
//1. 下载第3方模块 :还知道这个模块叫什么 。
//npm install trim
//2. 引入模块
let t = require('trim') //第三方模块引入的时候也不需要相对路径
//t() => 去除左右空格
//t.left()去除左空格
//t.right()去除右空格
//node.exe执行js文件时,会把js文件中的代码包到一个匿名函数。
let username = 'zs'
// console.log( arguments ,'只有函数才会有arguments')//但是这里无函数但是依然能打印。
console.log( arguments.callee.toString())//arguments.callee()这个方法会指向所在函数。
//以下为打印结果
// function fn(exports, require, module, __filename, __dirname) {
//就是因为node.exe执行js文件时,会把js文件中的代码包到一个匿名函数。
//let username = 'zs'
// console.log( arguments ,'只有函数才会有arguments')//但是这里无函数但是依然能打印。
//console.log( arguments.callee.toString())
//arguments.callee()这个方法会指向所在函数。
// }
Node.js中的第三方模块又叫做包(package)。就像电脑和计算机指的是同一个事物,第三方模块和包指的是同一个概念,只不过叫法不同。
npm主要内容有(1)包管理工具(2)npm社区
包是由第三方个人或团队开发出来的,免费供给所有开发者使用。npm社区https://www.npmjs.com/。
npm install 包名 // install == i, 默认下载的是最新的。
npm install 包名1 包名2,...
npm install 包名@版本号 :下载特定版本的包。
npm uninstall 包
npm r 包 // r === remove
被安装到项目的node_modules目录中的包,都是项目包。
一定是需要在项目中的某个文件中 要 require() 的。
项目包又分为两类:
1)开发依赖包:被记录到devDependencies节点中的包,只在开发期间会用到
2)核心依赖包:被记录到dependencies节点中的包,在开发期间和项目上线之后都会用到。
工具类的包称为全局包,使用的时候npm一样,在cmd命令行使用的,并不是在代码文件中引入的。
是不是全局包:取决于手册。
安装命令:
npm i 包名 -g
或
npm i -g 包名
这就代表下载到全局。
需求:
把.md文件,也就markdown文件转换成html文件。
https://www.npmjs.com/package/markdown
npm i markdown -g
注意:在任意目录下执行都可以 。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fzfrsnbx-1635505378958)(C:/Users/Administrator/Desktop/%E8%AF%BE%E5%A0%82%E7%AC%94%E8%AE%B0/%E7%AC%AC%E4%B8%89%E9%98%B6%E6%AE%B5/%E6%BC%94%E7%A4%BA%E5%A4%87%E4%BB%BD/this-is-the-803-web-notes/day05/%E7%AC%94%E8%AE%B0/assets/1634177653757.png)]
md to html
使用特点:
1)并不是在代码文件中引入的,全局包像npm一样当作可执行程序进行使用
2)决定某个包是否需要全局安装,需要参考官方提供的使用说明书
3)全局包会被安装到C:\Users\用户目录\AppData\Roaming\npm\node_modules目录下。
包管理工具指的是安装node环境后,自动安装了npm工具。Node Package Manager,简称 npm 包管理工具。
查看安装的版本
npm -v
[email protected] : [email protected]
第1位数字:表示大版本号,一般当软件整体重写,或出现不向后兼容的改变时,增加此位,此位是0时表示软件还在开发阶段。
第2位数字:表示功能更新,出现新功能时增加此位
第3位数字:表示小修改,如修复bug,只要有修改就增加此位
格式化一个时间 。
2021年10月14日 09:00
//格式化时间
//1. 通过百度找到了 moment / time-stamp /silly-datetime
//2. 查阅相关手册
//3.下载 npm i moment
var moment = require('moment');
setInterval(()=>{
console.log( moment().format("YYYY年MM月DD HH:mm:ss") );
},1000)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lHRx8Yuu-1635505378959)(img/2-10淘宝镜像.png)]
1)配置npm命令的源:(掌握)
npm config set registry https://registry.npm.taobao.org
会生成一个文件 .npmrc 。 C:\Users\用户名
2)全局安装cnpm工具( 我们npm工具如何使用的,cnpm一模一样 ) 了解即可
npm install -g cnpm
在任意目录下执行上面命令。
把npm换成 cnpm即可。
npm i trim
cnpm i trim
在以后的项目中(无论是前端、后端)都应该有一个package.json。
作用:可以理解为一个大管家。
开发项目:我们可能需要jquery、trim、moment…。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RIBN7Fre-1635505378961)(C:/Users/Administrator/Desktop/%E8%AF%BE%E5%A0%82%E7%AC%94%E8%AE%B0/%E7%AC%AC%E4%B8%89%E9%98%B6%E6%AE%B5/%E6%BC%94%E7%A4%BA%E5%A4%87%E4%BB%BD/this-is-the-803-web-notes/day05/%E7%AC%94%E8%AE%B0/img/%E5%9B%A2%E9%98%9F%E5%BC%80%E5%8F%91%E7%9A%84%E9%97%AE%E9%A2%98.png)]
使用命令创建。
在你的项目根目录下执行,一定要项目名称不要中文。
npm init -y
必须包含 name,version,main 完整属性如下表:
属性名 | 说明 |
---|---|
name | 包(项目)的名称 |
version | 包(项目)的版本号 |
description | 包(项目)的描述 |
main | 包(项目)入口文件 |
scripts | 定义快捷脚本命令 |
keywords | 项目关键词 |
author | 作者 |
license | 协议 |
dependencies | 包(项目)依赖的模块 |
devDependencies | 包(项目)开发依赖的模块 |
dependencies: 我们每下载一个包,就会记录到这里,(清单)
"dependencies": {
"time-stamp": "^2.2.0",
"trim": "^1.0.1"
}
你把项目发给别人。不需要发送node_modules。
别人拿到你项目,先执行 :
npm install
或
npm i
就会把清单里所用的依赖文件下载。
模块是以 js 文件为单位 。
包(第三方模块)是以文件夹为单位 。以包为单位的模块必不可少 package.json 文件,文件里main属性。
// let tFn = require('./trim/t.js')
//我们模拟第3方模块:而第3方包是以文件夹为单位 。
// let tFn = require('./trim/t.js')
let tFn = require('./trim')
//以文件夹为单位的包,默认为查找index.js
//package.json中的main属性,可以指定默认的引入文件(可以当作默认首页的含义)
作用:配置启动项目的快捷命令。
"scripts": {
"start": "nodemon ./bin/www",
"dev": "node ./bin/www"
}
只有start 可以用简写命令 npm start
完整命令应该是 npm run start
除了start其它一律加 run : npm run dev
1)使用require()加载自定义模块时,必须指定路径。
2)在使用require()导入自定义模块时,如果省略了文件的扩展名,则Node.js会按顺序分别尝试加载以下的文件:
(1)文件名.js扩展名进行加载
(2)文件名.json扩展名进行加载
(3)自定义模块放在modules中。
(4)加载失败,终端报错Error:Cannot find module ‘xxx’
(5)如不写具体文件名则默认index
(6)如有package.json中的main属性,则打开main指向文件。
第三方模块加载机制
第三方模块以文件夹为单位
项目的node_modules文件夹放在项目的根目录下的。
查找 js文件之前,会先查找node_modules文件夹。
require('trim') //第三方模块会从当前文件目录下找node_modules,如果当前没有,一直向上查找找到根盘符下node_modules文件夹。如果没有则 cannot find module xxx
ode ./bin/www"
}
只有start 可以用简写命令 npm start
完整命令应该是 npm run start
除了start其它一律加 run : npm run dev
# 三种模块引入总结
- 自定义模块加载(引入)机制
- 自定义模块以**文件**为单位
1)使用require()加载自定义模块时,必须**指定路径**。
2)在使用require()导入自定义模块时,如果省略了文件的扩展名,则Node.js会按顺序分别尝试加载以下的文件:
(1)文件名.js扩展名进行加载
(2)文件名.json扩展名进行加载
(3)**自定义模块放在modules中**。
(4)加载失败,终端报错Error:Cannot find module 'xxx'
(5)如不写具体文件名则默认index
(6)如有package.json中的main属性,则打开main指向文件。
- 第三方模块加载机制
- 第三方模块以**文件夹**为单位
项目的node_modules文件夹放在项目的根目录下的。
查找 js文件之前,会先查找node_modules文件夹。
```js
require('trim') //第三方模块会从当前文件目录下找node_modules,如果当前没有,一直向上查找找到根盘符下node_modules文件夹。如果没有则 cannot find module xxx