前端工程化
- 前端工程化就是通過各種工具和拘束,提升前端開發(fā)效率的過程。
NOde.js
- 官方網(wǎng)址:nodejs.org/
瀏覽器內(nèi)核的組成部分
- 渲染引擎:用來做內(nèi)容渲染,比如html、css渲染。
- js引擎:渲染JavaScript
node.js的作用
- Node.js適合開發(fā)服務(wù)器端的應(yīng)用層(BFF)
- 為網(wǎng)站,APP,小程序等提供數(shù)據(jù)服務(wù)
- Node.js適合用于開發(fā)前端方向的各種工具
- 各種前端工程化的工具
- Node.js可以用來做桌面應(yīng)用開發(fā)
- 各種跨平臺的桌面應(yīng)用開發(fā)
全局對象
Node.js下的全局對象是global。
- 在
交互模式下,聲明的變量和函數(shù)都屬于global。- 例如:var a = 1; global.a可以放文到 a 的值。
- 在
腳本模式下,聲明的變量和函數(shù)都不屬于global。- 例如:var a = 1; global.a訪問不到a的值。
全局函數(shù)
- JavaScript語言提供的全局函數(shù),在Node.hs下依然可用。
setImmediate()
- 表示立即執(zhí)行事件,參數(shù)是一個(gè)函數(shù),表示執(zhí)行事件的函數(shù)。
- setImmediate()是在隊(duì)列事件中執(zhí)行,與setTimeout()等函數(shù)都是在事件隊(duì)列中執(zhí)行,相當(dāng)于異步執(zhí)行。
- 當(dāng)主線程執(zhí)行完之后,才會(huì)執(zhí)行任務(wù)隊(duì)列中的任務(wù)。
setImmediate()與process.nextTick()的區(qū)別
- setImmediate()是存在于任務(wù)隊(duì)列中,并且是任務(wù)隊(duì)列中有限執(zhí)行的事件。
- process.nextTick()是存在于主進(jìn)程中,并且在主進(jìn)程中是最后執(zhí)行的。
- 任務(wù)隊(duì)列中的任務(wù)需要等主進(jìn)程中的任務(wù)執(zhí)行結(jié)束后才會(huì)執(zhí)行,也就是說理論上需要等process.nextTick()執(zhí)行完成之后才會(huì)執(zhí)行setImmediate()事件任務(wù)。
Node.js模塊
模塊是Node.js應(yīng)用程序的基本組成部分,大部分前端工程化的工具,是以模塊的形式存在的。
Node.js中的模塊可以劃分為內(nèi)置模塊、自定義模塊、第三方模塊三類。
內(nèi)置模塊是官方提供的,跟隨Node.js一起安裝。
自定義模塊是自己定義的模塊。
第三方模塊社區(qū)維護(hù)的,需要單獨(dú)下載才能使用。(https://www.npmjs.com/)
內(nèi)置模塊
內(nèi)置模塊-process
- process 對象是一個(gè)全局變量,提供了有關(guān)當(dāng)前 Node.js 進(jìn)程的信息并對其進(jìn)行控制。 作為全局變量,它始終可供 Node.js 應(yīng)用程序使用,無需使用 require()。 它也可以使用 require() 顯式地訪問:
const process = require('process');
- 獲取操作系統(tǒng):process.arch
- 獲取操作系統(tǒng)平臺:process.platform
- 獲取當(dāng)前工作目錄:process.cwd()
- 獲取環(huán)境變量:process.env
- 自定義環(huán)境變量:process.env.NODE_ENV = "develop"
- 獲取進(jìn)程編號:process.pid
- 殺死進(jìn)程:process.kill("進(jìn)程編號")
內(nèi)置模塊-path
- 在使用之前,需要通過require引入
const path = require("path")
- 獲取當(dāng)前文件所在的路徑:console.log(
__dirname) - 獲取當(dāng)前文件的完整路徑:console.log(
__filename) - 獲取文件的擴(kuò)展名:path.extname(
__filename) - 獲取路徑中的目錄部分:path.dirname(
__filename) - 獲取路徑中的文件名:path.basename(
__filename) - 合并路徑:path.join("", "")
內(nèi)置模塊-fs
- fs提供了文件操作的API。
- 文件操作
- 目錄操作
- 使用之前,需要通過require引入。
寫入文件 writeFile()
寫入文件 writeFile(),清空寫入
- 語法:fs.writeFile(file, data[, options], callback)
- 參數(shù)說明:
- file <string> | <Buffer> | <URL> | <integer> 文件名或文件描述符。
- data <string> | <Buffer> | <TypedArray> | <DataView> 寫入內(nèi)容。
- options <Object> | <string>
- encoding <string> | <null> 默認(rèn)值: 'utf8'。
- mode <integer> 默認(rèn)值: 0o666。
- flag <string> 參見文件系統(tǒng) flag 的支持。 默認(rèn)值: 'w'。
- callback <Function> 回調(diào)函數(shù)。
- err <Error>
- 示例:
const fs = require("fs");
const path = require("path");
// 構(gòu)造文件路徑
let fileName = path.join(__dirname, "1.txt");
// 寫入文件
fs.writeFile(fileName, "寫入內(nèi)容", { flag: "a+" }, (err) => {
// 如果有異常,則拋出異常
if (err) throw err;
console.log("寫入成功");
});
- 如果 options 是字符串,則它指定字符編碼
fs.writeFile('文件.txt', 'Node.js 中文網(wǎng)', 'utf8', callback);
追加的方式寫入文件 appendFile()
以追加的方式寫入文件
- path <string> | <Buffer> | <URL> | <number> 文件名或文件描述符。
- data <string> | <Buffer>
- options <Object> | <string>
- encoding <string> | <null> 默認(rèn)值: 'utf8'。
- mode <integer> 默認(rèn)值: 0o666。
- flag <string> 參見文件系統(tǒng) flag 的支持。默認(rèn)值: 'a'。
- callback <Function>
- err <Error>
如果文件不存在,則創(chuàng)建文件
- err <Error>
fs.appendFile('文件.txt', '追加的數(shù)據(jù)', (err) => {
if (err) throw err;
console.log('數(shù)據(jù)已被追加到文件');
});
如果 options 是字符串,則它指定字符編碼:
fs.appendFile('文件.txt', '追加的數(shù)據(jù)', 'utf8', callback);
讀取文件 readFile()
- 語法:fs.readFile()path[, options], callback
- 參數(shù)說明:
- path <string> | <Buffer> | <URL> | <integer> 文件名或文件描述符。
- options <Object> | <string>
- encoding <string> | <null> 默認(rèn)值: null。
- flag <string> 參見文件系統(tǒng) flag 的支持。默認(rèn)值: 'r'。
- callback <Function>
- err <Error>
- data <string> | <Buffer>
- 示例:
fs.readFile(fileName, "utf8", (err, data) => {
if (err) throw err;
console.log(data);
});
- 如果不寫"utf8",返回的data是一個(gè)二進(jìn)制數(shù)據(jù),是以十六進(jìn)制展示,如果想正常展示,需要使用
tostring()方法。 - fs.readFile() 函數(shù)會(huì)緩沖整個(gè)文件。 若要最小化內(nèi)存成本,則盡可能選擇流式(使用 fs.createReadStream())。
刪除文件 unlink()
刪除文件
- path <string> | <Buffer> | <URL>
- callback <Function>
- err <Error>
const fs = require("fs");
const path = require("path");
let fileName = __dirname;
fs.unlink(path.join(fileName, "err.txt"), (err) => {
if (err) throw err;
console.log("刪除文件成功");
});
創(chuàng)建目錄 mkdir()
創(chuàng)建目錄:
fs.mkdir(path[, options], callback)
參數(shù):path <string> | <Buffer> | <URL>
-
options <Object> | <integer>
- recursive <boolean> 默認(rèn)值: false。
- mode <string> | <integer> 在 Windows 上不支持。默認(rèn)值: 0o777。
-
callback <Function>
- err <Error>
// 創(chuàng)建 `/目錄1/目錄2/目錄3`,不管 `/目錄1` 和 `/目錄1/目錄2` 是否存在。
fs.mkdir('/目錄1/目錄2/目錄3', (err) => {
if (err) throw err;
});
midirSync()
同步創(chuàng)建文件:
fs.mkdirSync(path[, options])
參數(shù):path <string> | <Buffer> | <URL>
-
options <Object> | <integer>
- recursive <boolean> 默認(rèn)值: false。
- mode <string> | <integer> 在 Windows 上不支持。默認(rèn)值: 0o777。
刪除目錄 rmdir()
注意:rmdir只能刪除空目錄
語法:
fs.rmdir(path[, options], callback)
參數(shù):path <string> | <Buffer> | <URL>
-
options <Object>
- maxRetries <integer> 如果遇到 EBUSY、 EMFILE、 ENFILE、 ENOTEMPTY 或 EPERM 錯(cuò)誤,則 Node.js 會(huì)重試該操作(每次嘗試時(shí)使用 retryDelay 毫秒時(shí)長的線性回退等待)。 此選項(xiàng)表示重試的次數(shù)。 如果 recursive 選項(xiàng)不為 true,則此選項(xiàng)會(huì)被忽略。 默認(rèn)值: 0。
- recursive <boolean> 如果為 true,則執(zhí)行遞歸的目錄刪除。 在遞歸模式中,錯(cuò)誤不會(huì)被報(bào)告(如果 path 不存在),并且操作會(huì)被重試(當(dāng)失敗時(shí))。 默認(rèn)值: false。
- retryDelay <integer> 重試之間等待的時(shí)間(以毫秒為單位)。 如果 recursive 選項(xiàng)不為 true,則此選項(xiàng)會(huì)被忽略。 默認(rèn)值: 100。
-
callback <Function>
- err <Error>
文件重命名 rename()
異步地把 oldPath 文件重命名為 newPath 提供的路徑名。 如果 newPath 已存在,則覆蓋它。 除了可能的異常,完成回調(diào)沒有其他參數(shù)。
語法:
- fs.rename(oldPath, newPath, callback)
參數(shù):
- oldPath <string> | <Buffer> | <URL>
- newPath <string> | <Buffer> | <URL>
- callback <Function>
- err <Error>
fs.rename('舊文件.txt', '新文件.txt', (err) => {
if (err) throw err;
console.log('重命名完成');
});
讀目錄 readdir()
讀取目錄,返回一個(gè)數(shù)組,數(shù)組中保存當(dāng)前目錄下的文件/文件夾名稱。
語法:
- fs.readdir(path[, options], callback)
參數(shù):
- path <string> | <Buffer> | <URL>
- options <string> | <Object>
- encoding <string> 默認(rèn)值: 'utf8'。
- withFileTypes <boolean> 默認(rèn)值: false。
- callback <Function>
- err <Error>
- files <string[]> | <Buffer[]> | <fs.Dirent[]>
讀取目錄的內(nèi)容。 回調(diào)有兩個(gè)參數(shù) (err, files),其中 files 是目錄中文件的名稱的數(shù)組(不包括 '.' 和 '..')。
可選的 options 參數(shù)可以是字符串(指定字符編碼)、或具有 encoding 屬性(指定用于傳給回調(diào)的文件名的字符編碼)的對象。 如果 encoding 被設(shè)置為 'buffer',則返回的文件名會(huì)作為 Buffer 對象傳入。
如果 options.withFileTypes 被設(shè)置為 true,則 files 數(shù)組會(huì)包含 fs.Dirent 對象。
判斷當(dāng)前文件是否是目錄 stat()
語法:
- fs.stat(path[, options], callback)
參數(shù):
- path <string> | <Buffer> | <URL>
- options <Object>
- bigint <boolean> 返回的 fs.Stats 對象中的數(shù)值是否為 bigint 型。 默認(rèn)值: false。
- callback <Function>
- err <Error>
- stats <fs.Stats>
回調(diào)有兩個(gè)參數(shù) (err, stats),其中 stats 是 fs.Stats 對象。
若要只檢查文件是否存在,但沒有更多的操作,則建議使用 fs.access()。
.isDirectory() // 是否是目錄
.isFile() // 是否是普通文件
路徑是否存在 existsSync()
用于檢查文件路徑是否存在:
- fs.existsSync(path)
參數(shù):
- path <string> | <Buffer> | <URL>
- 返回: <boolean>
if (fs.existsSync('文件')) {
console.log('該路徑已存在');
}
文件流
文件操作可以是緩沖的方式,也可以是文件流的方式,緩沖的方式就是比如在寫入文件的時(shí)候,首選讀取源文件,然后將源文件讀取到內(nèi)存緩沖中,當(dāng)緩存中的文件溢出的時(shí)候,在將內(nèi)容寫入到新的文件中,上述的文件寫入方式就是通過緩沖方式實(shí)現(xiàn)。
文件流表示將讀取的文件和寫入的文件通過一個(gè)管道連接,直接將要讀取的文件內(nèi)容寫入到新的文件中。
特點(diǎn):
- 內(nèi)存效率提高
- 無需加載大量數(shù)據(jù)。
- 流把大數(shù)據(jù)切成小塊,占用內(nèi)存更少。
- 時(shí)間效率提高
- 獲取數(shù)據(jù)后立即開始處理。
- 無需等到內(nèi)存緩沖填滿。
// 1.創(chuàng)建讀取流
const readStream = fs.createReadStream("文件路徑");
// 2.創(chuàng)建寫入流
const writeStream = fs.createWriteStream("文件路徑");
// 3.把讀取流通過管道傳給讀取流
readStream.pipe(writeStream)
內(nèi)置模塊-http
const http = require("http");
// 創(chuàng)建服務(wù)
// req = request 請求
// res = response 響應(yīng)
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/plain; charset=utf-8");
res.end("你好");
});
// 發(fā)布web服務(wù)
const port = 1234;
const host = "localhost";
server.listen(port, host, () => {
console.log(`服務(wù)器運(yùn)行在:http://${host}:${port}`);
});
自定義模塊
- Node.js中每個(gè)單獨(dú)的
.js文件,就是一個(gè)模塊。 - 每個(gè)模塊中都有一個(gè)
module變量,其代表當(dāng)前模塊。 -
module中的exports屬性時(shí)對外的接口。- 只有導(dǎo)出(module.exports)的屬性或方法才能被外部調(diào)用
- 未導(dǎo)出的內(nèi)容是模塊私有,不能被外部訪問。
- 使用時(shí)需要用
require引入。引入的時(shí)候需要將完整的路徑寫入??梢允÷院竺娴?code>.js
// modules.js
function info() {
return "自定義模塊";
}
module.exports = {
info,
};
// app.js
const info = require("./modules");
console.log(info.info());
模塊的加載邏輯
以路徑開頭引入:
-
文件模式:
- 可以直接通過
require("文件路徑")引入,后綴名可以省略不寫。
- 可以直接通過
-
目錄模塊:
- 通過
require("目錄路徑"),然后引入入口文件。 - 默認(rèn)入口文件是
index.js,在目錄路徑中直接寫入路徑的時(shí)候,默認(rèn)在這個(gè)目錄下尋找index.js這個(gè)文件。 - 如果沒有
index.js這個(gè)文件,可以在目錄下創(chuàng)建一個(gè)package.json文件,在文件中通過main屬性指定入口文件。 - package.json是目錄模塊中的掃描文件。
- 通過
// package.json
{
"main": "modules.json"
}
不以路徑開頭引入:
- 文件模式:
- 引入官方的內(nèi)置模塊
目錄模式:
* 會(huì)在當(dāng)前目錄下尋找`node_modules`文件,找到之后會(huì)引入`index.js`。
* 如果沒有`index.js`文件,可以通過`package.json`指定入口文件。
第三方模塊
網(wǎng)站:https://www.npmjs.com/
通過npm安裝第三方包,npm是一個(gè)命令,跟隨Node.js一起安裝。
修改鏡像源:npm config set registry https://registry.npm.taobao.org
全局安裝資源:
- npm install <package-name> --global
- npm i <package-name> -g
minify ./style.css > ./style.min.css
項(xiàng)目安裝:
- 創(chuàng)建項(xiàng)目目錄(mkdir project);
- 進(jìn)入項(xiàng)目目錄(cd project);
- 初始化項(xiàng)目(npm init);
- 在項(xiàng)目中安裝包;
- npm install <package-name> --sava
- npm i <package-name> -S
./node_modules/bin/minify ./style.css > ./style.main.css
--save/-S : 安裝的包,開發(fā)和上線都需要
--save-dev/-D : 安裝的包,只在開發(fā)環(huán)境使用
壓縮css文件插件
- 安裝:
npm i minify -g - 使用:
minify output.css > output.min.css
將less轉(zhuǎn)為css
- 安裝:
npm i less -g - 使用:
lessc input.less output.css
發(fā)布服務(wù)
- 安裝:
npm i serve -g - 使用:
serve .
腳手架工具
Yeoman
-
Yeoman是一款腳手架工具
- 可以幫助開發(fā)人員創(chuàng)建項(xiàng)目的基礎(chǔ)結(jié)構(gòu)代碼
-
yo是Yeoman的命令行管理工具
- 可以在命令行運(yùn)行yeoman的命令
-
生成器:Yeoman中具體的腳手架
- 針對不同項(xiàng)目有不同的額腳手架(例如:網(wǎng)站,APP,小程序等)
Yeoman 使用說明
- 全局安裝yo
- npm install --global yo
- 安裝generator
- npm install --global generator-webapp
- 通過yo運(yùn)行g(shù)enerator
- mkdir project-name
- cd project-name
- yo webapp
- 啟動(dòng)應(yīng)用
- npm run start
自動(dòng)化構(gòu)建
npm scripts
-
npm允許在package.json文件中,使用scripts字段定義腳本命令。
npm scripts 自定義腳本命令
- 1.聲明命令:在
package.json文件中,聲明scripts字段定義的腳本命令。"scripts": {"foo": "node bar,js"}
- 2.執(zhí)行命令:在終端中執(zhí)行命令
npm run foo
npm scripts 命令的執(zhí)行方式
-
并行執(zhí)行:
- 任務(wù)1 & 任務(wù)2
- 任務(wù)之間沒有先后順序,同時(shí)執(zhí)行可以提高執(zhí)行效率
-
串行執(zhí)行:
- 任務(wù)1 && 任務(wù)2
- 任務(wù)之間有先后順序,先執(zhí)行一個(gè)任務(wù),后執(zhí)行下一個(gè)。
注意:并行執(zhí)行
&符號在windows中不起作用。-
解決方法:
- 在項(xiàng)目中安裝
npm-run-all插件。npm i npm-run-all -D. - 并行執(zhí)行:
npm-run-all -p 腳本1 腳本2 腳本3 - 并行執(zhí)行簡寫:
run-p 腳本1 腳本2 腳本3 - 串行執(zhí)行:
npm-run-all -s 腳本1 腳本2 腳本3 - 串行執(zhí)行簡寫:
run-s 腳本1 腳本2 腳本2
- 在項(xiàng)目中安裝
示例代碼:
// package.json
{
"name": "stylesFile",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
// 現(xiàn)將less文件轉(zhuǎn)換成css文件,然后再壓縮。
"style": "lessc styles/index.less styles/index.css && minify styles/index.css > styles/index.min.css"
},
"keywords": [],
"author": "",
"license": "ISC"
}
腳本文件
在ES6中新增加了一些語法,可能在一些瀏覽器中不支持,所以需要將ES6+的新語法轉(zhuǎn)成ES5的語法。可以使用Babel插件,將ES6的語法轉(zhuǎn)換成ES5的語法。
- 安裝Babel:
npm install -g babel-core babel-cli - 安裝轉(zhuǎn)碼規(guī)則:
npm install -g babel-preset-env - 配置轉(zhuǎn)換規(guī)則:
.babelrc一定要將文件放到根目錄。不要省略文件名前面的 "."。 - 在npm scripts中添加轉(zhuǎn)換命令(babel src -d dist)
- 執(zhí)行轉(zhuǎn)換命令
// .babelrc 配置轉(zhuǎn)換規(guī)則
{
"presets": [
"env"
]
}
- 轉(zhuǎn)換規(guī)則:
babel-preset-env - 轉(zhuǎn)換命令:
- 單個(gè)文件:
babel input.js --out-file output.js或babel input.js -o oupput.js - 整個(gè)目錄:
babel src --out-dir dist或babel src -d dist
- 單個(gè)文件:
代碼格式化的校驗(yàn)
- 不同的工程師,代碼風(fēng)格不統(tǒng)一。
- 項(xiàng)目代碼提交時(shí),需要保持統(tǒng)一的代碼格式。
- 可以通過工具完成代碼格式校驗(yàn)。
- 格式校驗(yàn)工具提供編碼規(guī)范,根據(jù)編碼規(guī)范,自動(dòng)檢查代碼。
使用 ESLint,校驗(yàn)js代碼。
官網(wǎng):eslint.org
- 初始化項(xiàng)目(npm init --yes)
- 安裝ESLint(npm i eslint -g)
- 初始化配置文件(eslint --init)
- 檢查js代碼格式。
- 單個(gè)文件檢查:eslint path/filename.js
- 整個(gè)目錄檢查:eslint path/dirname
初始化配置文件中的rules表示規(guī)則,可以進(jìn)行配置。
- indent:表示縮進(jìn),他的值是一個(gè)數(shù)組,里面可以配置兩個(gè)參數(shù)。
-
第一個(gè)參數(shù):
-
off:表示關(guān)閉。 -
warn:警告,不影響代碼格式檢測。 -
error:錯(cuò)誤,檢查代碼格式
-
-
第二個(gè)參數(shù):
- 數(shù)字類型,表示縮進(jìn)。
-
- quotes:表示引號。他的值是一個(gè)數(shù)組,里面可以配置兩個(gè)參數(shù)。
-
第一個(gè)參數(shù):
-
off:表示關(guān)閉。 -
warn:警告,不影響代碼格式檢測。 -
error:錯(cuò)誤,檢查代碼格式
-
-
第二個(gè)參數(shù):
- double:表示雙引號。
-
StyleLint 校驗(yàn)css代碼
用于檢測css代碼格式規(guī)范
官網(wǎng):stylelint.io
- 初始化項(xiàng)目:npm init --yes
- 安裝StyleLint:npm i stylelint -g
- 安裝檢測標(biāo)準(zhǔn):npm i stylelint-config-standard
- 創(chuàng)建配置文件:.stylelintrc.json
{"extends": "stylelint-config-standard"}
- 檢查CSS代碼格式:
- 單個(gè)文件:stylelint path/filename.css
- 整個(gè)項(xiàng)目:stylelint */.css
自動(dòng)化構(gòu)建工具
Gulp
Gulp與npm scripts的區(qū)別
Gulp與npm scripts都能夠?qū)崿F(xiàn)自動(dòng)化構(gòu)建
-
Gulp語法簡單
- Gulp語法就是JavaScript語法。
- npm scripts語法接近shell腳本。
Gulp生態(tài)完善,構(gòu)建效率高。
Gulp使用
- 全局安裝gulp客戶端:
npm install -g gulp-cli - 初始化項(xiàng)目:
npm init --yes - 安裝gulp包:
npm install gulp -D - 新建gulpfile文件,文件必須在項(xiàng)目的跟目錄下:
gulpfile.js - 在gulpfile.js中,創(chuàng)建gulp任務(wù)。
- 執(zhí)行g(shù)ulp任務(wù):
gulp <task-name> - 注意:
- gulp任務(wù)是一個(gè)異步任務(wù),在創(chuàng)建任務(wù)的時(shí)候,需要?jiǎng)?chuàng)建異步任務(wù),可以添加一個(gè)回調(diào)函數(shù),在任務(wù)中執(zhí)行回調(diào)函數(shù)。
- 任務(wù)創(chuàng)建成功之后,需要導(dǎo)出任務(wù)。
- 示例代碼:
const gulp = require("gulp");
// 創(chuàng)建任務(wù)
const task1 = (cb) => {
setTimeout(() => {
console.log("task1 is running");
cb();
}, 1000)
};
module.exports = {
task1,
};
Gulp組合任務(wù)
Gulp中的組合任務(wù)就是指任務(wù)并行執(zhí)行或者串行執(zhí)行。
并行執(zhí)行:
- gulp.parallel(task1, task2, task3)
串行執(zhí)行
- gulp.series(task1, task2, task3)
代碼示例:
const gulp = require("gulp");
// 創(chuàng)建任務(wù)
const task1 = (cb) => {
setTimeout(() => {
console.log("task1 is running");
cb();
}, 1000);
};
const task2 = (cb) => {
setTimeout(() => {
console.log("task2 is running");
cb();
}, 1000);
};
const task3 = (cb) => {
setTimeout(() => {
console.log("task3 is running");
cb();
}, 1000);
};
// 并行執(zhí)行
exports.p = gulp.parallel(task1, task2, task3);
// 串行執(zhí)行
exports.s = gulp.series(task1, task2, task3);
// 終端執(zhí)行命令方式:
// gulp p
// gulp s
gulp 文件操作
Gulp的文件操作是基于流的構(gòu)建系統(tǒng)來操作文件的。
步驟:
- 輸入(讀取流)
- 對應(yīng)函數(shù):src(),讀取文件。
- 參數(shù)1:讀取的文件地址。
- 參數(shù)2:寫入文件的參照路徑,對象格式。
- {base: "src"} 表示參照src中的文件路徑最終寫入文件。
- 加工(轉(zhuǎn)換流)
- 對應(yīng)函數(shù):pipe()
- 管道可以進(jìn)行多次操作,稱作為管道流
- 輸出(寫入流)
- 對應(yīng)函數(shù):dest()
- 參數(shù):將文件寫入的目標(biāo)路徑。
示例代碼:
// 文件操作任務(wù),本身就是異步任務(wù),所以不需要回調(diào)函數(shù)
const fileStyle = () => {
return gulp
.src("src/style/main.less", { base: "src" })
.pipe(gulp.dest("dest"));
};
module.exports = {
fileStyle,
};
使用gulp插件完成文件轉(zhuǎn)換
// 文件轉(zhuǎn)換任務(wù)
// gulp-less 將less文件轉(zhuǎn)換成css文件
const gulpLess = require("gulp-less");
// gulp-clean-css 壓縮css文件
const cleanCss = require("gulp-clean-css");
// gulp-rename 文件重命名
const rename = require("gulp-rename");
const fileStyle = () => {
return gulp
.src("src/style/main.less", { base: "src" })
.pipe(gulpLess())
.pipe(cleanCss())
.pipe(rename({ extname: ".min.css" }))
.pipe(gulp.dest("dest"));
};
module.exports = {
fileStyle,
};
CSS hack
- css代碼也會(huì)存在兼容性問題。同一段css代碼,在不同的瀏覽器上的呈現(xiàn)效果不同。
- 針對不同瀏覽器寫相對應(yīng)的css代碼的過程,叫做 CSS hack。
- CSS hack的目的就是使css代碼兼容不同的瀏覽器。
CSS hack屬性前綴法
- 給css屬性添加瀏覽器特有的前綴。稱之為屬性前綴法。
| 瀏覽器 | 前綴 |
|---|---|
| IE | -ms- |
| chrome | -webkit- |
| Safari | -webkit- |
| Firefox | -moz- |
| Opera | -o- |
Autoprefixer
- Autoprefixer插件可以自動(dòng)的將一些css的屬性,添加前綴,不用自己手動(dòng)書寫屬性的前綴名稱。
- Autoprefixer使用caniuse.com的數(shù)據(jù),來決定哪些屬性需要加前綴。caniuse.com可以查詢屬性的兼容性。
安裝:npm i gulp-autoprefixer
示例代碼:
const gulp = require("gulp");
// gulp-less 將less文件轉(zhuǎn)換成css文件
const gulpLess = require("gulp-less");
// gulp-clean-css 壓縮css文件
const cleanCss = require("gulp-clean-css");
// gulp-rename 文件重命名
const rename = require("gulp-rename");
// gulp-autoprefixer css自動(dòng)添加前綴
const autoprefixer = require("gulp-autoprefixer");
const fileStyle = () => {
return (
gulp
.src("src/style/main.less", { base: "src" })
.pipe(gulpLess())
.pipe(autoprefixer())
// .pipe(cleanCss())
// .pipe(rename({ extname: ".min.css" }))
.pipe(gulp.dest("dest"))
);
};
module.exports = {
fileStyle,
};
Gulp 腳本文件轉(zhuǎn)換
Gulp 構(gòu)建腳本文件所需插件
-
gulp-babel:將ES6新語法轉(zhuǎn)換成ES5語法。
- npm install --save-dev gulp-babel@7 babel-core babel-preset-env
-
gulp-uglify:壓縮js代碼。
- npm i gulp-uglify -D
gulp-rename:對文件進(jìn)行重命名。
示例代碼:
const gulp = require("gulp");
// gulp-babel 將ES6新語法轉(zhuǎn)換成ES5
const gulpBabel = require("gulp-babel");
// gulp-uglify 壓縮js代碼
const gulpUglify = require("gulp-uglify");
// gulp-rename 重命名
const rename = require("gulp-rename");
// 創(chuàng)建腳本文件轉(zhuǎn)換任務(wù)
const scripts = () => {
return gulp
.src("src/js/main.js")
.pipe(gulpBabel({ presets: "babel-preset-env" }))
.pipe(gulpUglify())
.pipe(rename({ extname: ".min.js" }))
.pipe(gulp.dest("dest/script"));
};
module.exports = {
scripts,
};
Gulp 構(gòu)建HTML文件
Gulp HTML文件所需要的插件
- gulp-htmlmin:壓縮html文件。
示例代碼:
// 創(chuàng)建壓縮html文件任務(wù)
const html = () => {
return gulp
.src("src/index.html")
.pipe(
htmlmin({
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true,
})
)
.pipe(gulp.dest("dest"));
};
Gulp 構(gòu)建圖片文件
圖片文件所需插件
- gulp-imagemin:壓縮圖片文件
Gulp 文件清除
文件清除所需插件
- del 刪除文件和目錄
const clearFile = () => {
return del("dist");
};
Gulp 發(fā)布服務(wù)
通過插件將html,css,js等文件壓縮之后,最終要發(fā)布的是壓縮之后的文件。
開發(fā)服務(wù)器插件
- browser-sync:服務(wù)發(fā)布
const server = () => {
watch("src/index.html", fileHtml);
watch("src/css/*.css", fileStyle);
watch("src/js/*.js", fileScript);
browserSync.init({
notify: false,
files: "dist/**", // 監(jiān)聽dist下的所有文件
server: {
baseDir: "./dist", // 指定服務(wù)啟動(dòng)的目錄
routes: { "/node_modules": "node_modules", "/lib": "lib" },
},
});
};
Gulp 中使用Bootstrap
- 安裝:
- bootstrap:提供常用的頁面效果
- jquery:Bootstrap的依賴包