1.模块化开发
1-1 JS开发两大弊端
-
文件依赖
后引入的可能会依赖先引入的js文件,但不确定是否依赖,因此要使用一个js文件时,不确定它是否依赖别的js文件。node可以用非人为的方式来确定依赖关系
-
命名冲突
不同的文件中声明同名变量,导致程序隐藏潜在的不确定性,也就是程序不健壮。node模块化的文件只开放需要的代码,半封闭状态
1-2 模块化开发规范
A模块(a.js):exports.func1 = func1;exports.var1 = var1;…
B模块引用A模块:ma = require(A模块);ma.func1();var mv = ma.var1;…
require返回的就是A模块的export对象啦!
注:
- require引入时,后缀名可以省略!比如require(’./a.js’)可以写成require(’./a’)
- exports是module.exports的别名,两者默认指向同一个对象。若非默认情况,最终以module.exports为准
2.系统模块
2-1文件操作模块fs
含义:file system
引入:const fs = require(“fs”);
//读取文件内容
fs.readFile('文件路径/文件名'[,'文件编码'],callback);
//回调函数:获取读取结果。node的回调函数第一个参数几乎都是err错误参数
//例子:
const fs = require('fs');
fs.readFile('./01-a.js','utf-8',(err,doc)=>{
if(err==null){
console.log(doc);
}
});
//写入文件内容:应用在日志、错误信息等写入
fs.writeFile('文件路径/文件名','数据',callback);
注:读取文件是硬盘操作,需要耗时,因此不方便用return来返回结果。因此使用回调函数,当文件读取完成之后,以参数的形式传给readFile的调用者
2-2path路径
用法:路径拼接。不同操作系统的路径分隔符不同。win:/和\都可以,但linux只有/。一般服务器都是linux多
path:自动知道当前系统所用的分隔符
const path = require('path');
let res = path.join('路径','路径',......);
console.log(res);//path返回的是拼接的结果
大多数情况使用绝对路径,因为相对路径所相对的,不是当前文件的当前目录,而是命令行中的当前目录
使用__dirname:获取当前文件的绝对路径。再拼接上要调用的文件路径
注:require使用的就是当前文件的当前路径,因此可以直接写相对路径
3.第三方模块
3-1概述
由多个文件组成,放在一个文件夹中,称为包
两种存在方式:
- js文件形式。提供api接口
- 命令行工具形式,辅助项目开发
3-2如何获取
npmjs.com网站:第三方模块的存储和分发仓库,提供一个命令行的包管理工具:npm(node package manager)
下载:npm install 模块名(默认下载到的地方是命令行的当前目录下哦)
卸载:npm uninstall 模块名
全局安装与本地安装:一般来说
- 库文件:本地安装
- 命令行工具:全局安装
3-3常用模块
3-3-1 nodemon
命令行工具,每次修改文件都要重新再命令行执行,很繁琐
使用方法:
- npm install nodemon -g(-g:global全局安装)
- 用nodemon替代node来执行js文件
- 它会监控文件的保存操作,一旦文件改变并保存,会自动再次执行文件
- ctrl+c结束
注:无法运行脚本错误的解决办法:
- 管理员身份运行powershell
- 输入 set-ExecutionPolicy RemoteSigned
- 选择是(y)或者全是(a)
3-3-2 nrm
命令行工具,切换npm的下载地址的工具(npm registry manager)。网站在国外,速度慢,容易下载失败
比如阿里巴巴,每隔十分钟和国外网站同步一次
阿里:npm.taobao.org
国外:npmjs.com
使用步骤:
- npm install nrm -g
- nrm ls:查看可用的下载地址
- nrm use 地址
4.gulp
4-1 概述
前端构建工具,将机械化构建操作编写成任务,只需命令行任务就想能自动执行
4-2 gulp能做啥
- 项目上线,HTML、CSS、JS文件压缩合并
- 语法转换(es6、less …)
- 公共文件抽离
- 修改文件浏览器自动刷新
4-3 使用准备
- 使用npm install gulp下载gulp库文件
- 在项目根目录下建立gulpfile.js文件
- 重构项目的文件夹结构 src目录放置源代码文件 dist目录放置构建后文件
- 在gulpfile.js文件中编写任务.
- 在命令行工具中执行gulp任务
4-4 常用方法
4-4-1 列出
- gulp.src():获取任务要处理的文件
- gulp.dest():输出文件
- gulp.task():建立gulp任务
- gulp.watch():监控文件的变化
4-4-2 使用
首先写任务:gulpfile.js
const gulp = require('gulp');
//建立任务。参数:1:任务名称;2:任务毁回调函数(执行这个任务时要执行的函数)
gulp.task('first',()=>{
console.log('第一个gulp任务执行啦');
//把一个文件爱你复制到dist目录下
//1 获取这个文件
gulp.src('./src/css/base.css')
.pipe(gulp.dest('dist/css'));
//这里不能直接使用dest,而要先用pipe,这是硬性规定
});
然后下载gulp的一个命令行工具:gulp-cli(别忘了命令行工具全局安装)
命令行:gulp 任务名
4-5 插件
gulp属于轻量库,功能大多由插件实现
常用插件:
- gulp-htmlmin :html文件压缩
- gulp-csso :压缩css
- gulp-babel :JavaScript语法转化
- gulp-less: less语法转化
- gulp-uglify :压缩混淆JavaScript
- gulp-file-include 公共文件包含
- browsersync 浏览器实时同步
插件的使用:
- npm下载
- 在gulpfile.js中引入
- 然后调用即可
注:使用时只需记住插件名字,在官网查使用方法:https://www.npmjs.com/
4-5-1 文件压缩与公共文件包含
gulpfile.js
const gulp = require('gulp');
//引入插件htmlmin
const htmlmin = require('gulp-htmlmin');
//引入抽取插件
const fileinclude = require('gulp-file-include');
//建立任务。参数:1:任务名称;2:任务毁回调函数(执行这个任务时要执行的函数)
gulp.task('first',()=>{
console.log('第一个gulp任务执行啦');
//把一个文件爱你复制到dist目录下
//1 获取这个文件
gulp.src('./src/css/base.css')
.pipe(gulp.dest('dist/css'));
//这里不能直接使用dest,而要先用pipe,这是硬性规定
});
//html代码压缩,抽取公共代码
gulp.task('hmin',()=>{
gulp.src('./src/*.html')//通配符*的使用
.pipe(fileinclude())//抽取公共代码放到src/common目录下
//首先把两个html的公共代码部分复制到common/header.html中,并删除原来代码中移除的这一部分
//然后用一个语法来代替:@@include('./common/header.html')
// 然后后命令行运行这个任务就可以把这些代码替换掉引入语法啦
.pipe(htmlmin({ collapseWhitespace: true }))//是否压缩空格:是
.pipe(gulp.dest('dist'));
console.log('压缩完成');
});
其他案例详见资料
4-5-2 最终写一个default任务:
// 构建任务
gulp.task('default', ['htmlmin', 'cssmin', 'jsmin', 'copy']);
直接gulp不加任务名,默认会去找default任务,并且依次执行后面数组中的任务
5.package.json文件
5-1 概述
node-module文件夹存在两个问题:
- 文件多又碎,传输速度慢
- 模块依赖关系需要记录,确保版本匹配
package.json文件是项目描述文件,记录了当前项目信息,例如项目名称、版本、作者、github地址、当前项目依赖了哪些第三方模块等。使用npm init -y命令生成。(一般在项目根目录下,-y表示全部yes,全部执行默认值)
下载npm模块时会自动记录到这个文件中,下载多个模块用空格隔开
使用:npm install 不加任何模块名,会自动根据package.json自动下载依赖库
5-2 详解
5-2-1 两种依赖:
- 项目依赖:项目运行时用到的模块,比如jq,放在dependencies字段中
- 开发依赖:开发时要用的模块,但运行时不必要,比如gulp,放在devDependencies字段中,安装时加一个参数:–save-dev
运行在服务器端时不需要开发依赖的话,用 npm install --production
5-2-2 package-lock.json
记录模块与模块的依赖关系。它的作用:
- 锁定包的版本,确保再次下载时不会因为包版本不同而产生问题
- 加快下载速度,因为该文件中已经记录了项目所依赖第三方包的树状结构和包的下载地址,重新安装时只需下载即可,不需要做额外的工作
5-2-3 scripts字段:别名
记录那些常用的命令的别名
用法:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "nodemon a.js"
},
然后命令行:npm run build 即可运行别名中的 nodemon a.js
6.NodeJs中模块的加载机制
6-1 模块查找规则
-
当模块拥有路径但没有后缀时
require('./find.js'); require('./find');
-
require方法根据模块路径查找模块,如果是完整路径,直接引入模块。
-
如果模块后缀省略,先找同名JS文件再找同名JS文件夹
-
如果找到了同名文件夹,找文件夹中的index.js
-
如果文件夹中没有index.js就会去当前文件夹中的package.json文件中查找main选项中的入口文件
-
如果找指定的入口文件不存在或者没有指定入口文件就会报错,模块没有被找到
-
-
当模块没有路径且没有后缀时
require('find');
-
Node.js会假设它是系统模块
-
Node.js会去node_modules文件夹中
-
首先看是否有该名字的JS文件
-
再看是否有该名字的文件夹
-
如果是文件夹看里面是否有index.js
-
如果没有index.js查看该文件夹中的package.json中的main选项确定模块入口文件
-
否则找不到报错
-