How to make gulp work with files without extension - gulp

I want to make gulp work with files without extension also. I tried to do it the following ways:
function someTask() {
return gulp.src('./src/**/*.{html,,xml,txt}')
.pipe(gulp.dest('./build'));
}
function someTask() {
return gulp.src('./src/**/*.{html,!*,xml,txt}')
.pipe(gulp.dest('./build'));
}
function someTask() {
return gulp.src('./src/**/*.{html,[^*],xml,txt}')
.pipe(gulp.dest('./build'));
}
but I haven't got any results. Any suggestions?

I am still trying to find a better answer, but one route is to get all the files and then eliminate the extentions you don't want. Like
var debug = require('gulp-debug'); // nice, will list all the files in the stream
return gulp.src(['./src/**/*', '!./src/**/*.{js,png}'])
.pipe(debug())
.pipe(gulp.dest('./build'));
So here {js,png} list the possible file extensions in your src directories you don't want.
Hopefully there is a better answer.
[EDIT]: Maybe there is, try this:
return gulp.src(['./src/**/*.{html,xml,txt}', './src/**/!(*\.*)'])
This part ./src/**/!(*\.*) appears to match only files with no . in them, i.e., no extention.

Related

Glob watch multiple files, process one

I use Gulp 4 with gulp-sass. What I try to do is the following.
The code I provide here is just a fragment of the whole code, to show the important parts.
The watch should like it does, watch all .scss files.
In style(), only the current file is going to be processed.
If I save custom/components/header/header.scss, then only custom/components/header/header.scss should be processed, not all files.
The saved file should then have a filename like assets/css/dist/header/header.css
Both src and dest is unknown in this case because I don't have a single file to grab on to.
I see now that I also need to remove custom/components from the dest, but the important thing is that I can get the current file to start working with that.
gulp.watch('custom/components/**/*.scss', style);
function style() {
return gulp
.src()
.pipe(sass())
.on('error', sass.logError)
.pipe(gulp.dest('assets/css/dist'));
}
I just figure it out. It's possible to do it like this.
let watcher = gulp.watch(css.watch);
watcher.on('change', function(path) {
console.log(path);
style();
}

How to push a gulp pipeline onto another

I would like to process a series of folders through the build pipeline. For each folder I start another gulp pipeline that will create some source files. Finally I'd like to pipe them all together through the zip() plugin to produce a final artifact.
The following pseudocode shows my approach. However, I cannot push the result of the gulp.src to the current pipeline.
return gulp.src(someFolder)
.pipe(through(function(folder, enc, cb){
// how to add the result of the following line to my
// own pipeline????
this.push(gulp.src(path.join(folder, "whatever"))
.pipe(somePlugin()));
}))
.pipe(zip(....))
.pipe(gulp.dest(....));
Any hints how to combine those pipelines together?
This is exactly what gulp-foreach is intended for. Using that the equivalent of the code you posted would look like this:
var foreach = require('gulp-foreach');
return gulp.src(someFolder)
.pipe(foreach(function(stream, folder) {
return gulp.src(path.join(folder.path, "whatever"))
.pipe(somePlugin());
}))
.pipe(zip(....))
.pipe(gulp.dest(....));
Note that the above will discard all files from the original gulp.src(someFolder). They will not be included in the ZIP. If you want to keep those around as well you can use merge-stream:
var foreach = require('gulp-foreach');
var merge = require('merge-stream');
return gulp.src(someFolder)
.pipe(foreach(function(stream, folder) {
return merge(stream,
gulp.src(path.join(folder.path, "whatever"))
.pipe(somePlugin()));
}))
.pipe(zip(....))
.pipe(gulp.dest(....));

How to use gulp to organize the different js file in different html?

How to use gulp to organize the different js file in different html?
is the only way I can do is to define each page to gulp task ? Or gulp have a better way can detect file automatically?
This is my situation below.
I have two html 'index.html','content.html'
index.html need plugin_A.js
content.html need plugin_B.js
And my gulp file:
gulp.task('index_concat', function() {
return gulp.src('./app/js/plugin_A.js')
.pipe(concat('index.js'))
.pipe(gulp.dest('./build/js/'));
});
gulp.task('content_concat', function() {
return gulp.src('./app/js/plugin_B.js')
.pipe(concat('content.js'))
.pipe(gulp.dest('./build/js/'));
});
If I had 100 pages, the tasks were too big!!!
I think this is a stupid way to define each page, but I have no idea how to get better. Please give me some advice.
You could use some name convention for your plugins like pluginName_index.js and pluginName_content.js . So you be able to do something like that:
function yourFunction(pluginName,targetName){
return gulp.src('./app/js/'+pluginName)
.pipe(concat(targetName))
.pipe(gulp.dest('./build/js/'));
}
fs.readdirSync('.app/js/pluginFolder')
.filter(function(fileName) {
var fileNameParts = fileName.split('_');
yourFunction(fileName,fileNameParts[1]);
});

How to make gulp-newer work with gulp-rev?

The setup is as simple as this:
gulp.task('rev-js', function() {
return gulp.src('/js/main.js, {base: '.'})
.pipe(newer('_build'))
.pipe(rev())
.pipe(gulp.dest('_build'))
.pipe(rev.manifest())
.pipe(gulp.dest('_build/rev/js'));
});
gulp-newer obviously doesn't work here since the destination file gets a different name. Any workaround to make gulp-newer (or gulp-changed) work in this case?
In the gulp-newer options documentation I read that it supports passing in a configuration object instead of the destination. In that configuration object you can specify a mapping function from old to new files. So instead of
newer('_build')
you can write
newer({dest: '_build', map: mappingFn})
The mapping function takes the relative name of the file and expects it to return a translated name - see the index.js file. You can define a function that uses the previously generated rev-manifest.json manifest to look up the correct filename. Id put something along these lines in your build script (not tested):
gulp.task('rev-js', function() {
// get the existing manifest
// todo: add logic to skip this if file doesn't exist
var currentManifest = JSON.parse(fs.readFileSync('rev-manifest.json', 'utf8'));
// mapping function for gulp-newer
function mapToRevisions(relativeName) {
return currentManifest[relativeName]
}
return gulp.src('/js/main.js, {base: '.'})
.pipe(newer({dest: '_build', map: mapToRevisions}))
.pipe(rev())
.pipe(gulp.dest('_build'))
.pipe(rev.manifest())
.pipe(gulp.dest('_build/rev/js'));
});
May I suggest gulp-newy in which you can manipulate the path and filename in your own function. Then, just use the function as the callback to the newy(). This gives you complete control of the files you would like to compare.
This will allow 1:1 or many to 1 compares.
newy(function(projectDir, srcFile, absSrcFile) {
// do whatever you want to here.
// construct your absolute path, change filename suffix, etc.
// then return /foo/bar/filename.suffix as the file to compare against
}

Gulp and Bower-files: Get js-files for developing and for production

I am having tried to read tutorials and browse other questions, but cannot find a good answer to how I can set up gulp so that I get javascript-files from (already installed) bower-components for development and for production.
First I tried a simple way. For development:
gulp.task('vendorScriptsDevelopment', function() {
return gulp.src(['bower_components/jquery/dist/jquery.js',
'bower_components/**/*.js',
'!bower_components/**/*.min.js'])
.pipe(filter('*.js'))
.pipe(concat('vendor-scripts.js'))
.pipe(gulp.dest('dev'))
});
And similar for production:
gulp.task('vendorScriptsProduction', function() {
return gulp.src(['bower_components/jquery/dist/jquery.min.js',
'bower_components/**/*.min.js'])
.pipe(filter('*.js'))
.pipe(concat('vendor-scripts.js'))
.pipe(gulp.dest('prod'))
});
I included jquery specifically first, since other plugins often depend on it.
But then I realize that some bower packages includes a lot of files, also various javascript-files that I do not want (I just want "the one" that typically also has a CDN-option (and are offered in two versions, normal js and minimized)).
One tutorial I have read uses the main-bower-files plugin for the development part, but then it goes on in the wrong direction and wants to make a minified version itself (as I understand, it is always best to use the packages included minified version, as that is optimized from the developers of the plugin).
How can I set up my two Gulp tasks so that they works as intended? Or am I forced to included all the files manually (like I included jquery manually in my examples)?
Ok, since nobody has replied, here is my attempt to answer my own question.
I created a function that generates an array of the filenames that I want. This uses main-bower-files and filters out the .js-files. If this is development, then that's it. If it is production, then I just change the file extension from .js to .min.js (and for safety checks if that file exists).
var concat = require('gulp-concat');
var mainBowerFiles = require('main-bower-files');
var fs = require('fs');
var vendorScripts = function (minified) {
var scripts = mainBowerFiles().filter(function (filename) {
return filename.match(/.+\.js$/)
});
if (minified) {
scripts = scripts.map(function (orgFilename) {
var minFilename = orgFilename.replace(/^(.+)\.js$/, '$1.min.js');
if (fs.existsSync(minFilename)) {
return minFilename
}
return orgFilename;
});
}
return scripts;
};
gulp.task('vendorScriptsDevelopment', function() {
return gulp.src(vendorScripts())
.pipe(concat('vendor-scripts.js'))
.pipe(gulp.dest('dev'))
});
gulp.task('vendorScriptsProduction', function() {
return gulp.src(vendorScripts(true))
.pipe(concat('vendor-scripts.js'))
.pipe(gulp.dest('dist'))
});
I should change my function to handle other assets too, like css.
If somebody has a better approach, I would be very glad for a suggestion!
Here is my solution for your problem enjoy:
Create a vendors.json file in your sources folder. Edit the file and make path to relevant files you want to include in the production folder. For example:
{
"js" : [
"lib/jquery/dist/jquery.js",
"lib/lodash/lodash.js",
"lib/angular/angular.js",
"lib/angular-sanitize/angular-sanitize.js",
"lib/angular-ui-router/release/angular-ui-router.js",
"lib/angular-ui-utils/ui-utils.js",
"lib/angular-bootstrap/ui-bootstrap-tpls.js",
"lib/chartjs/Chart.js",
"lib/pnotify/pnotify.core.js",
"lib/pnotify/pnotify.buttons.js",
"lib/angular-pnotify/src/angular-pnotify.js",
"lib/angular-prompt/dist/angular-prompt.js",
"lib/angular-mocks/angular-mocks.js"
],
"css" : [
"lib/bootstrap/dist/css/bootstrap.css",
"lib/bootstrap-rtl/dist/css/bootstrap-rtl.css",
"lib/bootstrap/dist/css/bootstrap-theme.css",
"lib/font-awesome/css/font-awesome.css",
"lib/pnotify/pnotify.core.css",
"lib/pnotify/pnotify.buttons.css"
],
"statics" : [
"lib/font-awesome/fonts/*"
]
}
Then in the gulpFile.js add this:
var sources = {
get 'vendor.js'(){
return getVendorSources().js;
},
get 'vendor.css'(){
return getVendorSources().css;
},
get 'vendor.statics'(){
return getVendorSources().statics;
}
};
function getVendorSources(){
return JSON.parse(fs.readFileSync('yourSourcesFolder/vendor.json', 'utf-8'));
}
gulp.task('vendor.css', function() {
return gulp.src(sources['vendor.css'])
.pipe(changed(paths.dist))
.pipe(gulp.dest(paths.dist));
});
and so on for the js and static files tasks.