腳手架設(shè)計(jì)
參考項(xiàng)目 G:\webpack-learn\my-cli
1. 為什么需要腳手架
腳手架 提供 創(chuàng)建項(xiàng)目, 項(xiàng)目運(yùn)行, 項(xiàng)目框架, 項(xiàng)目打包, 項(xiàng)目發(fā)布,等一系列能力,提升研發(fā)效率, 簡化復(fù)雜流程
2. 當(dāng)在命令行里輸入vue create app發(fā)生了什么
會(huì)找到vue對(duì)應(yīng)的可執(zhí)行文件, 然后執(zhí)行.
- 如果是蘋果系統(tǒng)會(huì)執(zhí)行
which vue, 找到對(duì)應(yīng)文件后執(zhí)行. - 如果是window, 用
where vue, 他會(huì)找到對(duì)應(yīng)文件. 找到對(duì)應(yīng)文件vue.js后, 第一行會(huì)有一個(gè)#!/usr/bin/env node,表示該文件是由node執(zhí)行的, 然后再找node的可執(zhí)行文件 比如C:\Program Files\nodejs\node.exe. 再用node.exe執(zhí)行vue.js. - 找到這些文件后,會(huì)把vue后面的字段當(dāng)做參數(shù),傳入可執(zhí)行文件中. 啟動(dòng).
- 可執(zhí)行文件的例子
- node_modules/.bin/webpack-cli.cmd
- C:\Program Files\Git\bin\bash.exe (很多.exe格式)
- package.json里有bin屬性
{
"bin": {
"my-app": "./bin/my-app"
},
}
- 啟動(dòng)文件的方式
默認(rèn).js文件是沒法啟動(dòng)的, 需要告訴系統(tǒng)啟動(dòng)方式, 在文件開頭添加#!/usr/bin/env node, 效果就是在命令行輸入/usr/bin/env node console.log(123), 命令行就知道用node啟動(dòng)了. - 操作系統(tǒng)window只能執(zhí)行二進(jìn)制文件, 比如node.exe. 而vue.js就需要node解析成二進(jìn)制再執(zhí)行
腳手架執(zhí)行流程
- 在終端輸入
vue create app - 終端解析出
vue命令 - 終端在環(huán)境變量中找到
vue命令 - 終端根據(jù)
vue命令鏈接到實(shí)際文件vue.js - 終端查看vue.js第一行,
#!/usr/bin/env node,確實(shí)是用node作為執(zhí)行程序 - 終端執(zhí)行命令
/usr/bin/env node vue.js - vue.js解析后續(xù)參數(shù)
create app,并執(zhí)行文件
3. 創(chuàng)建腳手架
- 創(chuàng)建npm項(xiàng)目
- 配置package.json的bin屬性
"bin": {
"imooc-ls": "./bin/imooc-ls.js"
},
- 在bin/imooc-ls.js文件開頭加上
#!/usr/bin/env node - 編寫imooc-ls.js, 比如
console.log(123) - 執(zhí)行命令
npm link, 將imooc-ls變成全局命令, 此時(shí)在全局的終端都可以使用imooc-ls命令了- 由于imooc-ls是用node執(zhí)行的命令,
npm link會(huì)在C:\Program Files\nodejs文件夾中,會(huì)生成關(guān)于imooc-ls的命令文件imooc-ls.cmd - 地址
C:\Program Files\nodejs\node_modules\imooc-ls是一個(gè)軟鏈接,指向我們真實(shí)的文件地址. - 執(zhí)行
imooc-ls時(shí),是先執(zhí)行C:\Program Files\nodejs\imooc-ls.cmd(二進(jìn)制文件),這個(gè)文件會(huì)啟用node執(zhí)行imooc-ls.js
- 由于imooc-ls是用node執(zhí)行的命令,
- 用
npm public將腳手架發(fā)布到npm服務(wù)器.
4. imooc-ls.js 命令文件開發(fā)
- 獲取命令參數(shù)用
process.argv獲取
// process.argv: ['node根目錄地址', 'imooc-ls目錄地址', '命令參數(shù)1', '命令參數(shù)2', ...]
/* 執(zhí)行"imooc-ls -all"
[
'C:\\Program Files\\nodejs\\node.exe',
'C:\\Program Files\\nodejs\\node_modules\\imooc-ls\\bin\\index.js',
'-all'
]
*/
console.log(process.argv);
// 執(zhí)行 node bin/index.js -a
// [
// 'C:\\Program Files\\nodejs\\node.exe',
// 'C:\\Program Files\\nodejs\\node_modules\\imooc-ls\\bin\\index.js',
// '-a'
// ]
imooc-ls -a 和 node bin/index.js -a, 效果是一樣的
- 獲取命令終端的工作目錄
輸入命令行的地方的工作目錄 process.cwd()
4. unix系統(tǒng)
Unix系統(tǒng)包括linux, MacOs.
用ls -l獲取到文件權(quán)限
// 文件權(quán)限
drwxr-xr-x 5 sam staff 160 Apr 4 13:58 bin
-rw-r--r-- 1 sam staff 260 Apr 4 13:58 package.json
文件權(quán)限drwxr-xr-x
- d: directory目錄, -表示文件
- r: read 讀取權(quán)限,表示文件是否可讀
- w: write 寫入權(quán)限,是否可修改
- x: execute 執(zhí)行權(quán)限,
- 如果是文件夾,是否可進(jìn)入,
- 如果是文件,是否可執(zhí)行.
rwxr-xr-x: 三個(gè)權(quán)限為一組,u|g|o,rwx(user當(dāng)前用戶權(quán)限)|r-x(group用戶所在分組權(quán)限)|r-x(other其他用戶權(quán)限)
unix使用32位二進(jìn)制數(shù)存儲(chǔ)文件類型和權(quán)限
在unix中萬物都是文件, 文檔,目錄, 鍵盤, 監(jiān)視器, 硬盤,網(wǎng)絡(luò)通信都是文件. 是文件,就有一套文件屬性.
這些文件屬性是用一個(gè)32位的二進(jìn)制數(shù)保存的
// 32位的2進(jìn)制數(shù).
0000 0000 0000 0000
0000(文件類型), 000(特殊權(quán)限), 000(用戶權(quán)限), 000(分組權(quán)限), 000(其他權(quán)限)
前4位0000: 文件類型, 可以表示16種文件類型. 0001表示file普通文件, 0100表示directory,目錄
這里的文件類型是由 1所在的位置表示的,
1. 0001, 1在第四位,就是file普通文件
2. 0100, 1在第二位,就是目錄.
用1所在位置記錄值,是因?yàn)? 二進(jìn)制程序有專門的位運(yùn)算符&, 可以用來快速判斷 當(dāng)前用戶是否有某權(quán)限.
unix系統(tǒng)文件mode含義

unix系統(tǒng)文件的mode各個(gè)位的含義

32位操作系統(tǒng)的位
- 8位二進(jìn)制: 00000000 可以表示0-255
- 16位二進(jìn)制: 00000000 00000000 可以表示 0-65535
- 32位二進(jìn)制: 00000000 00000000 00000000 00000000 可以表示 0-4294976295
操作系統(tǒng)的文件是由二進(jìn)制數(shù)組成的. 是可以直接執(zhí)行的機(jī)器語言.機(jī)器語言直接翻譯成人類語言就是匯編. 形如
00110000
00001000
00000010
01110000
00000010
00000100
00100100
00000000
8位操作系統(tǒng): 每一個(gè)匯編,由一個(gè)8位2進(jìn)制數(shù)表示,也就是有256個(gè)匯編語言.
16位操作系統(tǒng): 每一個(gè)匯編語言有兩個(gè)8位2進(jìn)制表示, 可以有65526個(gè)匯編.
32位操作系統(tǒng): 每一個(gè)匯編語言有4個(gè)8位2進(jìn)制表示, 可以有4294976296個(gè)匯編. 但是 不是每一個(gè)值的格式都是4個(gè)8位二進(jìn)制.
比如32位操作系統(tǒng)的系統(tǒng)文件類型權(quán)限,就是用16位的2進(jìn)制數(shù)表示的. 00000000 00000000足夠表示所有的系統(tǒng)類型.
獲取系統(tǒng)文件類型和權(quán)限
// file: package.json, bin
const stat = fs.statSync(file);
console.log(
file, // 文件路徑
stat.mode, // 描述文件類型和模式的位字段, 轉(zhuǎn)成二進(jìn)制數(shù), 查看文件類型和權(quán)限
stat.isDirectory(), // 是否是文件夾
stat.isFile()); // 是否是文件
// package.json: mode: 33206, false, true
// bin: mode 16877 true, false
fs.statSync(file)的返回值里有 mode: 描述文件類型和模式的位字段, 轉(zhuǎn)成二進(jìn)制數(shù), 查看文件類型和權(quán)限
比如: bin文件夾的mode: 16822, 轉(zhuǎn)成二進(jìn)制 1000001 11101101,(第一位的0被省略了,自己加上即可)
01000001 11101101 轉(zhuǎn)換成查看用戶權(quán)限的格式
0100 000 111 101 101
文件類型 特殊權(quán)限 用戶權(quán)限 用戶所在分組權(quán)限 其他權(quán)限
文件類型(前4位): 0100: 表示文件夾
特殊權(quán)限: 000表示特殊權(quán)限, 在ls的輸出里不展示.
用戶權(quán)限: 111(rwx)(read wirte execute)
翻譯成ls輸出的格式就是
bin: drwxr-xr-x
package.json: -rw-rw-rw-
位運(yùn)算符 &
文件權(quán)限的計(jì)算方式
下面的 mode是 33188, S_IXUSR: 64
"&" 是一個(gè)位運(yùn)算符,表示按位與操作。它將兩個(gè)數(shù)字的二進(jìn)制表示進(jìn)行逐位比較,如果兩個(gè)相應(yīng)的二進(jìn)制位都為1,則該位的結(jié)果為1,否則為0。
比如下面的 mode & fs.constants.S_IXUSR;
// 當(dāng)前用戶是否有執(zhí)行權(quán)限.
const canUserExecute = mode & fs.constants.S_IXUSR;
// S_IXUSR : 64 => 1 000 000
// mode: 33188 => 10000001 10100100
// 進(jìn)行位的對(duì)比 都不相同所以是 0.
1000 000 110 100 100
001 000 000
fs.constants.S_IXUSR
S_IRUSR: S: 表示system系統(tǒng)文件, I: is是否, R: read閱讀權(quán)限, USR: user用戶. 當(dāng)前用戶的系統(tǒng)文件是否有執(zhí)行權(quán)限
用戶閱讀常量 S_IRUSR: 0000 0001 0000 0000 => 256
用戶修改常量 S_IWUSR: 0000 0000 1000 0000 => 128
用戶執(zhí)行常量 S_IXUSR: 0000 0000 0100 0000 => 64
這些常量共同特點(diǎn)是用2個(gè)8位二進(jìn)制保存的話, 所有二進(jìn)制位都只有一個(gè)1,
文件的mode轉(zhuǎn)成2個(gè)8位二進(jìn)制, 如果有對(duì)應(yīng)位置的1,那就有這個(gè)權(quán)限, 沒有對(duì)應(yīng)位置的1,就沒有對(duì)應(yīng)權(quán)限.
所以用 mode & fs.constants.S_IXUSR 可以用來判斷當(dāng)前文件是否有此權(quán)限. 這個(gè)計(jì)算方式也是設(shè)計(jì)好的一環(huán).
mode
mode: 33188 的這個(gè)值不是隨便取的, 也不是順序排的. 而是現(xiàn)有二進(jìn)制,再轉(zhuǎn)成10進(jìn)制的.
mode的二進(jìn)制: 1000 000 110 100 100 這里面的16個(gè)位, 每一個(gè)位都表示一種權(quán)限或類型. 比如最開頭的1表示文件夾, 第二個(gè)1表示用戶的讀取權(quán)限.
是先根據(jù)當(dāng)前文件的各種權(quán)限生成了這個(gè)16位的2進(jìn)制,再為了存儲(chǔ)方便,轉(zhuǎn)成10進(jìn)制,33188,保存在了mode里.
uid, gid
uid: userId 用戶id, 可以獲取用戶名userName
gid: groupId, 用戶所在組id, 可以獲取用戶所在組名groupName
ls -l
結(jié)果
drwxr-xr-x 2 root root 4096 Sep 22 15:08 a
-rw-r--r-- 1 root root 1010 Sep 22 16:52 auth.js
結(jié)果解析
drwxr-xr-x 2 root root 4096 Sep 22 15:08 a
//文件權(quán)限 文件夾下的文件數(shù)量 創(chuàng)建人 創(chuàng)建人所在分組 文件大小 修改時(shí)間 文件名
浙公網(wǎng)安備 33010602011771號(hào)