Zip and unzip files via a grunt plugin
This was created for dependency management via grunt-curl
and grunt-zip
as a low-tech alternative to bower
and similar solutions.
http://twolfson.com/2014-01-19-low-tech-dependency-management-via-grunt-tasks
Features
router
optionrouter
optiongrunt-zip
can be installed via npm: npm install grunt-zip
grunt-zip
provides 2 grunt tasks: zip
and unzip
Compress files into a zip
file
// Inside your Gruntfile.js
module.exports = function (grunt) {
// Define a zip task
grunt.initConfig({
zip: {
'location/to/zip/files.zip': ['file/to/zip.js', 'another/file.css']
}
});
// Load in `grunt-zip`
grunt.loadNpmTasks('grunt-zip');
};
Now, we can run our task:
$ grunt zip
Running "zip:location/to/zip/files.zip" (zip) task
File "location/to/zip/files.zip" created.
Done, without errors.
Extract files from a zip
file
// Inside your Gruntfile.js
module.exports = function (grunt) {
// Define an unzip task
grunt.initConfig({
unzip: {
'location/to/extract/files/': 'file/to/extract.zip'
}
});
// Load in `grunt-zip`
grunt.loadNpmTasks('grunt-zip');
};
Now, we can run our task:
$ grunt unzip
Running "unzip:location/to/extract/files/" (unzip) task
Created "location/to/extract/files/" directory
Done, without errors.
The short format relies on grunt's
support of {dest: src}
zip: {
'location/to/zip/files.zip': ['file/to/zip.js', 'another/file.css']
}
This format is suggested only if you don't need to run zip
tasks separately
grunt zip
If you want to run this task standalone, it must be executed via:
grunt zip:dest
# grunt zip:location/to/zip/files.zip
zip: {
'long-format': {
src: ['file/to/zip.js', 'another/file.css'],
dest: 'location/to/zip/files.zip'
}
}
cwd
The cwd
option sets the base path for the zipped files
zip: {
'using-cwd': {
cwd: 'nested/'
// Files will zip to 'hello.js' and 'world.js'
src: ['nested/hello.js', 'nested/world.js'],
dest: 'location/to/zip/files.zip'
}
}
router
The router
option allows for adjust file paths on a per-file basis. This cannot be used with cwd
since there are ordering conflicts.
// This example requires using node's `path` module
var path = require('path');
// Inside grunt config
zip: {
'using-router': {
// `router` receives the path from grunt (e.g. js/main.js)
// The path it returns is what the file contents are saved as (e.g. all/main.js)
router: function (filepath) {
// Route each file to all/{{filename}}
var filename = path.basename(filepath);
return 'all/' + filename;
},
// Files will zip to 'main.js' and 'main.css'
src: ['js/main.js', 'css/main.css'],
dest: 'files.zip'
}
}
We allow for specifying the DEFLATE
compression algorithm, base64 encoding, and including dotfiles
(e.g. .travis.yml
) via the following options:
zip: {
'using-delate': {
src: ['file.js'],
dest: 'files.zip',
compression: 'DEFLATE'
},
'encode-base64': {
src: ['file.js'],
dest: 'files.zip',
base64: true
},
'including-dotfiles': {
src: ['file.js'],
dest: 'files.zip',
dot: true
}
}
As with zip
, we support the {dest: src}
format. Additionally, it has the same drawbacks of being difficult to run standalone.
unzip: {
'location/to/extract/files': 'file/to/extract.zip'
}
unzip: {
'long-format': {
// Note: If you provide multiple src files, they will all be extracted to the same folder.
// This is not well-tested behavior so use at your own risk.
src: 'file/to/extract.zip',
dest: 'location/to/extract/files'
}
}
router
During extraction, we can dynamically change the filepaths of the zip's
contents via the router
option.
// This example requires using node's `path` module
var path = require('path');
// Inside grunt config
unzip: {
'using-router': {
// `router` receives the path that was used during zipping (e.g. css/bootstrap.css)
// The path it returns is where the file contents will be written to (e.g. dist/bootstrap.css)
router: function (filepath) {
// Route each file to dist/{{filename}}
var filename = path.basename(filepath);
return 'dist/' + filename;
},
// Collects all nested files in same directory
// css/bootstrap.css -> bootstrap.css, js/bootstrap.js -> bootstrap.js
src: 'bootstrap.zip',
dest: 'bootstrap/'
}
}
With the following options we can disable the CRC32 check or decode from base64 encoding:
zip: {
'skip-crc32-check': {
src: 'bootstrap.zip',
dest: 'bootstrap/',
checkCRC32: false
},
'decode-base64': {
src: ['file.js'],
dest: 'files.zip',
base64: true
}
}
zip
zip's router
allows for returning null
to skip over a file.
zip: {
'skip-files': {
// Skip over non-js files
router: function (filepath) {
// Grab the extension
var extname = path.extname(filepath);
// If the file is a .js, add it to the zip
if (extname === '.js') {
return filepath;
} else {
// Otherwise, skip it
return null;
}
},
src: ['js/main.js', 'css/main.css'],
dest: 'js-only.zip'
}
}
unzip
As with zip
, unzip
supports skipping extracting of files by returning null
in router
.
unzip: {
'skip-files': {
// Skip over non-css files
router: function (filepath) {
// Grab the extension
var extname = path.extname(filepath);
// If the file is a .css, extract it
if (extname === '.css') {
return filepath;
} else {
// Otherwise, skip it
return null;
}
},
src: ['bootstrap.css'],
dest: 'bootstrap-css/'
}
}
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint your code using grunt and test via npm test
.
Support this project and others by twolfson via gittip.
Copyright (c) 2013 Todd Wolfson Licensed under the MIT license.