I'm new comer in Gulp, and i got stock when i try to output my files to their parent's path.
My directories like this:
app/page_a/less/a.less
app/page_a/css
My goal is:
app/page_a/less/a.less
app/page_a/css/a.css
Here's what i'm doing:
I use ** because i want to match all of my page_* module.
gulp.task('test', function () {
var files = ['./app/**/*.less'];
return gulp.src(files, {
base: '.' // Now the base url becomes where the *.less is.
})
.pipe(less())
.pipe(gulp.dest('.'));
});
My result:( which is obviously wrong :( )
app/page_a/less/a.less
app/page_a/less/a.css
app/page_a/css
So how can i output *.css into the corresponding app/page_*/css path?
The path you specify in the base option to gulp.src() isn't relative to each respective .less file, but rather the current working directory. This is usually the directory your Gulpfile.js resides in.
What you actually want to do is alter the path for each resulting .css file after your less() plugin has run, so when the .css files are written to the directory specified by gulp.dest() the /less/ part of the path has been replaced with /css/.
This is exactly what the gulp-rename plugin is for:
var gulp = require('gulp');
var less = require('gulp-less');
var rename = require('gulp-rename');
gulp.task('default', function () {
return gulp.src( './app/**/*.less')
.pipe(less())
.pipe(rename(function(file) {
file.dirname = file.dirname.replace(/less$/, "css");
}))
.pipe(gulp.dest('./app/'));
});
With gulp.dest('.') you say 'here'
Try with:
.pipe(gulp.dest('./app/page_a/css/'));
This should be work
Related
Good day!
I want to automate the conversion of images to webp format. To avoid doing it manually or via online converters, I decided to use gulp 4 and gulp-webp.
This is the structure of nesting folders in my project:
I want Gulp, when it finds a picture, so that it creates a folder called "webp" at the same nesting level and places the converted picture in this folder.
I want the following result:
My Gulpfile.js:
let gulp = require('gulp'),
webp = require('gulp-webp');
gulp.task('webp', () => {
// './dev/img/**/*.{png,gif,jpg}' - all files in img and all files in subfolders in img
return gulp.src('./dev/img/**/*.{png,gif,jpg}')
.pipe(webp())
.pipe(gulp.dest(gulp.src)) //something like this, but it doesn't work
}
);
This can be done with the help of gulp-rename.
To install gulp-rename run:
npm i -D gulp-rename
Then in your gulpfile.js add the import:
const rename = require('gulp-rename');
Then change your stream like this:
return gulp.src('./dev/img/**/*.{png,gif,jpg}')
.pipe(webp())
.pipe(rename({ prefix: 'webp/' }))
.pipe(gulp.dest('./dev/img'));
The prefix option inserts "webp/" before the bare filename after the dest target "./dev/img".
i tried to make the src path dynamic and it worked but it messed up the dest somehow
var gulp = require('gulp');
var sass = require ('gulp-sass');
var sassUrl = '**/style.scss';
// compile sass
gulp.task('compile-sass', function(){
gulp.src([sassUrl])
.pipe(sass())
.pipe(gulp.dest('dist/css'))
});
in this exemple
src returns dev/sass/style.scss (which's what i want).
dest returns dist/css/dev/sass i obviously want it to be dist/css but its adding dev/sass at the end
I'm late but I think you want to look into setting your base for your src (this will impact the end location). Please see https://gulpjs.org/api#gulpdestpath-options for more info but here's a quick code snippet from it that'll help you out:
gulp.src('client/js/**/*.js') // Matches 'client/js/somedir/somefile.js' and resolves `base` to `client/js/`
.pipe(minify())
.pipe(gulp.dest('build')); // Writes 'build/somedir/somefile.js'
gulp.src('client/js/**/*.js', { base: 'client' })
.pipe(minify())
.pipe(gulp.dest('build')); // Writes 'build/js/somedir/somefile.js'
I am using gulp to uglify and make ready my javascript files for production. What I have is this code:
var concat = require('gulp-concat');
var del = require('del');
var gulp = require('gulp');
var gzip = require('gulp-gzip');
var less = require('gulp-less');
var minifyCSS = require('gulp-minify-css');
var uglify = require('gulp-uglify');
var js = {
src: [
// more files here
'temp/js/app/appConfig.js',
'temp/js/app/appConstant.js',
// more files here
],
gulp.task('scripts', ['clean-js'], function () {
return gulp.src(js.src).pipe(uglify())
.pipe(concat('js.min.js'))
.pipe(gulp.dest('content/bundles/'))
.pipe(gzip(gzip_options))
.pipe(gulp.dest('content/bundles/'));
});
What I need to do is to replace the string:
dataServer: "http://localhost:3048",
with
dataServer: "http://example.com",
In the file 'temp/js/app/appConstant.js',
I'm looking for some suggestions. For example perhaps I should make a copy of the appConstant.js file, change that (not sure how) and include appConstantEdited.js in the js.src?
But I am not sure with gulp how to make a copy of a file and replace a string inside a file.
Any help you give would be much appreciated.
Gulp streams input, does all transformations, and then streams output. Saving temporary files in between is AFAIK non-idiomatic when using Gulp.
Instead, what you're looking for, is a streaming-way of replacing content. It would be moderately easy to write something yourself, or you could use an existing plugin. For me, gulp-replace has worked quite well.
If you want to do the replacement in all files it's easy to change your task like this:
var replace = require('gulp-replace');
gulp.task('scripts', ['clean-js'], function () {
return gulp.src(js.src)
.pipe(replace(/http:\/\/localhost:\d+/g, 'http://example.com'))
.pipe(uglify())
.pipe(concat('js.min.js'))
.pipe(gulp.dest('content/bundles/'))
.pipe(gzip(gzip_options))
.pipe(gulp.dest('content/bundles/'));
});
You could also do gulp.src just on the files you expect the pattern to be in, and stream them seperately through gulp-replace, merging it with a gulp.src stream of all the other files afterwards.
You may also use module gulp-string-replace which manages with regex, strings or even functions.
Example:
Regex:
var replace = require('gulp-string-replace');
gulp.task('replace_1', function() {
gulp.src(["./config.js"]) // Every file allown.
.pipe(replace(new RegExp('#env#', 'g'), 'production'))
.pipe(gulp.dest('./build/config.js'))
});
String:
gulp.task('replace_1', function() {
gulp.src(["./config.js"]) // Every file allown.
.pipe(replace('environment', 'production'))
.pipe(gulp.dest('./build/config.js'))
});
Function:
gulp.task('replace_1', function() {
gulp.src(["./config.js"]) // Every file allown.
.pipe(replace('environment', function () {
return 'production';
}))
.pipe(gulp.dest('./build/config.js'))
});
I think that the most correct solution is to use the gulp-preprocess module. It will perform the actions you need, depending on the variable PRODUCTION, defined or not defined during the build.
Source code:
/* #ifndef PRODUCTION */
dataServer: "http://localhost:3048",
/* #endif */
/* #ifdef PRODUCTION **
dataServer: "http://example.com",
/* #endif */
Gulpfile:
let preprocess = require('gulp-preprocess');
const preprocOpts = {
PRODUCTION: true
};
gulp.task('scripts', ['clean-js'], function () {
return gulp.src(js.src)
.pipe(preprocess({ context: preprocOpts }))
.pipe(uglify())
.pipe(concat('js.min.js'))
.pipe(gulp.dest('content/bundles/'));
}
This is the best solution because it allows you to control the changes that are made during the build phase.
There I have a versioning specific example for your reference.
let say you have version.ts file and it contains the version code inside it. You now can do as the follows:
gulp.task ('version_up', function () {
gulp.src (["./version.ts"])
.pipe (replace (/(\d+)\.(\d+)(?:\.(\d+))?(?:\-(\w+))?/, process.env.VERSION))
.pipe (gulp.dest ('./'))
});
the above regex works for many situation on any conventional version formats.
I have the following file paths:
resources/assets/css/site1/app.css
resources/assets/css/site2/app.css
resources/assets/css/common/common.css
and I would like them to be copied to public folder without keeping my nested folder structure. Obviously, I need to modify target file names because I have two app.css here. So, I decided to take the last folder of the path as a prefix for filename (and also add -dev postfix because these files are only for development mode and will be deleted when building final release with elixir minification). As the result I should get:
public/css/site1-app-dev.css
public/css/site2-app-dev.css
public/css/common-common-dev.css
Now I have the following gulp code:
gulp.src("resources/assets/css/**/*.css")
.pipe(gulp.dest(
function(file) {
var newPath = "public/css/" +
// folder name, like admin or public
path.basename(path.dirname(file.path)) + "-" +
path.basename(file.path, ".css") + "-dev.css";
console.log(newPath);
return newPath;
}));
I see that console outputs the result as expected. But at the end I get the following files:
public/css/site1-app-dev.css/site1/app.css
public/css/site2-app-dev.css/site2/app.css
public/css/common-common-dev.css/common/common.css
Obviously, gulp treats newPath as a folder name to use when copying the files matching **/*.css and preserving the folder hierarchy.
Is there any way to tell gulp that I actually want it to treat newPath as the final destination filename and not as a directory?
Use gulp-rename to add suffix on file names, the base is specified to keep the nested folder structure.
var rename = require('gulp-rename');
gulp.src("resources/assets/css/**/*.css", {base: 'resources/assets/css/'})
.pipe(rename({ suffix: "-dev", }))
.pipe(gulp.dest("public/css/"));
https://www.npmjs.com/package/gulp-rename
I am enumerating the subdirectories in a directory. For each sub directory I would like to apply a number of gulp activities like less compilation, and then create an output file specific to that subdirectory.
I would like the gulp process to continue, as further transformation steps need to be performed later.
Can someone help me understand how I can create these files half way through the "gulp pipeline"?
This seems quite interesting to achieve and gulp has no limitations at all.
I will give you detailed example how I have managed to accomplish such a task a while ago.
Let assume that you have directoryA. Subdirectories childA, childB and childC are contained into directoryA. So basically your tree structure looks like:
directoryA
--childA
--childB
--childC
I am always looking for a flexible solutions so I would suggest to include a JSON file in each subdirectory naming the tasks you would like to running. Using fs you can access these files. You can also use run-sequence to execute gulp tasks synchronously.
For demo purposes place a file named manifest.json inside childA subdirectory.
Manifest.json contains the following declarations:
{
"filesToProccess" : ["./childA/*.js", "./childB/*.js"],
"tasksToRun" :["taskA", "taskB"]
}
Finally gulpfile would like this:
'use strict';
//dependencies declared into package.json
//install them using npm
var gulp = require('gulp'),
fs = require('fs'),
runSequence = require('run-sequence'),
path = require('path');
//these two array will keep the actions you have included into manifest file.
var filesHolder = [], tasksHolder = [];
gulp.task('taskA', function () {
return gulp.src(filesHolder)
.pipe(whatever)
.pipe(gulp.dest('whatever')); //chailed actions
});
gulp.task('taskB', function () {
return gulp.src(filesHolder)
.pipe(whatever)
.pipe(gulp.dest('whatever'));
});
//a simple utility function to read all subdirectories of directoryA
function getDirectories(srcpath) {
return fs.readdirSync(srcpath).filter(function(file) {
return fs.statSync(path.join(srcpath, file)).isDirectory();
});
}
//finally insert the default gulp task
gulp.task('default', function(){
var manifest;
//map directory's A subdirectories
var availableDirs = getDirectories("./directoryA");
//finally loop the available subdirectories, load each manifest file and
availableDirs.forEach(function(subdir) {
manifest = require("./directoryA/"+subdir+"manifest.json");
filesHolder = manifest.filesToProccess;
tasksHolder = manifest.tasksToRun;
runSequence( tasksHolder , function () {
console.log( " Task ended :" + tasksHolder + " for subdirectory : " + subdir);
});
});
});