前端工程化概述
- 工程的概念
工程就是项目。工程的整个生命周期可分为以下几个部分:
- 工程化
工程化就是完成项目过程中,用到的各种工具和技术。
- 前端工程化
前端工程化就是通过各种工具和技术,提升前端开发效率的过程。 前端工程化的内容:各种工具和技术。
前端工程化的内容
技术是为解决问题而存在的。
- 前端代码压缩是为了节约带宽,网页加载更快;
- 想要用ES6+和CSS3需要解决兼容性问题,兼容性问题可以在caniuse.com上查找到;
- 代码规范是为了解决代码风格无法统一的问题;
等等。 工程化≠某个工具,工具和技术只是工程化落地的手段。不过我们还是需要学习相关的工具和技术,先从前端工程化的基础node.js学起。
node.js基础
node.js官网:nodejs.org “Node.js®是基于Chrome的V8 JavaScript引擎构建的JavaScript运行时。”,运行时的英文是runtime,运行环境。
node.js不是新的编程语言,也不是JavaScript框架,而是JavaScript的一个运行环境。
node.js功能
和浏览器中的JavaScript主要负责前端功能不同,node.js中的JavaScript主要负责后端功能。
浏览器端的JavaScript:
- 响应浏览器事件
- 数据验证
- DOM操作
- 不能做文件操作
Node端的JavaScript:
- Node.js适合开发服务器端的应用层(BFF)
- 为网站、APP、小程序等提供数据服务
- Node.js适合用于开发前端方向的各种工具
- 各种前端工程化的工具
- Node.js可以用来做桌面应用开发,各种跨平台的桌面应用,比如vscode,typora,insomnia等
Node.js给JavaScript插上了全栈编程的翅膀。
node.js API
node.js API是在ES的语法基础上实现了和操作系统的交互。
node.js安装
- 在官网下载Node.js安装包
一般选择首页推荐的LTS版本就行了,这里我们手动选择download,
找到历史版本,
找到12.19.0版本,download
2. 双击安装包,一路next安装
3. 命令行输入node -v
验证安装是否成功
node.js使用
Node.js下运行JavaScript
- 脚本模式
命令行输入node .\hello.js
表示运行当前目录的hello.js文件 - 交互模式
命令行输入node回车进入交互模式,在交互模式下- 使用tab键自动补全
- 探索JavaScript对象(例如:Math.然后按两次tab键)
- 点命令(例如:输入.help然后回车)
node.js下的全局对象是global
在交互模式下,声明的变量和函数都属于global。例如var a = 1; global.a可以获取到a的值。
在脚本模式下,声明的变量和函数都不属于global。
无论哪个模式,属于DOM和BOM的部分是无法访问到的。比如window、ducument。
node.js下的全局对象
- JavaScript语言提供的全局函数,在Node.js下依然可用
- parseInt/parseFloat/isNaN/isFinite/eval..
- 一次性定时器(setTimeout/clearTimeout)
- 周期性定时器(setInterval/clearlnterval)
- Node.js环境也提供了一些全局函数
- 立即执行定时器(setImmediate/clearImmediate)
- 进程立即执行定时器(process.nextTick)
执行顺序是:主进程→nextTick→事件队列(setImmediate)→事件队列(setTimeout,setInterval)
node.js模块
- 内置模块:在nodejs.cn/api/ 有中文说明文档,也可以进入nodejs.org/en/docs/ 官网文档中查看
- 自定义模块
- 第三方模块:社区维护的,需要单独下载才能使用,比如Less,Babel,Express...在集中管理平台www.npmjs.com/ 都有说明。
内置模块console
在中文文档和官方文档中都可找到相关用法: 我们只列举常用的几个。
// 不同类型的数据,输出后颜色不同
console.log('1');
console.log(1);
var obj = { name: 'Tom', age: 19 }
console.log(obj)
console.table(obj) // 以表格方式展示数据
console.time('for');//开始计时
for (var i = 1; i <= 100000; i++) {
}
console.timeEnd('for');//结束计时
console.time('while');
var i = 1;
while (i <= 100000) {
i++;
}
console.timeEnd('while');
内置模块process
process 对象是一个全局变量,提供了有关当前 Node.js 进程的信息并对其进行控制。作为全局变量,它始终可供 Node.js 应用程序使用,无需使用 require()
。 它也可以使用 require()
显式地访问:
// process 是全局变量,可以不写 require 引入
const process = require('process');
// 获取操作系统架构 x64
console.log(process.arch)
// 当前系统平台信息 win32
console.log(process.platform)
// 获取当前文件所在的目录
console.log(process.cwd())
// 环境变量
console.log(process.env)
// 自定义环境变量
process.env.NODE_ENV = 'develop'// 标识是线上环境还是开发环境
console.log(process.env)
// 获取进程的编号
console.log(process.pid)
// 杀死进程
process.kill(进程编号)
内置模块path
path 模块负责文件路径的,使用之前必须使用require关键字引入。
- ./ 表示当前目录
- ../ 表示上一级目录
- __dirname 返回当前文件所在的目录
- __filename 返回当前文件的完整路径(目录+文件)
// path使用之前必须使用require关键字引入
const path = require('path');
// __dirname 获取当前文件所在的目录
console.log(__dirname);
// __filename 获取当前文件的完整路径
console.log(__filename);
// path.join()用于拼接多个路径部分,并转化为正常格式
const temp = path.join(__dirname, '..', 'lyrics', './友谊之光.lrc');
console.log(temp);
console.log('获取路径中的文件名');
console.log(path.basename(temp));
console.log('获取一个路径中的目录部分');
console.log(path.dirname(temp));
console.log('获取一个路径中最后的扩展名');
console.log(path.extname(temp));
内置模块fs
fs (file system)模块主要负责文件基本操作。使用之前必须使用require关键字引入。
- 文件基本操作
// 使用 fs 之前先引入
const fs = require('fs')
// 写文件 (清空写入:写入之前会先将文件清空)
// fs.writeFile('文件路径','写入内容',回调函数)
fs.writeFile('./1.txt', '曾经有一首歌,她感动了我', (err) => {
if (err) throw err
console.log('写入成功')
})
// 读文件
// fs.readFile('文件路径', 回调函数)
fs.readFile('./1.txt', (err, data) => {
if (err) throw err
// data 是二进制数据,默认输出时,以十六进制的方式展示
// 想要看到正常的效果,需要通过 toString() 转换
console.log(data.toString())
})
// 删除文件
// fs.unlink('文件路径', 回调函数)
fs.unlink(__dirname+'/1.txt', (err) => {
if (err) throw err
console.log('删除成功')
})
// 追加写入(多次执行,文件中会有多条数据)
// fs.appendFile('文件路径','写入内容',回调函数)
fs.appendFile(__dirname+'/2.txt', '曾经有一首歌,她是这样唱的\n', (err) => {
if (err) throw err
console.log('追加写入成功')
})
- 目录基本操作
const fs = require('fs')
// 创建目录
fs.mkdir('./d1', (err) => {
if (err) throw err
console.log('创建成功')
})
// 删除目录,只能删除空目录
fs.rmdir('./d1', (err) => {
if (err) throw err
console.log('删除成功')
})
// 重命名目录
// fs.rename(旧名称, 新名称, 回调函数)
fs.rename(__dirname+'/d1', __dirname+'/d2', (err) => {
if (err) throw err
console.log('重命名成功')
})
// 读取目录的内容
fs.readdir(__dirname, (err, data) => {
if (err) throw err
// console.log(data) // data 是数组
data.map((d) => {
console.log(d)
})
})
// 判断文件是否存在
if (!fs.existsSync('./d2')) {
fs.mkdirSync('./d2')
}
- fs.stat 查看状态
// 查看文件信息
fs.stat(__dirname+"/a.txt", (err, stat) => {
if (err) throw err
if (stat.isDirectory()) {
// 判断当前文件是否是目录
console.log('目录:', d)
} else if (stat.isFile()) {
// 判断当前文件是否是普通文件
console.log('文件:', d)
}
})
- 同步函数(synchronization)
- 同步函数:在主程序中,自上而下运行
- 异步函数:通过回调函数在事件队列中运行
const fs = require('fs')
// 先判断文件是否存在
// 然后,如果文件存在的化,再执行删除
if (fs.existsSync(__dirname+"/1.txt")) {
fs.unlinkSync(__dirname+"/1.txt")
} else {
console.log('文件不存在')
}
- 文件流
文件流相比文件缓冲方式操作文件优点:
- 内存效率提高: 无需加载大量数据,流把大数据切成小块,占用内存更少
- 时间效率提高: 接获数据后立即开始处理,无需等到内存缓冲填满
const fs = require('fs')
// 1. 创建读取流
var readStream = fs.createReadStream('./file2.txt')
// 2. 创建写入流
var writeStream = fs.createWriteStream('./file_stream.txt')
// 3. 把读取流通过管道传给写入流
readStream.pipe(writeStream)
内置模块http
http可以发布web服务,需要通过require()引用。
const http = require('http')
// 1. 创建服务器
/**
* req = request 请求
* res = response 响应
*/
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('你好:Node.js')
})
// 2. 发布 web 服务
const port = 3000
const host = 'localhost'
// 在浏览器中访问 http://localhost:3000 然后能看到效果
server.listen(port, host, () => {
console.log(`服务器运行在 http://${host}:${port}`)
})
自定义模块
- Node.js中每个单独的文件,就是一个模块
- 每个模块中都有一个module变量,其代表当前模块
- module的exports属性是对外的接口。
- 使用时使用require()引用
只有导出(module.exports)的属性或方法才能被外部调用,未导出的模块是内部私有的,不能被外部访问。
创建自定义模块:
// circle.js 我们声明一个模块 circle,模块中有两个方法,分别求圆的面积和周长。
const PI = 3.14
// 圆的周长
const perimeter = (r) => {
return 2 * PI * r
}
// 圆的面积
function area (r) {
return PI * Math.pow(r, 2)
}
// 模块内容导出后,才能被外部调用
module.exports = {
perimeter,
area
}
外部使用模块:
// 在 app.js 中引入模块
// 引入模块时,需要写引入路径,否则 require('circle') 会报错
const circle = require('./circle')
// 调用模块中的属性或方法
const r = 10
const p = circle.perimeter(r)
const a = circle.area(r)
console.log(`直径为 ${r} 的圆的周长是:` + p)
console.log(`直径为 ${r} 的圆的面积是:` + a)
模块的加载逻辑
这里我们可以根据文件的组织方式,将模块分成文件模块和目录模块。 不同类型的模块,引入方式不同,其加载逻辑也不相同,一共有四种情况:
- 以路径开头的文件模块
- 不以路径开头的文件模块
- 以路径开头的目录模块
- 不以路径开头的目录模块
这里,我们将以上四种情况的加载逻辑整理成下表:
第三方模块
第三方模块是由社区维护的模块,想要使用第三方模块需要单独安装。前端工程化的大部分工具都是第三方工具。
第三方工具集中管理网站:www.npmjs.com/
以bootstrap为例:
我们可以在上面看到关于bootstrap的各种信息。
npm概述
我们知道了第三方模块,以及它们的集中管理平台,我们要如何安装呢?这时候就需要用到npm了。
npm(Node Package Manager)是Node.js的包管理工具,跟随Node.js一起安装的,同时也是一个命令。
在命令行中输入npm相应命令就可以进行包及其依赖的安装操作。
npm 命令下载包的资源地址,称为 npm 的镜像源。
默认 npm 的镜像源是国外的(npmjs.com),下载速度慢,为了提高下载速度,可以将 npm 的镜像源设置为国内的地址(例如:淘宝镜像源)
设置命令为:
// 修改npm的镜像源
npm config set registry https://registry.npm.taobao.org
// 验证是否更改成功(查看镜像源):
npm config get registry
使用npm安装包
npm安装包分为全局安装和项目安装。
-
全局安装:
npm install 包名称 --global
(或 简写为npm i 包名称 -g
)
全局卸载:npm uninstall 包名称 --global
(或 简写为npm uninstall 包名称 -g
) -
项目安装,分为四步:
-
创建项目目录(mkdir project)
-
进入项目目录(cd project)
-
初始化项目(npm init)
-
在项目中安装包: 项目中安装的包,默认存在 当前项目/node_modules 目录下
安装包时,涉及到两个重要的参数:
-
npm install --save
- 安装好后,包的信息会写入 package.json 的 dependencies 中;
- dependencies 中的包,在开发和生产环境都使用,例如:jQuery。
-
npm install --save-dev
- 安装好后,包的信息会写入 package.json 的 devDependencies 中
- devDependencies 中的包只用于开发环境,生产环境不需要。例如 minify,项目上线后,就不需要压缩文件了。
-
配置项 命令 描述 devDependencies --save-dev 简写 -D 开发环境,管理的依赖包仅在开发阶段有效 dependencies --save 简写 -S 生产环境,管理的依赖包在项目上线后依然有效 -
# --save(-S) 安装好后写入 package.json 的 dependencies 中;
# dependencies 依赖的包不仅开发环境能使用,生产环境也能使用,例如 jQuery 开发和线上环境都需要
npm install jquery --save
# 或
npm i jquery -S
# --save-dev(-D) 安装好后写入 package.json 的 devDependencies 中;
# devDependencies是只会在开发环境下依赖的模块,例如 minify 只需要开发环境使用,上线后就不需要了
npm install minify --save-dev
# 或
npm i minify -D
包在命令行中的使用方法:
如果包安装在当前项目中(局部安装),则命令的执行路径是当前项目下的 .\node_modules\.bin 目录下。
如果包是全局安装,则命令执行的路径也是全局的
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!