关于前端:实战在Nodejs和Vuejs中构建文件压缩应用程序

1次阅读

共计 6262 个字符,预计需要花费 16 分钟才能阅读完成。

Node.js 为咱们提供了一个模块来帮助文件压缩。在本文中,咱们将构建一个应用程序,用户能够在该应用程序中上传他们想要压缩的文件,而后应用 Node.js Zlib 模块下载该文件的压缩版本。

前提

要持续学习本教程,你须要具备以下条件:

  • 相熟 HTML,CSS 和 Javascript(ES6 +)
  • VS Code 或开发计算机上安装的任何代码编辑器
  • 在你的开发机器上装置了 Postman
  • Vue 和 Node.js 的基础知识

设置我的项目

咱们将从构建后端开始,这是咱们应用程序的根底。

在桌面上,为应用程序创立一个文件夹,群殴取名为 compressor,并通过运行 npm init -y 设置一个新的 Node.js 我的项目。

咱们先编写后端服务,所以在我的项目中再建设一个 server 目录。

当初,咱们须要为利用程序安装必要的软件包:

  • koakoa-router:这将有助于设置咱们的服务器以及路由
  • nodemon:当咱们对应用程序进行更改时,Nodemon 将重新启动咱们的服务器
  • multer:用于上传文件的中间件
  • cors:帮忙将 headers 增加到代理申请中

要装置所有这些,请在咱们创立的 server 目录中运行以下命令:

npm i --save koa koa-router nodemon multer cors

实现装置后,在 server 目录内创立一个 index.js 文件,这是咱们将编写后端代码的中央。

应用 VS Code 关上文件夹。在开始之前,咱们先创立一个 .gitignore 文件,并向其中增加 node_modules,这将避免将 node_modules 文件夹增加到 git 中。

让咱们持续来创立一个简略的 Koa.js 服务器,而后配置咱们的 packages:

const express = require('express');
const multer = require('multer');
const zlib = require('zlib');
const cors = require('cors');
const fs = require('fs');
const path = require('path');
const app = express();
app.use(cors());

//multer
const storage = multer.memoryStorage();
const upload = multer({storage: storage,});

app.listen(3000, () => {console.log('App is runnuing on port 3000');
});

咱们首先要求咱们装置的包,如 Express、Multer 和 Cors。而后,咱们创立一个 Express 的实例,并将其保留在一个变量中。咱们应用 Express 实例来配置咱们的 cors 作为中间件。

咱们还须要一些 Node.js 的外围模块,比方 zlib,咱们将应用它来进行理论的压缩。而后咱们应用 Express 的实例来创立一个服务器,它将监听 3000 端口。

接下来,咱们将创立一个路由,该路由将接管一个文件,而后返回压缩文件。

Zlib 有很多压缩办法,然而在本文中,咱们将应用 gzip 办法。

app.post("/compress", upload.single("file"), async (req, res) => {
  try {const destination = `compressed/${req.file.originalname}.gz`;
    let fileBuffer = req.file.buffer;
    await zlib.gzip(fileBuffer, (err, response) => {if (err) {console.log(err);
      }
      fs.writeFile(path.join(__dirname, destination), response, (err, data) => {if (err) {console.log(err);
        }
        res.download(path.join(__dirname, destination));
      });
    });
  } catch (err) {console.log(err);
    res.json(err);
  }
});

咱们定义 /compress 路由,这是一个 POST 申请,而后在该路由中传递 Multer 中间件。咱们的 Multer 中间件将返回文件缓冲区,该文件缓冲区存储在 fileBuffer 变量中。

为了进行测试,咱们创立一个 compressed 目录,在其中保留压缩文件。

咱们将应用 Multer 中间件来取得咱们想要压缩的文件的名称,以便咱们能够将其保留到咱们的 compressed 目录中。

const destination = `compressed/${req.file.originalname}.gz`;

咱们应用 Zlib 办法 gzip 来压缩文件,该办法将 fileBuffer 作为第一个参数,而后将一个回调函数作为第二个参数。回调函数由任何可能的谬误和压缩响应组成。

失去 Zlib 响应后,咱们创立一个文件并将响应保留在 compressed 目录中,该文件将具备 .gz 文件扩展名,因为它用于标识 Zlib 压缩。

当初,咱们能够在开始前端之前在 Postman 上测试咱们的应用程序,我将压缩 package.lock.json 文件,它的大小是 48kb。

压缩文件可失去 11kb。

当初咱们的后端曾经筹备好,咱们能够为应用程序设置用户界面。

让咱们在 compressor 根目录内创立一个 client 目录。在 client 目录中,创立两个文件:index.htmlmain.js

咱们将从为利用程序定义用户界面开始。

咱们将搭建一个 HTML 5 样板文件,而后在模板头中增加 vuei .js 脚本、Bootstrap CSS CDN 和 Axios 脚本。而后,咱们将在 body 标记的开端增加 main.js 文件。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue Compressor</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
        integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
  <div id="app">
    <h1> 压缩 </h1>
  </div>
  <script src="main.js"></script>
</body>
</html>

对于此应用程序,用户将通过拖放增加其文件。让咱们为咱们的利用程序定义一个简略的用户界面。

批改模板为:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue Compressor</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
        integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <style>
    body {background: #ccc !important;}
    .wrapper {
      width: 350px;
      height: 350px;
      border: 2px dotted gray
    }
    .wrapper h4 {
      text-align: center;
      font-family: sans-serif;
    }
  </style>
</head>
<body>
<div id="app">
  <div class="container">
    <div class="row">
      <div class="col-md-12">
        <div class="wrapper mt-5 p-3">
          <h4> 在这里拖放 </h4>
          <ul class="list-group mt-5">
            <li class="list-group-item">FileName -> File Size <button class="btn btn-sm btn-danger">X</button></li>
          </ul>
        </div>
        <button class="btn btn-primary my-4">  
          <span class="spinner-border spinner-border-sm" role="status" v-if="loading" aria-hidden="true"></span>
          压缩
        </button>
      </div>
    </div>
  </div>
</div>
  <script src="main.js"></script>
</body>

你能够应用任何实时服务器运行你的应用程序,这里我应用 live-server

拖放性能

咱们先在 main.js 文件中定义咱们的 Vue.js 实例。而后,咱们将创立一个 state 来保留咱们的文件。

const app = new Vue({
  el: '#app',
  data: {files: [],
    loading:false
  },
  methods: {addFile(e) { },
    removeFile(file) { },
    compressFile() {}
  }
})

在 Vue 中实现拖放,咱们须要增加一个 @drop 事件来抉择咱们的文件,还有一个 v-cloak 属性,这个属性用于在利用加载之前暗藏 {{tags}}

<div class="wrapper mt-5 p-3" v-cloak @drop.prevent="addFile">
  <h4> 在这里拖放 </h4>
</div>

@drop 事件监听 addFile 办法,咱们必须定义:

addFile(e) {
  let files = e.dataTransfer.files;
  [...files].forEach(file => {this.files.push(file);
    console.log(this.files)
  });
}

应用这种办法,搁置在框中的所有文件都将记录在咱们的管制台上。

然而,咱们想在框内显示文件,因而咱们必须将 <li> 元素批改为:

<li v-for="(file,id) in files" :key="id" class="list-group-item">
  {{file.name}}-{{file.size}} kb<button class="btn btn-sm btn-danger">X</button>
</li>

这样,每当咱们将文件放入框中时,都会显示文件名和大小。

咱们能够通过向 X 按钮增加点击事件来增加额定的性能,以从框中删除文件:@click =‘removeFile(file)’

而后,咱们定义 removeFile 办法:

removeFile(file) {
  this.files = this.files.filter(f => {return f != file;});
},

让咱们定义压缩函数,该函数将压缩所选文件,这就是 Axios 的作用所在。咱们将向咱们在后端定义的 /compress 路由发出请求:

compressFile() {
  this.loading = true;
  let formdata = new FormData();
  formdata.append('file', this.files[0])
  axios.post('http://localhost:3000/compress', formdata, {responseType: 'blob'}).then(response => {let fileURL = window.URL.createObjectURL(new Blob([(response.data)]))
    let fileLink = document.createElement('a');
    fileLink.href = fileURL;
    fileLink.setAttribute('download', `${this.files[0].name}.gz`);
    document.body.appendChild(fileLink);
    fileLink.click();
    this.loading = false;
  }).catch(err => {
    this.loading = false;
    console.log(err)
  })
}

咱们应用 FormData 上传文件。上载文件后,后端会压缩文件并将压缩后的文件返回给咱们。

咱们应用 URL.createObjectURL 创立一个 DOMstring,其中蕴含示意给定对象的 URL。而后,咱们从后端下载给定的数据。

当初,咱们须要在 compress 按钮中增加一个 click 事件,以侦听咱们创立的办法:

<button class="btn btn-primary my-4" @click="compressFile"> 
  <span class="spinner-border spinner-border-sm" 
        role="status" v-if="loading"
        aria-hidden="true"></span>
  压缩 
</button>

单击咱们的压缩按钮将触发文件下载:

就是这样!

咱们只是建设了一个简略的压缩应用程序。最初咱们很想增加一个简略的办法,通过创立一个 Vue.js 过滤器,将咱们的文件大小以千字节为单位进行格式化。

filters: {kb(val) {return Math.floor(val / 1024);
  }
},

在模板中应用

{{file.size | kb}} kb

这会将文件的大小格式化为更易读的格局。

源码

Node.js 使文件压缩变得容易。它能够进一步用于压缩 HTTP 申请和响应,以进步应用程序性能。要取得更多 Zlib 性能,能够查看 Zlib 上的 Node.js 文档。

源代码:https://github.com/dunizb/CodeTest/tree/master/Node/compressor

首发于公众号《前端全栈开发者》,第一工夫浏览最新文章,会优先两天发表新文章。关注后私信回复:大礼包,送某网精品视频课程网盘材料,准能为你节俭不少钱!

正文完
 0