您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Node怎么實現瀏覽器預覽項目所有圖片”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Node怎么實現瀏覽器預覽項目所有圖片”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
在前端實際項目開發中,會有這樣一種場景。每次引入新的圖片,并不知道這個資源是否被引用過,所以會點開存放圖片的資源一個個去看。實際問題是:
1.圖片并不是放到一個目錄下的,可能存在任何的地方,不好查找
2.費時間,費力
3.可能會重復引入圖片資源
如果有個能力,將項目圖片資源羅列到一起查看,并方便看到引入路徑的話,就會大大節約開發的體力活。
可以集成到任何前端項目中,那就要求是個npm包
讀取文件,分析哪些是圖片,將圖片資源通過img標簽
寫入到html文件中
創建一個服務器,將html渲染出來
這就需要借助Node來實現,需要用到的 fs
path
http
模塊。
1 實現可發布npm包
創建一個項目 npm init
包名字是 test-read-img
在package.json 中加入如下代碼
"bin": {
"readimg": "./index.js"
},
在入口文件index.js 中加入測試代碼
含義是這個文件是可執行的node文件
#!/usr/bin/env node
console.log('111')
將當前模塊鏈接到全局node_modules模塊內,方便調試
執行 npm link
執行 readimg
就看到輸出111 了
到此就實現了通過命令使用npm包的使用了,當項目安裝了這個包,并配置執行命令,就可以在別的項目執行設計的npm包了,后面就實現這個
"scripts": {
"test": "readimg"
},
2 集成到別的項目
創建一個測試項目 ,執行 npm init
將測試包集成到當前項目, 執行 npm link test-read-img
配置執行命令
"scripts": {
"test": "readimg"
},
執行npm run test
就能看到當前項目執行了讀取文件的包的代碼了。 現在只輸出了 111距離讀取文件還很遠,下面來實現讀取文件
3 讀取文件
在 test-read-img
項目中,聲明一個執行函數,并執行.
#!/usr/bin/env node
const init = async () => {
const readFiles = await getFileFun();
const html = await handleHtml(readFiles);
createServer(html);
}
init();
這里解釋一下 ,各函數作用
getFileFun
: 讀取項目文件,并將讀取的圖片文件路徑返回,這里不需要圖片資源,后面解釋為什么。
handleHtml
: 讀取模版html文件, 將圖片資源通過 img
承載 生成新的html文件。
createServer
: 將生成的html ,放到服務器下去渲染出來。
主流程就是這樣。
實現getFileFun
功能
分析一下這個文件具體要做什么
循環讀取文件,直到將所有文件查找完,將圖片資源過濾出來,讀取文件要異步執行,如何知道何時讀取完文件呢,這里用promise
實現,這里僅僅實現了單層文件的讀取
,因為發布到公司內部的npm,請見諒。 聰明的你這里想想如何遞歸實現呢?
getFileFun
: 應該先讀取完文件,才能將圖片返回,所以異步收集器應該在后面執行。
具體代碼如下:
const fs = require('fs').promises;
const path = require('path');
const excludeDir = ['node_modules','package.json','index.html'];
const excludeImg = ['png','jpg','svg','webp'];
let imgPromiseArr = []; // 收集讀取圖片,作為一個異步收集器
async function readAllFile(filePath) { // 循環讀文件
const data = await fs.readdir(filePath)
await dirEach(data,filePath);
}
async function handleIsImgFile(filePath,file) {
const fileExt = file.split('.');
const fileTypeName = fileExt[fileExt.length-1];
if(excludeImg.includes(fileTypeName)) { // 將圖片丟入異步收集器
imgPromiseArr.push(new Promise((resolve,reject) => {
resolve(`${filePath}${file}`)
}))
}
}
async function dirEach(arr=[],filePath) { // 循環判斷文件
for(let i=0;i<arr.length;i++) {
let fileItem = arr[i];
const basePath = `${filePath}${fileItem}`;
const fileInfo = await fs.stat(basePath)
if(fileInfo.isFile()) {
await handleIsImgFile(filePath,fileItem)
}
}
}
async function getFileFun() { // 將資源返回給調用使用
await readAllFile('./');
return await Promise.all(imgPromiseArr);
}
module.exports = {
getFileFun
}
實現 handleHtml
這里讀取 test-read-img
的html文件,并替換。
const fs = require('fs').promises;
const path = require('path');
const createImgs = (images=[]) => {
return images.map(i => {
return `<div class='img-warp'>
<div class='img-item'> <img src='${i}' /> </div>
<div class='img-path'>文件路徑 <span class='path'>${i}</span></div>
</div>`
}).join('');
}
async function handleHtml(images=[]) {
const template = await fs.readFile(path.join(__dirname,'template.html'),'utf-8')
const targetHtml = template.replace('%--%',`
${createImgs(images)}
`);
return targetHtml;
}
module.exports = {
handleHtml
}
實現 createServer
這里讀取html 文件,并返回給服務器。
這里僅僅實現了對 png
的文件的展示,對于其他類型的圖片如何支持呢,這里提示一下對 content-type
進行處理。
const http = require('http');
const fs = require('fs').promises;
const path = require('path');
const open = require('open');
const createServer =(html) => {
http.createServer( async (req,res) => {
const fileType = path.extname(req.url);
let pathName = req.url;
if(pathName === '/favicon.ico') {
return;
}
let type = ''
if(fileType === '.html') {
type=`text/html`
}
if(fileType === '.png') {
type='image/png'
}
if(pathName === '/') {
res.writeHead(200,{
'content-type':`text/html;charset=utf-8`,
'access-control-allow-origin':"*"
})
res.write(html);
res.end();
return
}
const data = await fs.readFile('./' + pathName );
res.writeHead(200,{
'content-type':`${type};charset=utf-8`,
'access-control-allow-origin':"*"
})
res.write(data);
res.end();
}).listen(3004,() => {
console.log('project is run: http://localhost:3004/')
open('http://localhost:3004/')
});
}
module.exports = {
createServer
}
以上就是實現過程,執行一下 npm run test
就可以看到瀏覽器執行在http://localhost:3004/, 效果如下:
npm login
npm publish
為什么用異步讀取文件?
因為js是單線程,同步讀取文件的話會卡在那里,不能執行其他了。
為什么要用Promise 收集圖片
因為不知道什么時候讀取完文件,當異步讀取完再用Promise.all
整體處理
為什么 不讀取新的html文件,而將結果直接返回給瀏覽器?
如果將轉換后html放到
test-read-img
文件,就必須將圖片資源也要生成在當前目錄,要不然html 讀取的相當路徑資源是找不到的,因為資源都在使用項目中。結束的時候還要將圖片資源刪除,這也無形增加了復雜度;
如果將轉化后的html 寫入放到使用項目
中,這樣就可以直接用圖片的路徑,并能正確加載,但是這樣會多了一個html文件,程序退出的時候還要刪除這個,如果忘記刪除了,就可能被開發者提交到遠程,造成污染,提供的預覽應該是無害的。這兩種方式都不可取。因此直接返回html資源,讓它去加載相對目標項目路徑,不會產生任何影響。
讀到這里,這篇“Node怎么實現瀏覽器預覽項目所有圖片”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。