├── test ├── app.test.js ├── test.manifest.json └── test.js ├── .gitignore ├── example ├── images │ ├── doge.jpg │ └── fb-logo-blue.png ├── dist │ ├── rev-manifest.json │ ├── images │ │ ├── doge-d9409101bb.jpg │ │ └── fb-logo-blue-395d0c25f2.png │ └── webpack-assets.json ├── app.js ├── gulpfile.js └── webpack.config.js ├── package.json ├── index.js └── README.md /test/app.test.js: -------------------------------------------------------------------------------- 1 | var doge = require('../example/images/doge'); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | test/bundle.js 4 | example/dist 5 | -------------------------------------------------------------------------------- /example/images/doge.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adjavaherian/gulp-rev-loader/HEAD/example/images/doge.jpg -------------------------------------------------------------------------------- /example/images/fb-logo-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adjavaherian/gulp-rev-loader/HEAD/example/images/fb-logo-blue.png -------------------------------------------------------------------------------- /test/test.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "doge.jpg": "doge-d9409101bb.jpg", 3 | "fb-logo-blue.png": "fb-logo-blue-395d0c25f2.png" 4 | } -------------------------------------------------------------------------------- /example/dist/rev-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "doge.jpg": "doge-d9409101bb.jpg", 3 | "fb-logo-blue.png": "fb-logo-blue-395d0c25f2.png" 4 | } -------------------------------------------------------------------------------- /example/dist/images/doge-d9409101bb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adjavaherian/gulp-rev-loader/HEAD/example/dist/images/doge-d9409101bb.jpg -------------------------------------------------------------------------------- /example/dist/images/fb-logo-blue-395d0c25f2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adjavaherian/gulp-rev-loader/HEAD/example/dist/images/fb-logo-blue-395d0c25f2.png -------------------------------------------------------------------------------- /example/app.js: -------------------------------------------------------------------------------- 1 | // run "gulp" here in the example directory, and check the output of ./dist 2 | 3 | var fb = require('images/fb-logo-blue.png'); 4 | var doge = require('images/doge'); 5 | -------------------------------------------------------------------------------- /example/dist/webpack-assets.json: -------------------------------------------------------------------------------- 1 | {"errors":[],"warnings":[],"version":"2.4.1","hash":"bd012d34f40ba0e51adb","publicPath":"/dist/","assetsByChunkName":{"app":"app.bundle.bd012d34f40ba0e51adb.js"},"assets":[{"name":"app.bundle.bd012d34f40ba0e51adb.js","size":4673,"chunks":[0],"chunkNames":["app"],"emitted":true},{"name":"webpack-assets.json","size":0,"chunks":[],"chunkNames":[]}],"entrypoints":{"app":{"chunks":[0],"assets":["app.bundle.bd012d34f40ba0e51adb.js"]}},"children":[]} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-rev-loader", 3 | "version": "2.0.0", 4 | "description": "webpack loader to work in tandem with gulp-rev", 5 | "homepage": "https://github.com/adjavaherian/gulp-rev-loader", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "mocha test/test.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/adjavaherian/gulp-rev-loader" 13 | }, 14 | "keywords": [ 15 | "gulp-rev", 16 | "webpack", 17 | "webpack-loader" 18 | ], 19 | "author": "@adjavaherian", 20 | "license": "MIT", 21 | "dependencies": { 22 | "gulp-util": "^3.0.8", 23 | "loader-utils": "^1.1.0", 24 | "mime": "^1.3.4" 25 | }, 26 | "devDependencies": { 27 | "gulp": "^3.9.1", 28 | "gulp-rev": "^7.1.2", 29 | "run-sequence": "^1.2.2", 30 | "stats-webpack-plugin": "^0.6.0", 31 | "webpack": "^2.4.0", 32 | "webpack-stats-plugin": "^0.1.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /example/gulpfile.js: -------------------------------------------------------------------------------- 1 | //webpack.js 2 | //main webpack gulp task 3 | 4 | var gulp = require('gulp'); 5 | var runSequence = require('run-sequence'); 6 | var webpack = require('webpack'); 7 | var path = require('path'); 8 | var gutil = require('gulp-util'); 9 | var rev = require('gulp-rev'); 10 | var devConfig = require(path.join(__dirname, 'webpack.config.js')); 11 | 12 | function onBuild(done) { 13 | return function(err, stats) { 14 | if (err) { 15 | gutil.log('Error', err); 16 | if (done) { 17 | done(); 18 | } 19 | } else { 20 | Object.keys(stats.compilation.assets).forEach(function(key) { 21 | gutil.log('Webpack: output ', gutil.colors.green(key)); 22 | }); 23 | gutil.log('Webpack: ', gutil.colors.blue('finished ', stats.compilation.name)); 24 | if (done) { 25 | done(); 26 | } 27 | } 28 | } 29 | } 30 | 31 | gulp.task('default', function(callback) { 32 | runSequence( 33 | 'images', 34 | 'webpack-build', 35 | callback); 36 | }); 37 | 38 | //rev images 39 | gulp.task('images', function() { 40 | return gulp.src('images/**/*.+(jpg|jpeg|ico|png|gif|svg)') 41 | .pipe(rev()) 42 | .pipe(gulp.dest('dist/images')) 43 | .pipe(rev.manifest()) 44 | .pipe(gulp.dest('dist')); 45 | }); 46 | 47 | //build 48 | gulp.task('webpack-build', function(done) { 49 | webpack(devConfig).run(onBuild(done)); 50 | }); 51 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | //manifest loader for replacing rev'd sources 2 | var loaderUtils = require('loader-utils'); 3 | var path = require('path'); 4 | var mime = require('mime'); 5 | var gutil = require('gulp-util'); 6 | 7 | module.exports = function(content) { 8 | 9 | this.cacheable && this.cacheable(); 10 | var callback = this.async(); 11 | 12 | var options = loaderUtils.getOptions(this); 13 | var manifest = require(path.join(options.outputDir, options.manifest)); 14 | var relativeSplit = options.relativeSplit || '/'; 15 | var fileName = this.resourcePath.split(relativeSplit).slice(-1) || ''; 16 | var prefix = options.prefix || ''; 17 | var result = manifest[fileName] ? prefix + '/' + manifest[fileName] : ''; 18 | 19 | var limit = 0; 20 | if (options.limit) { 21 | limit = parseInt(options.limit, 10); 22 | } 23 | 24 | var mimetype = options.mimetype || options.minetype || mime.lookup(this.resourcePath); 25 | 26 | if (limit <= 0 || content.length < limit) { 27 | if (options.debug) { 28 | gutil.log('manifest loader:', gutil.colors.gray(fileName), '>', gutil.colors.green('to base64')); 29 | } 30 | callback(null, "module.exports = " + JSON.stringify("data:" + (mimetype ? mimetype + ";" : "") + "base64," + content.toString("base64"))); 31 | } else { 32 | if (options.debug) { 33 | gutil.log('manifest loader:', gutil.colors.gray(fileName), '>', gutil.colors.green(result)); 34 | } 35 | callback(null, 'module.exports = "' + result + '"'); 36 | } 37 | 38 | 39 | }; 40 | 41 | module.exports.raw = true; 42 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var path = require('path'); 3 | var assert = require('assert'); 4 | var webpack = require('webpack'); 5 | var fs = require('fs'); 6 | 7 | var testConfig = { 8 | entry: path.join(__dirname, 'app.test.js'), 9 | resolve: { 10 | extensions: ['.json', '.jpg'] 11 | }, 12 | output: { 13 | filename: path.join('./test', 'bundle.js'), 14 | libraryTarget: 'commonjs2' 15 | }, 16 | module: { 17 | loaders: [ 18 | { 19 | test: /\.json$/, 20 | loaders: ['json-loader'] 21 | }, 22 | { 23 | test: /\.(jpe?g|png|gif|svg)$/i, 24 | loader: path.join(__dirname, '../', 'index'), 25 | query: { 26 | debug: true, 27 | limit: 5000, 28 | hash: 'sha512', 29 | digest: 'hex', 30 | relativeSplit: 'images/', 31 | prefix: 'images', 32 | manifest: 'test.manifest.json', 33 | outputDir: __dirname 34 | } 35 | } 36 | ] 37 | } 38 | }; 39 | 40 | 41 | it('should export reved files as is', function (cb) { 42 | 43 | webpack(testConfig, function onCompilationFinished(err, stats) { 44 | 45 | if (err) { 46 | return cb(err); 47 | } 48 | if (stats.hasErrors()) { 49 | return cb(stats.compilation.errors[0]); 50 | } 51 | if (stats.hasWarnings()) { 52 | return cb(stats.compilation.warnings[0]); 53 | } 54 | 55 | fs.readFile(path.join(__dirname, 'bundle.js'), function (err, data) { 56 | if (err) throw err; 57 | assert(data.indexOf('images/doge-d9409101bb.jpg') > 0); 58 | cb(); 59 | }); 60 | 61 | }); 62 | 63 | }); 64 | -------------------------------------------------------------------------------- /example/webpack.config.js: -------------------------------------------------------------------------------- 1 | //webpack.config.js 2 | //main webpack config 3 | var webpack = require('webpack'); 4 | var path = require('path'); 5 | var StatsPlugin = require('stats-webpack-plugin'); 6 | //var manifestParams = '?debug=false&limit=5000&hash=sha512&digest=hex&relativeSplit=images/&prefix=images&manifest=rev-manifest&outputDir=' + path.join(__dirname, 'dist'); 7 | 8 | module.exports = { 9 | name: 'example', 10 | context: __dirname, 11 | node: { 12 | console: true 13 | }, 14 | entry: { 15 | app: path.join(__dirname, 'app.js') 16 | }, 17 | output: { 18 | path: path.join(__dirname, 'dist'), 19 | publicPath: '/dist/', 20 | filename: '[name].bundle.[hash].js' 21 | }, 22 | resolve: { 23 | alias: { 24 | node_modules: path.resolve(__dirname, 'node_modules'), 25 | images: path.resolve(__dirname, 'images') 26 | }, 27 | modules: ['node_modules'], 28 | extensions: ['.json', '.js', '.jsx', '.scss', '.png', '.jpg', '.jpeg', '.gif'] 29 | }, 30 | module: { 31 | loaders: [ 32 | { 33 | test: /\.json$/, 34 | loaders: ['json-loader'] 35 | }, 36 | { 37 | test: /\.(jpe?g|png|gif|svg)$/i, 38 | loader: path.join(__dirname, '../', 'index'), 39 | query: { 40 | debug: true, 41 | limit: 5000, 42 | hash: 'sha512', 43 | digest: 'hex', 44 | relativeSplit: 'images/', 45 | prefix: 'images', 46 | manifest: 'rev-manifest', 47 | outputDir: path.join(__dirname, 'dist') 48 | } 49 | } 50 | ] 51 | }, 52 | plugins: [ 53 | new StatsPlugin(path.join('webpack-assets.json'), { 54 | assetsByChunkName: true, 55 | source: false, 56 | reasons: false, 57 | modules: false, 58 | chunks: false 59 | }) 60 | ], 61 | bail: true 62 | }; 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gulp Rev Loader 2 | This Webpack 2.x loader is designed to work in tandem with gulp-rev :punch:. 3 | For example, you might have a build process that uses gulp and [gulp-rev](https://github.com/sindresorhus/gulp-rev) to tag hashes on your rev'd images or files. Gulp-rev creates a manifest of the processed files. Using gulp-rev-loader checks your files against the rev-manifest and re-writes them to their rev'd paths at webpack compile time. You can also update path prefixes and hash out the file content based on file size. 4 | 5 | Note: People using Webpack 1.x can still use the previous version of this loader. 6 | 7 | ## Install 8 | `npm install gulp-rev-loader` 9 | 10 | ## Configure a gulp-rev task 11 | ```javascript 12 | //gulpfile.js 13 | var gulp = require('gulp'); 14 | var rev = require('gulp-rev'); 15 | 16 | gulp.task('default', function() { 17 | return gulp.src('images/**/*.+(jpg|jpeg|ico|png|gif|svg)') 18 | .pipe(rev()) 19 | .pipe(gulp.dest('dist/images')) 20 | .pipe(rev.manifest()) 21 | .pipe(gulp.dest('dist')); 22 | }); 23 | ``` 24 | 25 | ## Configure the webpack loader 26 | ```javascript 27 | //webpack.config.js 28 | var webpack = require('webpack'); 29 | var path = require('path'); 30 | 31 | module.exports = { 32 | name: 'example', 33 | entry: { 34 | index: path.join(__dirname, 'app.js') 35 | }, 36 | output: { 37 | path: path.join(__dirname, 'dist'), 38 | publicPath: '/dist/', 39 | filename: '[name].bundle.[hash].js' 40 | }, 41 | resolve: { 42 | extensions: ['.json', '.js', '.jsx', '.scss', '.png', '.jpg', '.jpeg', '.gif'] 43 | }, 44 | module: { 45 | loaders: [ 46 | { 47 | test: /\.json$/, 48 | loaders: ['json-loader'] 49 | }, 50 | { 51 | test: /\.(jpe?g|png|gif|svg)$/i, 52 | loader: 'gulp-rev-loader', 53 | query: { 54 | debug: true, 55 | limit: 5000, 56 | hash: 'sha512', 57 | digest: 'hex', 58 | relativeSplit: 'images/', 59 | prefix: 'images', 60 | manifest: 'rev-manifest', 61 | outputDir: path.join(__dirname, 'dist') 62 | } 63 | } 64 | ] 65 | }, 66 | }; 67 | 68 | //optionally, use string of url params as options 69 | //var manifestParams = '?debug=false&limit=5000&hash=sha512&digest=hex&relativeSplit=images/&prefix=images&manifest=rev-manifest&outputDir=' + path.join(__dirname, 'dist'); 70 | ``` 71 | 72 | ## Options 73 | ```javascript 74 | debug: true, //bool to output logging info 75 | limit: 5000, //int to limit min k before hashing file src 76 | hash: 'sha512', //string hash type 77 | digest: 'hex', //string digest type 78 | relativeSplit: 'images/', //string to relative split point 79 | prefix: 'images', //string to prefix manifest replacements 80 | manifest: 'rev-manifest', //string path to manifest 81 | outputDir: path.join(__dirname, 'dist') //string path to output directory 82 | ``` 83 | 84 | ## Running the example 85 | `cd gulp-rev-loader/examples && gulp` 86 | 87 | ## Testing 88 | `npm install -g mocha && npm test` 89 | --------------------------------------------------------------------------------