I'm new to using gulp and am trying to create a gulpfile for my project.
My first task is to combine all my script and link tags present in index.html and replace them with only a single tag. To achieve this purpose, I'm making use of gulp-useref as below.
gulp.task('useref', ['clean'], function () {
return gulp.src(config.paths.app.src + 'index.html')
.pipe(gulpif('*.js', uglify()))
.pipe(gulpif('*.css', cleanCSS()))
.pipe(useref())
.pipe(gulp.dest(config.paths.dist.src))
});
This thing simply concatenates and minifies all my JS and CSS files and create a single script and link tag for them. All good till here.
Now, I wish to implement hashing to the combined JS and CSS files as well. For this, I'm using gulp-rev and gulp-rev-replace plugin like below.
gulp.task('useref', ['clean'], function () {
return gulp.src(config.paths.app.src + 'index.html')
.pipe(gulpif('*.js', uglify()))
.pipe(gulpif('*.css', cleanCSS()))
.pipe(useref())
.pipe(rev())
.pipe(revReplace())
.pipe(gulp.dest(config.paths.dist.src))
});
This also works good but for one small thing. It creates the hashed filenames not only for my JS and CSS files but for my index.html file as well as below.
Is there a way by which I can avoid the renaming of index.html file while still preserving the JS and CSS hashed filenames because my server would look for the index.html file in the folder rather than index-*********.html?
Thanks.
I'm not sure if this is the ideal way to solve the problem, but my solution was to apply gulpif to filter out css/js assets and then call rev(). revReplace should still update your index file to use the renamed css/js assets.
Essentially you can add the following pipe to your stream:
.pipe(gulpif(*.{js,css}, rev()))
Example based on your code:
gulp.task('useref', ['clean'], function () {
return gulp.src(config.paths.app.src + 'index.html')
.pipe(gulpif('*.js', uglify()))
.pipe(gulpif('*.css', cleanCSS()))
.pipe(useref())
.pipe(gulpif('*.{js,css}', rev()))
.pipe(revReplace())
.pipe(gulp.dest(config.paths.dist.src))
});
I had the same issue, but I was using gulp-rev-all instead of gulp-rev like you are.
My solution (workaround) will still work for you and others that are interested.
Essentially, you need to run another gulp-task after you 'rev' all of your files.
I use gulp-inject to grab the newly revisioned files, and inject them into my index.html file.
Step 1: use gulp-rev or gulp-rev-all in my case to revision your files and save them to your /dist folder.
Example:
gulp.task('rev', function () {
var css= gulp
.src(styles)
.pipe(concat('main.css'))
.pipe(RevAll.revision())
.pipe(gulp.dest('dist/css'));
var js = gulp
.src(scripts)
.pipe(concat('scripts.js'))
.pipe(RevAll.revision())
.pipe(gulp.dest('dist/js'));
return merge(css, js); //merge is from the gulp plugin merge-stream. It allows me to manipulate multiple streams in 1 task instead of having separate tasks.
});
Step 2:
Use gulp-inject to inject the newly created css/js file references into your index.html
Markup your index.html like this:
<!-- inject:css -->
<!-- endinject -->
<!-- inject:js -->
<!-- endinject -->
Step 3:
Use gulp-inject to grab the newly revisioned files and inject them into your index.html
gulp.task('inject',
function() {
var jsSource = gulp.src('./dist/js/*.js', { read: false });
var cssSource = gulp.src('./dist/css/*.css', { read: false });
return gulp.src('./index.html')
.pipe(inject(merge(jsSource, cssSource)))
.pipe(clean({force:true}))
.pipe(gulp.dest('./'));
});
In my project, I do NOT put the index.html in the dist folder. Maybe I should, but in this example/project I do not.
My folder structure
index.html
--/dist
---/js
---/css
---/views
gulp-inject documentation
gulp-rev-all documentation
Please let me know if there are any further questions, I would love to answer them
try
var ignoreIndexHtml = gulpfilter(['**/*', '!**/index.html'], { restore: true });
return gulp
.src('......')
.pipe('......')
.pipe('......')
.pipe(ignoreIndexHtml)
.pipe($.rev())
.pipe(ignoreIndexHtml.restore)
.pipe($.revReplace())
.pipe(gulp.dest('......'));
Related
i use angular-template-cache.
follow code exist for remove template cache in app module but i need to remove all templateCache with gulp on dev machine.
myApp.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
The best way to avoid template caching is revisioning your files.
Since you are using gulp, you can revision your files using gulp-rev or gulp-rev-all.
What is revisioning?
Static asset revisioning by appending content hash to filenames unicorn.css → unicorn-d41d8cd98f.css.
i.e., On every builds the filename changes and that way avoiding template caching.
You can revision every file including .html, .css, .js, images, videos etc.
Since gulp-rev-all is the latest and forked from gulp-rev, let's talk about gulp-rev-all only.
Revisioning using gulp-rev-all:
var revAll = require('gulp-rev-all');
if you want to neglect some files from revisioning, you can do that like this.
var rev = new revAll({dontRenameFile: [/^\/favicon.ico$/g, /^\/index.html/g]})
Consider all your files are in the folder dist and save the new revisioned files in the folder www.(You can save them in dist also. Considering www is your build directory.)
return gulp.src('dist/**')
.pipe(rev.revision())
.pipe(gulp.dest('www'))
Next, create a manifest file to map your files with the revisioned one. for that use .manifestFile() function. which returns a transform function that will filter out any existing files going through the pipe and will emit a new manifest file. Must be called after .revision().
.pipe(rev.manifest())
.pipe(gulp.dest('www/manifest'));
An asset manifest, mapping the original paths to the revisioned paths, will be written to www/manifest/rev-manifest.json:
{
"css/unicorn.css": "css/unicorn.098f6bcd.css",
"js/unicorn.js": "js/unicorn.273c2cin.js"
.....
.....
}
Complete code:
gulp.task('rev', () => {
var revAll = require('gulp-rev-all'),
rev = new revAll({dontRenameFile: [/^\/favicon.ico$/g, /^\/index.html/g]});
return gulp.src('dist/**')
.pipe(rev.revision())
.pipe(gulp.dest('www'))
.pipe(rev.manifest())
.pipe(gulp.dest('www/manifest'));
});
Read more about gulp-rev-all here
I've written a gulp task to rename files so that they can be versioned. The problem is that the filenames of the files that the index.html scripts reference are not changed.
For example, in my index.html:
<script src=pub/main_v1.js"></script>
But if you actually navigate through the build folder to the subdirectory pub, you will find main.js.
Here is the custom gulp task:
const gulpConcat = require('gulp-concat');
const gulpReplace = require('gulp-replace');
const version = require('./package.json').version;
gulp.task('version', function () {
var vsn = '_' + version + '.js';
gulp.src('scripts/**/*.js')
.pipe(gulpConcat(vsn))
.pipe(gulp.dest('./prodBuild'));
return gulp.src('./prodBuild/index.html', { base: './prodBuild' })
.pipe(gulpReplace(/* some regex */, /* append vsn */))
.pipe(gulp.dest('./prodBuild'));
});
What do I need to fix/add so that the original filename changes to match that in the script tag?
Note: According to the gulp-concat docs, I should be able to find the concated files at prodBuild/[vsn], where [vsn] is _v1.js. However, it is no where to be found.
Update: The files rename properly in index.html, but I can't seem to get the renaming of the original files to work. Here's a snapshot of my build directory:
prodBuild/
pub/
main.js
someDir/
subDirA/
// unimportant stuff
subDirB/
file2.js
file3.js
// ...other files and folders...
EDIT:
The issue is that you return only one of the two tasks. The first task is simply ignored by gulp, since it is not returned. A simple solutions: Split it into two tasks, and reference the one from the other, like in this SO answer.
Old Answer
This looks like a perfect case for the gulp-rename. You could simply pipe your scripts through gulp-rename, like this:
.pipe(rename(function (path) {
path.basename += vsn;
path.extname = ".js"
}))
Gulp concat is, AFAIK, made for the concatination of files, not particularly for the renaming of them.
I'm new with gulp and I'm trying to concatenate and minify my JS and CSS files. I'm using Jade.
gulpfile.js
gulp.task('jade2html', function() {
return gulp.src('app/*.jade')
.pipe(jade({pretty: true}))
.pipe(gulp.dest('dist'));
})
gulp.task('useref', function() {
return gulp.src('app/*.jade')
.pipe(useref())
.pipe(gulpIf('*.js', uglify()))
.pipe(gulpIf('*.css', cssnano()))
.pipe(gulp.dest('dist'))
})
index.jade
// build:css css/style.min.css
link(rel='stylesheet', href='/css/style.css')
link(rel='stylesheet', href='/css/print.css')
// endbuild
// build:js js/main.min.js
script(src='js/lib/a-library.js')
script(src='js/lib/another-lib.js')
script(src='js/main.js')
// endbuild
When I run my task useref and then I check my main.min.js or style.min.css the files are empty. So, I'm missing some step?
(When I don't use Jade and use just HTML everything works well).
You're piping Jade templates into useref(). However gulp-useref has no clue how to parse Jade. It only knows HTML.
That means you need to compile your Jade templates to HTML before you pipe them to useref(). Doing it in a separate task jade2html like you're trying to doesn't really work (at least not the way you're doing it). Besides you only really need one task to begin with:
gulp.task('useref', function() {
return gulp.src('app/*.jade')
.pipe(jade({pretty: true}))
.pipe(useref())
.pipe(gulpIf('*.js', uglify()))
.pipe(gulpIf('*.css', cssnano()))
.pipe(gulp.dest('dist'))
})
So I have a simple use case, and it seems very similar to the usecase described in the readme for https://github.com/jonkemp/gulp-useref.
I'm trying to generate a templates.js file with all of the Angular templates during the build. I am trying to do this and NOT have a templates.js file in my local project. So the idea was to merge the output of the template stream into the useref stream so that the resulting scripts.js file would contain all of the files indicated in my index file AND the generated templates ouput.
Here's what I have in the gulp task:
gulp.task('usemin:dist', ['clean:dist'], function() {
var templatesStream = gulp.src([
'./app/**/*.html',
'!./app/index.html',
'!./app/404.html'
]).pipe(templateCache({
module: 'myCoolApp'
}));
var assets = $useref.assets({
additionalStreams: [templatesStream]
});
return gulp.src('./app/index.html')
.pipe(assets)
.pipe(assets.restore())
.pipe($useref())
.pipe(gulp.dest('./dist/'));
});
Now this should allow me to merge the output of the templatesStream and turn it all into one scripts.js file, I think...
I've also tried having <script src="scripts/templates.js"></script> of many forms sitting in my index file to try and assist it. None seem to work.
Anyone else doing this same type of thing? Seems like a common use-case.
I was able to get this to work by looking closely at the test cases.
I now have a templates.js script tag on my index.html file which will 404 while in my local environment.
My gulp task looks like this:
gulp.task('useref:dist', ['clean:dist'], function() {
var templateStream = gulp.src([
'./app/**/*.html',
'!./app/index.html',
'!./app/404.html'
]).pipe(templateCache({
module: 'digitalWorkspaceApp'
}));
var assets = $useref.assets({
additionalStreams: [templateStream]
});
var jsFilter = $filter('**/*.js', {restore: true});
return gulp.src('./app/index.html')
.pipe(assets)
.pipe($useref())
.pipe(gulp.dest('./dist/'));
});
Immediately I can't really see the difference, but it may have all hinged on the addition of this non-existent file in my index.html.
I'm using gulp for common tasks on a front-end project. My goal is to fingerprint my JS+CSS assets and update my rev-manifest on deploy without interrupting anything. My tasks look something like this:
gulp.task("clean-js", function() {
return del(["./public/shop-assets/javascripts/production/*.js", "./rev-manifest.json"], function(){
console.log("Production JS folder and rev-manifest JSON cleared");
});
});
gulp.task("clean-css", function() {
return del(["./public/shop-assets/stylesheets/production/*.css", "./rev-manifest-css.json"], function(){
console.log("Production CSS folder and rev-manifest-css JSON cleared");
});
});
gulp.task('js:prod',['clean-js'], function() {
return gulp.src("./public/shop-assets/javascripts/*.js/")
.pipe(uglify())
.pipe(rev())
.pipe(gulp.dest("./public/shop-assets/javascripts/production/"))
.pipe(rev.manifest())
.pipe(gulp.dest("."));
});
gulp.task('css:minify',["clean-css"], function() {
return gulp.src("./public/shop-assets/stylesheets/*.css")
.pipe(minifyCss())
.pipe(rev())
.pipe(gulp.dest("./public/shop-assets/stylesheets/production/"))
.pipe(rev.manifest())
.pipe(rename("rev-manifest-css.json"))
.pipe(gulp.dest("."));
});
This does what I expect-it clears the manifest files each time, then rewrites them. What I would like to do is merely replace the contents of each manifest after I bundled + minified my JS +CSS files without blocking the user experience.
Also, in my express routes file, I am sending the manifest on down so I can then include the scripts/stylesheets like so:
script(src="/shop-assets/javascripts/production/#{assetPathJS}")
But when I delete and rewrite the manifest files, users will see an intermittent failure.
Does anyone have any tips on this matter? Most examples I have seen have only one entrypoint for the gulpfile. Thanks!
I wound up doing something like this in my routes files:
var jsPaths = ServerConfig.assetPaths(["cleanout.js", "hiw.js", "do_good.js"], revManifestJS, "javascripts/");
where that function assetPaths resolves the pathname based on the environment. Simple than I thought.