前端工程化

前端工程化

  • 前端工程化就是通過各種工具和拘束,提升前端開發(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)置模塊

文檔地址:http://nodejs.cn/api/

內(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)建文件
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

https://www.yeoman.io

  • 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

示例代碼:

// 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.jsbabel input.js -o oupput.js
    • 整個(gè)目錄:babel src --out-dir distbabel src -d dist

代碼格式化的校驗(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的依賴包
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容