首頁  >  文章  >  web前端  >  Node實戰學習:瀏覽器預覽專案所有圖片

Node實戰學習:瀏覽器預覽專案所有圖片

青灯夜游
青灯夜游轉載
2023-01-06 21:00:212615瀏覽

Node實戰學習:瀏覽器預覽專案所有圖片

在前端實際專案開發中,會有這樣一種場景。每次引入新的圖片,並不知道這個資源是否被引用過,所以會點開存放圖片的資源一個個去看。實際問題是:

  • 1.圖片並不是放到一個目錄下的,可能存在任何的地方,不好找

  • 2 .費時間,費力

  • 3.可能會重複引入圖片資源

如果有個能力,將項目圖片資源羅列到一起查看,並方便看到引入路徑的話,就會大大節約開發的體力活。

如果要做這樣的能力,該考慮什麼呢?

需求分析

  • 可以整合到任何前端專案中,那就要求是個npm套件

  • 讀取文件,分析哪些是圖片,將圖片資源透過img標籤寫入到html檔案中

  • 建立一個伺服器,將html渲染出來

這就需要藉助Node來實現,需要用到的fs path http模組。 【相關教學推薦:nodejs影片教學程式設計教學

#實作

##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(&#39;./&#39;);
            return await Promise.all(imgPromiseArr);
         }
    
        module.exports = {
            getFileFun
        }

實作handleHtml

  • 這裡讀取test -read-img

    的html文件,並替換。

        const fs = require(&#39;fs&#39;).promises;
       const path = require(&#39;path&#39;);
    
       const createImgs = (images=[]) => {
           return images.map(i => {
               return `<div class=&#39;img-warp&#39;> 
                  <div class=&#39;img-item&#39;>  <img   src=&#39;${i}&#39; / alt="Node實戰學習:瀏覽器預覽專案所有圖片" > </div>
                  <div class=&#39;img-path&#39;>文件路径 <span class=&#39;path&#39;>${i}</span></div>
                </div>`
           }).join(&#39;&#39;);
       }
    
       async function handleHtml(images=[]) {
           const template =   await fs.readFile(path.join(__dirname,&#39;template.html&#39;),&#39;utf-8&#39;)
           const targetHtml = template.replace(&#39;%--%&#39;,`
            ${createImgs(images)}
           `);
          return targetHtml;
       }
    
       module.exports = {
        handleHtml
       }
    實作 createServer

#這裡讀取html 文件,並傳回給伺服器。 這裡僅僅實現了對

png的文件的展示,對於其他類型的圖片如何支持呢,這裡提示一下對   content-type

進行處理。

  const http = require(&#39;http&#39;);
const fs = require(&#39;fs&#39;).promises;
const path = require(&#39;path&#39;);
const open = require(&#39;open&#39;);

const createServer =(html) => {
  http.createServer( async (req,res) => {
      const  fileType = path.extname(req.url);
      let pathName = req.url;
      if(pathName === &#39;/favicon.ico&#39;) {
        return;
      }
      let type = &#39;&#39;
      if(fileType === &#39;.html&#39;) {
          type=`text/html`
      }
      if(fileType === &#39;.png&#39;) {
         type=&#39;image/png&#39;
      }
      if(pathName === &#39;/&#39;) {
          res.writeHead(200,{
              &#39;content-type&#39;:`text/html;charset=utf-8`,
              &#39;access-control-allow-origin&#39;:"*"
          })
            res.write(html);
            res.end();
            return
      }
      const data = await fs.readFile(&#39;./&#39; + pathName );
      res.writeHead(200,{
          &#39;content-type&#39;:`${type};charset=utf-8`,
          &#39;access-control-allow-origin&#39;:"*"
      })
      res.write(data);
      res.end();
      
  }).listen(3004,() => {
   console.log(&#39;project is run: http://localhost:3004/&#39;)
  open(&#39;http://localhost:3004/&#39;)
  });

 
}

module.exports = {
  createServer
}
效果

Node實戰學習:瀏覽器預覽專案所有圖片以上就是實作過程,執行一下

npm run test

就可以看到瀏覽器執行在http://localhost:3004/, 效果如下:

###發布############npm login#######

npm publish

思考

  • #為什麼要用非同步讀取檔案?

    因為js是單線程,同步讀取檔的話會卡在那裡,不能執行其他了。

  • 為什麼要用Promise 收集圖片

    因為不知道什麼時候讀取完文件,當非同步讀取完再用Promise.all整體處理

  • 為什麼不讀取新的html文件,而將結果直接傳回瀏覽器?

    如果將轉換後html放到 test-read-img 文件,就必須將圖片資源也要產生在目前目錄,不然html 讀取的相當路徑資源是找不到的,因為資源都在使用專案中。結束的時候還要將圖片資源刪除,這也無形增加了複雜度;

    如果將轉換後的html 寫入放到使用項目中,這樣就可以直接用圖片的路徑,並能正確加載,但是這樣會多了一個html文件,程序退出的時候還要刪除這個,如果忘記刪除了,就可能被開發者提交到遠程,造成污染,提供的預覽應該是無害的。這兩種方式都不可取。因此直接返回html資源,讓它載入相對目標專案路徑,不會產生任何影響。

更多node相關知識,請造訪:nodejs 教學

以上是Node實戰學習:瀏覽器預覽專案所有圖片的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除