ember-cli-deploy-compress
Advanced tools
Comparing version 0.1.1 to 0.2.0
128
index.js
@@ -9,7 +9,8 @@ /*eslint-env node*/ | ||
var caniuse = require('caniuse-api'); | ||
var denodeify = require('rsvp').denodeify; | ||
var RSVP = require('rsvp') | ||
var denodeify = RSVP.denodeify; | ||
var renameFile = denodeify(fs.rename); | ||
var DeployPluginBase = require('ember-cli-deploy-plugin'); | ||
var validCompressions = ['best', 'gzip', 'brotli']; | ||
@@ -30,2 +31,3 @@ module.exports = { | ||
ignorePattern: null, | ||
compression: ['best'], | ||
zopfli: false, | ||
@@ -43,21 +45,3 @@ keep: false, | ||
this._super.configure.call(this, context); | ||
if (this.canUseBrotli) { | ||
this.log("Using brotli for compression", { verbose: true }); | ||
let lib = require('iltorb'); | ||
this.buildCompressor = function() { | ||
return lib.compressStream({ quality: 11 }); | ||
} | ||
} else if (this.readConfig('zopfli')) { | ||
this.log("Using zopfli for compression", { verbose: true }); | ||
let lib = this.project.require('node-zopfli'); | ||
this.buildCompressor = function() { | ||
return lib.createGzip({ format: 'gzip' }); | ||
} | ||
} else { | ||
this.log("Using standard gzip for compression", { verbose: true }); | ||
let lib = require('zlib'); | ||
this.buildCompressor = function() { | ||
return lib.createGzip({ format: 'gzip' }); | ||
} | ||
} | ||
this._validateCompressionConfig(); | ||
}, | ||
@@ -73,3 +57,2 @@ | ||
var keep = this.readConfig('keep'); | ||
var outputProp = this.canUseBrotli ? 'brotliCompressedFiles' : 'gzippedFiles'; | ||
@@ -79,17 +62,26 @@ this.log('compressing `' + filePattern + '`', { verbose: true }); | ||
return this._compressFiles(distDir, distFiles, filePattern, ignorePattern, keep) | ||
.then(function(compressedFiles) { | ||
self.log(`compressed ${compressedFiles.length} files ok`, { verbose: true }); | ||
if (keep) { | ||
self.log('keep is enabled, added compressed files to `context.distFiles`', { verbose: true }); | ||
return { | ||
distFiles: [].concat(compressedFiles), // needs to be a copy | ||
[outputProp]: compressedFiles | ||
}; | ||
} | ||
return { [outputProp]: compressedFiles }; | ||
}) | ||
.catch(this._errorMessage.bind(this)); | ||
let promises = { gzippedFiles: [], brotliCompressedFiles: [] }; | ||
if (this._mustCompressWithBrotli()) { | ||
this.log('Compressing files with brotli', { verbose: true }); | ||
promises.brotliCompressedFiles = this._compressFiles(distDir, distFiles, filePattern, ignorePattern, keep, 'brotli'); | ||
} | ||
if (this._mustCompressWithGzip()) { | ||
this.log('Compressing files with gzip', { verbose: true }); | ||
promises.gzippedFiles = this._compressFiles(distDir, distFiles, filePattern, ignorePattern, keep, 'gzip'); | ||
} | ||
return RSVP.hash(promises).then(function({ gzippedFiles, brotliCompressedFiles }) { | ||
self.log(`compressed ${gzippedFiles.length + brotliCompressedFiles.length} files ok`, { verbose: true }); | ||
if (keep) { | ||
self.log('keep is enabled, added compressed files to `context.distFiles`', { verbose: true }); | ||
return { | ||
distFiles: [].concat(gzippedFiles).concat(brotliCompressedFiles), // needs to be a copy | ||
gzippedFiles, | ||
brotliCompressedFiles | ||
}; | ||
} else { | ||
return { gzippedFiles, brotliCompressedFiles }; | ||
} | ||
}).catch(this._errorMessage.bind(this)); | ||
}, | ||
_compressFiles(distDir, distFiles, filePattern, ignorePattern, keep) { | ||
_compressFiles(distDir, distFiles, filePattern, ignorePattern, keep, format) { | ||
var filesToCompress = distFiles.filter(minimatch.filter(filePattern, { matchBase: true })); | ||
@@ -101,23 +93,18 @@ if (ignorePattern != null) { | ||
} | ||
return RSVP.map(filesToCompress, this._compressFile.bind(this, distDir, keep)); | ||
return RSVP.map(filesToCompress, this._compressFile.bind(this, distDir, keep, format)); | ||
}, | ||
_compressFile(distDir, keep, filePath) { | ||
_compressFile(distDir, keep, format, filePath) { | ||
var self = this; | ||
var fullPath = path.join(distDir, filePath); | ||
var fileExtension = this.canUseBrotli ? '.br' : '.gz'; | ||
var fileExtension = format === 'brotli' ? '.br' : '.gz'; | ||
var outFilePath = fullPath + fileExtension; | ||
return new RSVP.Promise(function(resolve, reject) { | ||
var inp = fs.createReadStream(fullPath); | ||
var out = fs.createWriteStream(outFilePath); | ||
inp.pipe(self.buildCompressor()).pipe(out); | ||
inp.on('error', function(err){ | ||
reject(err); | ||
}); | ||
out.on('error', function(err){ | ||
reject(err); | ||
}); | ||
out.on('finish', function(){ | ||
resolve(); | ||
}); | ||
let compressor = self[format + 'Compressor'](); | ||
inp.pipe(compressor).pipe(out); | ||
inp.on('error', function(err){ reject(err); }); | ||
out.on('error', function(err){ reject(err); }); | ||
out.on('finish', function(){ resolve(); }); | ||
}).then(function(){ | ||
@@ -137,5 +124,46 @@ if(!keep) { | ||
}, | ||
gzipCompressor() { | ||
if (this.readConfig('zopfli')) { | ||
return this.project.require('node-zopfli').createGzip({ format: 'gzip' }) | ||
} else { | ||
return require('zlib').createGzip({ format: 'gzip' }); | ||
} | ||
}, | ||
brotliCompressor() { | ||
return require('iltorb').compressStream({ quality: 11 }); | ||
}, | ||
_mustCompressWithBrotli() { | ||
let compression = this._getCompression(); | ||
return compression.indexOf('brotli') > -1 || (compression.indexOf('best') > -1 && this.canUseBrotli); | ||
}, | ||
_mustCompressWithGzip() { | ||
let compression = this._getCompression(); | ||
return compression.indexOf('gzip') > -1 || (compression.indexOf('best') > -1 && !this.canUseBrotli); | ||
}, | ||
_errorMessage(error) { | ||
this.log(error, { color: 'red' }); | ||
return RSVP.reject(error); | ||
}, | ||
_validateCompressionConfig() { | ||
let compression = this._getCompression(); | ||
compression.forEach(function (value) { | ||
if (validCompressions.indexOf(value) === -1) { | ||
throw new Error(`The "compression" config option has a wrong value: "${value}"`); | ||
} | ||
}); | ||
if (compression.indexOf('best') > -1 && compression.length > 1) { | ||
throw new Error('The "compression" config cannot combine "best" with other values'); | ||
} | ||
if (compression.length > 1 && !this.readConfig('keep')) { | ||
throw new Error('You cannot compress using both brotli and gzip unless you enable the `keep` option'); | ||
} | ||
}, | ||
_getCompression() { | ||
let compression = this.readConfig('compression'); | ||
if (!Array.isArray(compression)) { | ||
compression = [compression]; | ||
} | ||
return compression; | ||
} | ||
@@ -142,0 +170,0 @@ }); |
{ | ||
"name": "ember-cli-deploy-compress", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "Ember CLI Deploy plugin to compress files in gzip or brotli automatically depending on supported browsers", | ||
@@ -5,0 +5,0 @@ "directories": { |
@@ -8,2 +8,5 @@ # ember-cli-deploy-compress | ||
When brotli is supported you tipically get around ~17% reduction on the file size of the average javascript files, and | ||
even bigger in html and css files. | ||
## What is an ember-cli-deploy plugin? | ||
@@ -70,6 +73,18 @@ | ||
Keep original file and write compressed data to `originalFile.gz` (or `originalFile.br`) | ||
Keep original file and write compressed data to `originalFile.gz` (or `originalFile.br`, or both) | ||
*Default:* `false` | ||
### Compression | ||
It determines the compression algorithm used. | ||
*Default:* `["best"]` | ||
When the value is `["best"]`, it will automatically decide wether it can use brotli or has to stick | ||
to gzip automatically. | ||
If the users want to force one algorithm, they force it passing `compression: ["brotli"]`. | ||
Also, users can force the addon to use both algorithms simultaneously with `compression: ["gzip", "brotli"]`. When both algorithms are used, the user has to also enable the `keep` option. | ||
## Prequisites | ||
@@ -76,0 +91,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
220588
10
198
111