I'm looking to split my gulpfile.js assets or src variables into separate files so that I can manage them better. For example:
....
var scripts = ['awful.js', 'lot.js', 'of.js', 'js.js', 'files.js']
....(somewhere down the line)
gulp.task('vendorjs', function() {
return gulp.src(scripts)
.pipe(concat('vendor.js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest(paths.root + 'dist'))
.pipe(notify({ message: 'vendorjs task completed' }));
});
So what I'm basically interested if theres a way to actually move to a separate file the scripts variable and be able to access it from gulpfile.js.
I've been looking into something like:
require("fs").readFile('gulp/test.js', function(e, data) {
//(test.js would be the file that holds the scripts var)
});
Howerver while it does read the contents of the file, I still can't access it from the gulpfile.js. Any tips or ideas are much appreciated.
Node.js allows you to import other files using require(). It supports three types of files:
JSON files. See DavidDomain's answer for that.
Binary Node.js addons. Not useful for your use case.
JavaScript files. That's what you want.
For JavaScript files the value returned from require() is the one that is assigned to module.exports in the imported file.
So for your use case:
gulp/test.js
var arrayOfFiles = ["awful.js", "lots.js"];
arrayOfFiles.push("of.js");
arrayOfFiles.push("js.js");
arrayOfFiles.push("files.js");
for (var i = 0; i < 10; i++) {
arrayOfFiles.push("some_other_file" + i + ".js");
}
module.exports = {
scripts: arrayOfFiles
};
gulpfile.js
var test = require('gulp/test.js');
gulp.task('vendorjs', function() {
return gulp.src(test.scripts)
.pipe(concat('vendor.js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest(paths.root + 'dist'))
.pipe(notify({ message: 'vendorjs task completed' }));
});
You could use a json file to store your assets or source file location in and load that into your gulp file.
For example:
// config.json
{
"scripts": ["awful.js", "lot.js", "of.js", "js.js", "files.js"]
}
And in your gulp file you would do
// gulpfile.js
var config = require('./config');
var scripts = config.scripts;
console.log(scripts);
Related
I have been working on modifying this relatively simple gulpfile/project: https://github.com/ispykenny/sass-to-inline-css
The first issue I had was to update to gulp v4, but I've also tried to store variables for my src and destination folders which is a bit easier to control. So now my gulpfile looks like this:
const gulp = require('gulp');
const inlineCss = require('gulp-inline-css');
const sass = require('gulp-sass');
const browserSync = require('browser-sync').create();
const plumber = require('gulp-plumber');
const del = require('del');
const srcFolder = './src'; // TODO tidy this up once working
const buildFolder = srcFolder + '/build/'; // Tidy this up once working
const src = {
scss: 'src/scss/**/*.scss',
templates: 'src/templates/**/*.html'
}
const dest = {
build: 'build/',
css: 'build/css'
};
function processClean() {
return del(`${buildFolder}**`, { force: true });
}
function processSass() {
return gulp
.src(src.scss)
.pipe(plumber())
.pipe(sass())
.pipe(gulp.dest(dest.css))
.pipe(browserSync.stream())
}
function processInline() {
return gulp
.src('./*.html')
.pipe(inlineCss({
removeHtmlSelectors: true
}))
.pipe(gulp.dest('build/'))
}
function processWatch() {
gulp.watch(['./src/scss/**/*.scss'], processSass);
gulp.watch(srcFolder).on('change', browserSync.reload);
gulp.watch(distFolder).on('change', browserSync.reload);
}
const buildStyles = gulp.series(processSass, processInline);
const build = gulp.parallel(processClean, buildStyles);
gulp.task('clean', processClean);
gulp.task('styles', buildStyles);
gulp.task('sass', processSass);
gulp.task('inline', processInline);
gulp.task('build', build);
gulp.task('watch', processWatch);
But I am now wanting to create lots of template files, store them in a subfolder and have gulp spit out each file into the destination folder. if I have index.html, test1.html etc in the root it works fine.
I tried modifying this:
function processInline() { return gulp.src('./*.html')
To this:
function processInline() { return gulp.src(src.templates) // should equate to 'src/templates/**/*html'
Now I'm seeing this error in the console:
ENOENT: no such file or directory, open 'C:\Users\myuser\pathToApp\emailTemplates\src\templates\build\css\style.css'
In the head of index.html in the root is this:
<link rel="stylesheet" href="build/css/style.css">
I actually don't really care about the css file as the final output should be inline (for email templates). But I cannot get my head around why this is happening.
Does gulp create the css file and then read the class names from there? EDIT, Ah I guess it must because it has to convert the sass to readable css first before stripping out the class names and injecting the inline styles.
Years ago I worked with grunt a fair bit, and webpack, but haven't done much with gulp.
I hope it is obvious, but if you need more information just let me know.
I'm trying to copy multiple files and folders using gulp.src and gulp.dest from my base directory . to a new subdirectory dist.
The base directory is the root of a Symfony project.
Here's my gulpfile:
var files = [
'./app**/*.*',
'./bin**/*.*',
'./src**/*.*',
'./tests**/*.*',
'./var/',
'./vendor/',
'./composer.json']
gulp.task('distribute', function() {
return gulp.src(files , { base: '.' }).pipe(gulp.dest('./dist'));
});
I just don't understand, why this isn't working. As result, I get a dist folder with the contents of the specified folders. So app, bin, src etc. are missing as root folders.
Moving the directories themselves
Based on Use gulp to select and move directories and their files, use ./ for the base option and make sure the paths are correct:
var files = [
'./app/**/*.*',
'./bin/**/*.*',
'./src/**/*.*',
'./tests/**/*.*',
'./var/',
'./vendor/',
'./composer.json'
];
gulp.task('distribute', function() {
return gulp.src(files , { base: './' })
.pipe(gulp.dest('dist'));
});
Moving the files within each directories
Don't use the base option and change your paths a little.
var files = [
'app/**/*.*',
'bin/**/*.*',
'src/**/*.*',
'tests/**/*.*',
'var/',
'vendor/',
'composer.json'
];
gulp.task('distribute', function() {
return gulp.src(files)
.pipe(gulp.dest('./dist'));
});
Flexible way to threat each directory as a task
If you want to move the folder themselves, just make a task for each one using a task generator function.
function moveDirTask(dir, dest) {
return function() {
return gulp.src(`${dir}/**/*`)
.pipe(gulp.dest(`${dest}/${dir}/`));
};
}
gulp.task('move-app', moveDirTask('app', 'dest'));
gulp.task('move-bin', moveDirTask('bin', 'dest'));
gulp.task('move-src', moveDirTask('src', 'dest'));
gulp.task('move-tests', moveDirTask('tests', 'dest'));
// etc.
gulp.task('distribute', [
'move-app',
'move-bin',
'move-src',
'move-tests'
// etc.
], function() {
return gulp.src('composer.json')
.pipe(gulp.dest('dest'));
});
I have this default gulp file from a Visual Studio template:
/// <binding BeforeBuild='clean, minPreBuild' />
"use strict";
var gulp = require("gulp"),
rimraf = require("rimraf"),
concat = require("gulp-concat"),
cssmin = require("gulp-cssmin"),
uglify = require("gulp-uglify");
var webroot = "./wwwroot/";
var paths = {
js: webroot + "js/**/*.js",
minJs: webroot + "js/**/*.min.js",
css: webroot + "css/**/*.css",
minCss: webroot + "css/**/*.min.css",
concatJsDest: webroot + "js/_site.min.js",
concatCssDest: webroot + "css/_site.min.css"
};
gulp.task("clean:js", function (cb) {
rimraf(paths.concatJsDest, cb);
});
gulp.task("clean:css", function (cb) {
rimraf(paths.concatCssDest, cb);
});
gulp.task("clean", ["clean:js", "clean:css"]);
gulp.task("min:js", function () {
return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
.pipe(concat(paths.concatJsDest))
.pipe(uglify())
.pipe(gulp.dest("."));
});
gulp.task("min:css", function () {
return gulp.src([paths.css, "!" + paths.minCss])
.pipe(concat(paths.concatCssDest))
.pipe(cssmin())
.pipe(gulp.dest("."));
});
gulp.task("min", ["min:js", "min:css"]);
gulp.task("minPreBuild", ["min:js", "min:css"]);
The problem I'm having is one of my js files in the directory has a dependency on knockout, but I'm only using knockout on one of the pages on the site. I don't want to include knockout on my shared view, and the default bundling all files into a single file causes a JS error "ko is undefined" as one of the JS files is dependent on KO.
Is there a way that I can minify files individually, without concatting it into the main "site.min.css"?
First you need to exclude the Knockout file from your min:js task. Prepending a path with ! tells gulp to ignore that file:
gulp.task("min:js", function () {
return gulp.src([
paths.js,
"!" + paths.minJs,
"!js/path/to/knockout.js" // don't include knockout in _site.min.js
], { base: "." })
.pipe(concat(paths.concatJsDest))
.pipe(uglify())
.pipe(gulp.dest("."));
});
Then you need to create a new task min:knockout that does nothing but minify your Knockout file. You'll probably want the minified file to end with a .min.js extension so you'll have to install the gulp-rename plugin as well.
var rename = require('gulp-rename');
gulp.task("min:knockout", function () {
return gulp.src("js/path/to/knockout.js", { base: "." })
.pipe(rename("js/_knockout.min.js"))
.pipe(uglify())
.pipe(gulp.dest("."));
});
Finally you need to make sure your new min:knockout task is executed when running the min and minPreBuild tasks:
gulp.task("min", ["min:js", "min:knockout", "min:css"]);
gulp.task("minPreBuild", ["min:js", "min:knockout", "min:css"]);
I have a file at /components/slider/index.html. I setup a gulp task that injects related css/js files from separate folders using gulp-inject.
gulp.task('default', function() {
return gulp.src('./components/**/*.html')
.pipe( inject(gulp.src(['./assets/css/bootstrap/*.css'], {read: false}), { relative: true }) )
.pipe( inject(gulp.src(['./assets/js/jquery/*.js'], {read: false}), {starttag: '<!-- inject:head:{{ext}} -->', relative: true} ) )
.pipe(gulp.dest('./dist'));
});
Now I need to get the source of a js file, located along side of the html source we are pipe-ing, in order to inject it relativley using gulp-inject.
Is there anyway to get gulp.src('./components/**/*.html') in a pipe and somehow get the sibling js file from there? Any suggestion?
It turns out you can not do that using gulp-inject, So what I did was to get a list of directory paths, and then do gulp-inject on each of them separately.
This way I had access to all the folders & files paths before I even begin injecting.
var fs = require('fs');
var dirPath = '/components/widgets/';
var result = []; //this is going to contain paths
fs.readdir(__dirname + dirPath, function (err, filesPath) {
if (err) throw err;
result = filesPath.map(function (filePath) {
return dirPath + filePath;
});
function do_inject(entry) {
// Injection Code using gulp-inject
}
result.forEach(function(entry) {
do_inject(entry);
});
});
Also I ended up using "addPrefix" and "addRootSlash" options for my gulp-inject to make it behave how I want. Just some additional info, it may help someone.
I have a gulp task that is attempting to convert .scss files into .css files (using gulp-ruby-sass) and then place the resulting .css file into the same place it found the original file. The problem is, since I'm using a globbing pattern, I don't necessarily know where the original file is stored.
In the code below I'm trying to use gulp-tap to tap into the stream and figure out the file path of the current file the stream was read from:
gulp.task('convertSass', function() {
var fileLocation = "";
gulp.src("sass/**/*.scss")
.pipe(sass())
.pipe(tap(function(file,t){
fileLocation = path.dirname(file.path);
console.log(fileLocation);
}))
.pipe(gulp.dest(fileLocation));
});
Based on the output of the console.log(fileLocation), this code seems like it should work fine. However, the resulting CSS files seem to be placed one directory higher than I'm expecting. Where it should be project/sass/partials, the resulting file path is just project/partials.
If there's a much simplier way of doing this, I would definitely appreciate that solution even more. Thanks!
As you suspected, you are making this too complicated. The destination doesn't need to be dynamic as the globbed path is used for the dest as well. Simply pipe to the same base directory you're globbing the src from, in this case "sass":
gulp.src("sass/**/*.scss")
.pipe(sass())
.pipe(gulp.dest("sass"));
If your files do not have a common base and you need to pass an array of paths, this is no longer sufficient. In this case, you'd want to specify the base option.
var paths = [
"sass/**/*.scss",
"vendor/sass/**/*.scss"
];
gulp.src(paths, {base: "./"})
.pipe(sass())
.pipe(gulp.dest("./"));
This is simpler than numbers1311407 has led on. You don't need to specify the destination folder at all, simply use .. Also, be sure to set the base directory.
gulp.src("sass/**/*.scss", { base: "./" })
.pipe(sass())
.pipe(gulp.dest("."));
gulp.src("sass/**/*.scss")
.pipe(sass())
.pipe(gulp.dest(function(file) {
return file.base;
}));
Originally answer given here: https://stackoverflow.com/a/29817916/3834540.
I know this thread is old but it still shows up as the first result on google so I thought I might as well post the link here.
This was very helpful!
gulp.task("default", function(){
//sass
gulp.watch([srcPath + '.scss', '!'+ srcPath +'min.scss']).on("change", function(file) {
console.log("Compiling SASS File: " + file.path)
return gulp.src(file.path, { base: "./" })
.pipe(sass({style: 'compressed'}))
.pipe(rename({suffix: '.min'}))
.pipe(sourcemaps.init())
.pipe(autoprefixer({
browsers: ['last 2 versions'],
cascade: false
}))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest("."));
});
//scripts
gulp.watch([srcPath + '.js','!'+ srcPath + 'min.js']).on("change", function(file) {
console.log("Compiling JS File: " + file.path)
gulp.src(file.path, { base: "./" })
.pipe(uglify())
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest("."));
});
})
if you want to save all files in their own path in the dist folder
const media = () => {
return gulp.src('./src/assets/media/**/*')
.pipe(gulp.dest(file => file.base.replace('src', 'dist'))
)
}
const watch = () => {
gulp.watch(
"./src/**/*",
media
);
};