T1:前端工程化概述、Node.js 基础
前端工程化 #2
面向前端工程开发的工具集,方便对代码压缩、特性兼容、同一格式化、预编译文件等问题的解决。
- 脚手架工具
- 专用:vue-cli、create-reacet-app、angular-cli、gatsby-cli
- 通用:Yeoman、Plop
- 自动化构建:npm scripts & script hooks、Grunt、Gulp、FIS
- 模块化打包:Webpack、Rollup、Parcel
- 标准化规范:ESLint、StyleLint、Prettier
- 自动化测试:Mocha、Jest、Enzyme、Cypress、Nightmare、Puppeteer
- 自动化部署:Git Hook、Lint-staged、CI/CD
Node.js 基础
Node.js 是一个基于 V8 引擎的 JavaScript 运行时。
类同浏览器,Node.js 为 JavaScript 提供了一个运行环境,建立在 node.js 上
Node.js APIs #5
浏览器里的 JavaScript 包括了 ECAMScript 和 Web APIs,Web APIs 则包括 DOM 和 BOM;
Node.js 下的 JavaScript 包括了 ECMAScript 和 Node APIs,Node APIs 则包括 fs、path、OS、HTTP等
Node.js 的运行 #7
在命令行中运行
-
脚本模式
在文件目录下,输入 node 和文件名,即执行该 js 文件。
-
交互模式
输入 node 回车进入
此模式下,类似于浏览器 console,可以直接输入代码执行
输入 .exit 退出
全局对象 #8
浏览器中的 JavaScript 的全局对象是 window,Node.js 中是 global
在交互模式下,声明的变量和函数都属于 global;在脚本模式下,声明的变量和函数都不属于 global
全局函数 #9
全局函数包括了 JavaScript 自身提供的方法和全局对象 global 下的方法。
global 下有 setTimeout、clearTimeout、setInterval、clearInterval,与浏览器端的 window 下用法相同。也有新增加的方法:
-
setImmediate 立即执行定时器
插入到事件队列的最前执行
与 process.netxTick 的区别:
process.nextTick 函数将在主程序的末尾执行,在事件列队之前。
-
clearImmediate 立即清除定时器
Node.js 内置模块
Node.js 有内置模块、自定义模块和第三方模块。
内置模块即 Node.js APIs,安装 Node.js 即可用。第三方模块需要在使用前自行选用安装。
console #11
process #12~13
process 是 global 的变量,因此它是全局的。使用 require() 引入不是必须的。
-
arch 当前操作系统架构
-
platform 当前系统平台信息
-
cwd() 当前文件所在目录,cwd
与
__dirname
指向的值相同__filename
则是当前文件的完整路径,包含了文件名 -
env 环境变量
自定义的环境变量在 env 下新定义变量即可
-
pid 进程编号
-
kill(pid) 结束该进程
path #14
path 必须由 require() 引入。const path = require('path');
获取当前文件所在目录
-
extname(url) 路径指向文件的扩展名
-
dirname(url) 路径指向文件的目录部分
-
basename(url) 路径指向文件的文件名(包括扩展名)
-
join() 拼接路径,并且自动补
/
e.g.1 实现返回上一层:
let fa = path.join(__dirname,'..');
e.g.2 获得同一目录下的其他文件的完整路径:
let another = path.join(__dirname,'another.js');
fs #15~17
File System 能够实现对文件操作和管理。
对文件的操作
-
清空写入 fs.writeFile(fileName, content, callback)
参数:
- fileName
- content:文件内容
- callback:回调,写入完成后调用
- err:错误
e.g.
fs.writeFile(__dirname+'/1.txt', 'Hello,node.js!', (err)=>{if (err) throw err;})
-
读取 fs.readFile(url, callback);
参数:
-
url
-
callback
-
err
-
data:读取到的文件二进制数据,默认以十六进制输出。
【常用】调用 toString 转换为字符串
-
-
-
删除 fs.unlink(url, callback);
-
追加写入 fs.appendFile(url, content, callback);
对目录操作
-
创建目录 fs.mkdir(url, callback)
-
删除目录 fs.rmdir(url, callback);
只能删除空目录
-
重命名目录 fs.rename();
-
读取目录 fs.readdir()
查看文件信息
- fs.stat()
- isDirectory()
- isFile()
fs 中的同步和异步
除了上面讲的方法,另外还有加 Sync 后缀的方法,表示同步执行
一般情况下,多使用异步。强调先后顺序的命令使用同步方法,比如
【案例】文件的复制和压缩 #18
文件流 #19
读取流通过管道到写入流
-
创建一个读取流 createReadStream()
创建的实例可以调用 pipe() 联通写入流,写入流作为实参。
-
创建一个写入流 createWriteStream()
HTTP #20
HTTP 可以发布 Web 服务。
使用前需要使用 require 引入。
-
创建一个服务 http.createserver(func)
参数:一个函数
-
req:request 请求
- setHeader
- end
-
res:response 响应
-
-
发布服务 server.listen()
自定义模块
Node.js 中每个单独的 .js 文件,就是一个模块。模块内是定义的属性和方法。
每个模块中都有一个 module 变量,其代表当前模块。
module 的 exports 属性是对外的接口,其值为一个对象。module.exports 对象内的的属性或方法是被导出的,能被外部调用,未导出的内容是模块私有,不能被外部访问
使用时,通过 require 引入。
模块的组织和加载逻辑
模块文件的组织有两种,单个的文件模块和多个文件组成的目录模块。
模块的引入形式也有两种,以路径开头和不以路径开头。
第三方模块(npm)
第三方模块由 npm 维护,主要介绍 npm 的使用。
npm 换源
npm config set registry https://registry.npm.taobao.org
全局安装
npm i packageName -g
注:-g
= -global
全局安装后,可以直接以 packageName 调用包
局部安装(仅供某个项目使用)
-
在项目文件夹下初始化项目:
npm init
问答交互式配置 npm 项目,生成 package.json。也可以加
--yes
或-y
以默认值作配置 -
初始化完成后,可以进行安装,需要加命令行参数:
-
--save
/-S
:模块包会放在 dependencies 下。开发和运行都需要的模块,例如 jQuery -
--save-dev
/-D
:模块包会放在 devDependencies 下。只在开发环境下依赖的模块工具,开发完成后上线运行不再需要,例如压缩模块。
-
-
安装后,需要选中包的具体路径位置调用,默认在项目文件夹下的
.\node_modules\.bin\packageName
T2:脚手架工具:Yeoman
脚手架工具辅助开发,帮助快速创建项目基础、提供项目规范和约定,实现代码复用。
通用脚手架:yeoman
专用脚手架:vue-cli、create-react-app、angular-cli(它们又不止于脚手架)
Yeoman
命令行工具 yo
通过 yo 管理和调用生成器来生成不同的项目
- 官网 搜寻需要的 generator
- 安装生成器:
npm i -g generatorName
- 创建项目:在目标项目文件夹下
yo generatorName
- 运行项目:项目文件夹下
npm run start
T3:自动化构建
构建:将源代码转换成生产代码。
构建的需要有以下几种:
- 代码需要编译或处理兼容( LESS → CSS,ES6+ → ES5)
- 代码需要压缩( CSS,JS,HTML,图片等 ),节省带宽,提高加载速度
- 代码需要做格式化校验,统一代码风格。
通过不同功能的 npm 模块来实现我们想要的构建。
自动化构建的实现:npm scripts
npm 允许在 package.json
文件里面,使用 scripts
字段定义脚本命令。例如:
{
"scripts": {
"foo": "node bar.js"
}
}
scripts
字段是一个对象。它的每一个属性,对应一段命令脚本。可以直接以 npm 调用 scripts
的属性,即等同于在命令行中执行了对应的命令。例如:npm run foo
.
执行方式
一段 npm scripts 当中可能需要执行多个任务,需要明确它们的执行顺序。
-
并行执行 parallel
任务1**&** 任务2
-
串行执行 series
任务1 && 任务2
Windows 下无效,需要 npm-run-all 插件
插件添加了
-p
-s
命令行参数,分别对应并行和串行模式,在 run 时使用。
构建案例和相关包的使用
构建样式文件
-
less 转 css(less 插件)
lessc
-
css 格式检测(StyleLint 插件)
-
配置:
在项目文件夹下,先初始化:
eslint --init
可以通过问答交互自动生成配置文件.eslintrc.json
配置文件下的 rules 可以修改为需要规范的样式,比如缩进、单双引号
-
使用:
- 单个文件:eslint path/filename.js
- 整个目录:eslint path/dirname
会根据 rules 提示警告或错误
-
-
压缩 css(minify 插件)
构建脚本文件
-
ES6+ 转 ES5(Babel 插件)
-
安装:
Babel 有多种转码规则,本例需要的、也是最常用的:babel-preset-env
使用前需安装转码规则:
npm i babel-preset-env -D
-
配置:在项目根目录对 Babel 进行配置
.babelrc
-
使用:
-
单个文件
babel input.js -o output.js
-o
=--out-file
-
整个文件夹
babel src -d dist
-d
=--out-dir
-
-
-
js 格式检测(ESLint 插件)
-
安装:
需要安装标准:
npm i -g stylelint-config-standard
-
配置:在项目根目录手动创建配置文件
.stylelintrc.json
-
使用:
- 单个文件:
stylelint path/filename.css
- 整个项目:
stylelint **/*.css
- 单个文件:
-
-
压缩 js(minify 插件)同上
T4:自动化构建工具:Gulp
借助工具可以实现更进一步的自动化构建,比如:Grunt、Gulp、FIS,其中以 Gulp 最为流行。
Gulp 的安装、使用
-
全局安装 gulp 客户端
npm install -g gulp-cli
-
初始化项目
npm init --yes
-
安装 gulp 包
npm install gulp -D
-
项目根目录新建
gulpfile.js
文件 -
在
gulpfile.js
中,创建 gulp 任务-
任务变量声明
-
新:定义函数常量
所有的任务都是异步的,因此需要在参数中传入回调函数
-
旧语法:
gulp.task( 'taskName', func() )
-
-
任务导出:module.exports
exports 的 default 属性可以直接以
gulp
命令调用
-
-
执行 gulp 任务
gulp taskName
Gulp 中的组合任务 #2
与 npm scripts 相似,Gulp 也有区分串行和并行的方法
- 串行:
series(t1,t2,t3)
- 并行:
parallel(t1,t2,t3)
二者可以相互、多层嵌套来实现更复杂的执行顺序
文件操作 #3
Gulp 中的文件操作是基于流的
-
读取流/源:src()
参数:
- 源文件*,URL字符串
- 配置,对象
- base:保留该位置下的目录结构,url字符串
-
写入流/目标:dest()
-
管道:pipe()
e.g.
const { src, dest } = require('gulp');
exports.default = () => {
return src('src/styles/main.less', { base: 'src' }).pipe(dest('dist'))
}
【案例】使用 Gulp 和相关插件实现的自动化构建
构建 CSS 样式文件 #4
使用服务 gulp 的三个插件:gulp-less、gulp-clean-css、gulp-rename,来一步完成 less 文件转 css 文件,并压缩、重命名。
- 在
gulpfile.js
添加插件的依赖 - 新建任务,在源和目的之间,利用管道
pipe()
调用插件。每次调用都需要一个管道,可以连续调用。 - 导出任务
CSS hack 插件:autoprefixer #5
使用 gulp-autoprefixer 插件来完成 CSS 针对不同浏览器的前缀,它的数据来源于 caniuse.com
它的处理顺序应放在转换之后、压缩之前。
构建 JS 脚本文件 #6
使用插件 gulp-babel、gulp-uglify、gulp-rename 来实现对 js 文件降低版本、压缩、重命名。
gulp-babel 的调用时,是将转换规则写在配置对象中作为参数传入:
- 旧版本:
{ presets: ['@babel/env'] }
- 新版本:
{ presets: [babel/presets/env] }
构建 HTML 页面文件 #7
压缩:gulp-htmlmin
gulp-htmlmin 的参数为一个配置对象,例如:{ collapse: true, minifyCSS: true, minifyJS: true}
压缩 HTML 空白和行内样式、脚本。
构建图片文件 #8
gulp-imagemin
文件清除 #9
需求:构建前清除多余文件
del
【综合】
将上述的各项构建操作综合为一个任务:
series(clean, parallel(style, script, html, img))
先清空目标文件夹,然后并行执行 HTML、CSS、JS、图片文件的构建。
开发服务器 #10
browser-sync