Photo by Daniel Battersby
Zip is not supported out of the box by Node.js. By having a look out there, we can find some libraries but none of them provides clear documentation of how to do it.
We'll try today to fix that!
For this article, I chose the library jszip as it's the lightest and easiest to use!
Setup our environment
Before starting to write any code, let's set up our environment.
You'll need a Node.js environment as this won't work with any web-based environment. Although Jszip is web compatible, we are going to use fs to read our file
Let's install jszip with the command npm install -S jszip
.
We are also going to need a zip file for this. But I assume that if you came on this article, it's because you already have one and you don't know how to extract it! For my article, I zipped my package-lock.json
into a zip file. Here is its structure:
- package-lock
| package-lock.json
Opening our zip file
Before being able to extract the content of our zip file, we need to access it. To do that, we are going to use the built-in file system module fs
:
Read the zip file
As my project is very minimal. I had to create a function and execute it to use the async/await feature.
No need to precise any encoding when reading the file, all we need is the raw content of it.
Loading our zip file
Now after reading the file, we'll want to load it with Jszip. Firstly, we have to create an instance of it:
Creating an instance of jszip
With the instance created, we can load our file by adding the following code:
Load the zip file
So we've loaded our file now, let's stop for a minute and have a look at its content. By running a console.log on it, here is what's printed:
{
files: [Object: null prototype] {
'package-lock/': {
name: 'package-lock/',
dir: true,
date: 2022-05-29T18:12:24.000Z,
comment: null,
unixPermissions: null,
dosPermissions: 16,
_data: [Promise],
_dataBinary: true,
options: [Object]
},
'package-lock/package-lock.json': {
name: 'package-lock/package-lock.json',
dir: false,
date: 2022-05-01T22:40:52.000Z,
comment: null,
unixPermissions: null,
dosPermissions: 32,
_data: [Object],
_dataBinary: true,
options: [Object],
unsafeOriginalName: 'package-lock/package-lock.json'
}
},
comment: null,
root: '',
clone:
We can see a couple of items like comment
or root
but we are not going to give much attention to them.
However, what's interesting is the files
object. We have two items in there:
- package-lock/
- package-lock/package-lock.json
The first one is the folder containing our file. We can confirm it's a folder as the item dir
is true.
The second item is contained within our folder and it's our package-lock.json.
Extract our zip in the current directory
Now, let's extract them both. The easiest way to extract all our items is by looping on the keys within the files
object and then either creating a new directory (if it's a directory) or creating the file.
Jszip is well done and will always follow a logical order, which means that directories will always be before files and you won't end up being unable to create a file because the directory doesn't exists
Looping through the files
In this case, I decided to use a for loop as we'll need to do some async operations later on.
In this code, we are looping through all the keys, get the corresponding file and check if it's a directory or not. If it's a directory, we simply create a directory with fs.mkdirSync
.
You can also use
fs.mkdir
if you prefer.
Now we have to write our files. To do that, we are going to use fs.writeFileSync
and the async()
function available for each file item. This function allows us to convert the file to a readable format that fs can understand and write. In our case, it'll be an arraybuffer
.
Our final code
And here we are! If you run this piece of code, you are going to be able to extract and replicate the content of your zip file in your root directory!
This is all about unzipping a file with Node.js and Jszip. Thank you for reading.