I'm trying to create an automated process for including node modules in my projects. Some modules have css included, and so I'm trying to make gulpfile.js in a way it can read those modules and include the css of that module.
I try to be selective and have only the folders selected that I install as a dependency. Not the entire node_modules folder.
My gulpfile.js:
// Import (not showing all for the sake of the question)
const sourcemaps = require('gulp-sourcemaps');
const sass = require('gulp-sass');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const fs = require('fs');
const json = JSON.parse(fs.readFileSync('./package.json'));
// File paths
const files = {
cssPath: 'assets/styles/**/*.scss',
jsPath: 'assets/scripts/**/*.js',
imgPath: 'assets/images/**/*',
modulesPath: ['node_modules']+json.dependencies+'/**/*.scss'
//Desired output: node_modules/module_name/all_folders/all.scss
}
// Compile CSS
function styles(){
return src([files.cssPath, files.modulesPath])
.pipe(sourcemaps.init())
.pipe(sass())
.pipe(postcss([ autoprefixer(), cssnano() ]))
.pipe(sourcemaps.write('.'))
.pipe(dest('dist/styles')
);
}
When I run "gulp styles" the function runs just fine, but the desired styles are not included. What am I doing wrong?
First, there's an easier way to get your package.json file:
const package = require('./package.json');
Then you need the names of your dependencies, which are the keys in the dependencies object. Map these to a glob, like this:
const files = {
...
modulesPath: Object.keys(package.dependencies).map(module => `node_modules/${module}/**/*.scss`)
}
Lastly, destructure that array in your styles task:
return src([files.cssPath, ...files.modulesPath])
Related
I'm usign postcss/precss with gulp to convert my scss markup to valid css. This is my gulpfile.js:
var gulp = require('gulp');
var postcss = require('gulp-postcss');
var precss = require('precss');
var watch = require('gulp-watch');
gulp.task('stream', function () {
var processors = [
precss
];
return watch('src/*.css', { ignoreInitial: false })
.pipe(postcss(processors))
.pipe(gulp.dest('dest'));
});
gulp.task('default', gulp.parallel('stream'));
The problem is that it doesn't change file extensions, so I need to write scss in *.css files, and what I am trying to do is to set it to read scss from *.scss files and output css into *.css files. Can anybody tell me how to achieve that?
Not an expert on this, so I'll just share how we do sass compilation.
We use gulp-concat to concat the files together into one .css file. Your gulp snippet would be as follows:
var gulp = require('gulp');
var postcss = require('gulp-postcss');
var precss = require('precss');
var watch = require('gulp-watch');
var concat = require('gulp-concat');
gulp.task('stream', function () {
var processors = [
precss
];
return watch('src/*.css', { ignoreInitial: false })
.pipe(postcss(processors))
.pipe(concat('FILENAME.css'))
.pipe(gulp.dest('dest'));
});
gulp.task('default', gulp.parallel('stream'));
Don't forget to do npm install --save-dev gulp-concat first!
I am pretty new at Gulp (v.4.0.2), so I can't understand is there any kind of cache mechanism inside it (at least I can't find such a piece of information on Google). After running my "gulp" command styles.css file being created, but if I do changes in SASS file and the try to run the same command again I won't get a new generated file. I tried to delete styles.css file and run the command again - the file was generated, but with the old content. I can even see that the modification date of the generated file is being left from the old file.
My gulpfile.js:
const gulp = require('gulp');
const sass = require('gulp-sass');
const cssnano = require('gulp-cssnano');
const del = require('del');
gulp.task('styles', () => {
return gulp.src('app/sass/**/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(cssnano())
.pipe(gulp.dest('app/css'));
});
gulp.task('clean', () => {
return del([
'app/css/styles.css',
]);
});
gulp.task('default', gulp.series(['clean', 'styles']));
At work we used to use Ruby to compile SCSS. I had the Ruby compiler set up as a file watcher in PhpStorm, and when I edited a partial imported by another file, the CSS file corresponding to the ancestor file was updated without any fuss.
I want to get Gulp and Libsass to work the same way. Most solutions I've seen just compile all the SCSS files in a project when a single one changes, but our projects have way too much SCSS for that to be an acceptable solution.
gulp-cached seemed like a great solution to this problem. But when I use gulp-cached the CSS output file doesn't change when I edit partials, only their ancestor SCSS files.
I've seen a few SCSS dependency-graph solutions thrown around but I can't get them to work correctly or they simply don't do what I need. I've tried gulp-sass-graph, gulp-sass-inheritance, and gulp-sass-partials-imported.
Here's my gulp file
const gulp = require('gulp');
const glob = require('glob');
const sass = require('gulp-sass');
const sourcemaps = require('gulp-sourcemaps');
const cached = require('gulp-cached');
const sassGraph = require('gulp-sass-graph');
const sassGlobs = [
'./sites/all/libraries/gl/**/*.scss',
'./sites/all/modules/custom/**/*.scss',
'./sites/all/themes/{bcp_bootstrap3,gl_parent,gl_shiny,gli_bootstrap3,pru_bootstrap3,pru_bootstrap3v2,ubc_bootstrap3}/**/*.scss',
];
let sassPaths = [];
for (let j = 0; j < sassGlobs.length; ++j) {
glob(sassGlobs[j], function (er, files) {
let path;
for (let i = 0; i < files.length; ++i) {
path = files[i].substring(0, files[i].lastIndexOf('/'), '');
if (sassPaths.indexOf(path) === -1) {
sassPaths.push(path);
}
}
});
}
gulp.task('sass', function () {
return gulp
.src(sassGlobs, {base: "./"})
// .pipe(sassGraph(sassPaths))
.pipe(cached('sasscache'))
.pipe(sourcemaps.init())
.pipe(
sass({outputStyle: 'compressed'})
.on('error', sass.logError)
)
.pipe(sourcemaps.write())
.pipe(gulp.dest((file) => file.base));
});
gulp.task('watch', function () {
return gulp.watch(sassGlobs, ['sass']);
});
gulp.task('default', ['sass', 'watch']);
what I use to solve this problem is gulp-cached + gulp-dependents + gulp-filter
the key point here is gulp-dependents, it will find all the parent files that depends on the current file.
in your case, you just need:
const cached = require('gulp-cached');
const dependents = require('gulp-dependents');
const filter = require('gulp-filter');
const f = filter(['**', '!*src/partial']); //adjust this filter to filter the file you want to compile(pass to the sourcemap init method)
gulp.task('sass', function () {
return gulp
.src(PATH_TO_ALL_SASS_FILES, {base: "./"})
.pipe(cached('sasscache'))
.pipe(dependents())// this will find all parents of current changed files
.pipe(f) //exclude the partial files,get the files you want to compile
.pipe(sourcemaps.init())
.pipe(
sass({outputStyle: 'compressed'})
.on('error', sass.logError)
)
.pipe(sourcemaps.write())
.pipe(gulp.dest((file) => file.base)); // you might need to adjust the base path here, depend on your folder structure.
});
How do I use gulp to convert all jsx files to JavaScript?
When I try to do so, I get the error undefined function require
I'm using the following script.
What I want to do is use gulp to convert all jsx to JavaScript. Also use browserfy in my jsx files.
var gulp = require('gulp')
var react = require('gulp-react')
gulp.task('transpile-js', function() {
return gulp.src('./src/*.jsx')
.pipe(react({harmony: true}))
.pipe(gulp.dest('./build'))
})
I have jsx files in the src directory. I want to convert them into one JavaScript file and store the result in the build directory
Take a look at my domno repo for more:
var gulp = require('gulp'),
uglify = require('gulp-uglify'),
browserify = require('browserify'),
source = require('vinyl-source-stream'),
buffer = require('vinyl-buffer');
gulp.task('script', function () {
return browserify({
entries : ['the/path/to/the/main/entry/file.js'],
transform: ['babelify']
})
.bundle()
.pipe(source('app.js'))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest(dir.web));
});
There are several ways of configuring Browserify...
I have the next files structure:
modules/
list/
news/
news.scss
login/
login.scss
common/
common.scss
And I want to get next structure using gulp:
modules/
list/
news/
news.scss
news.css
login/
login.scss
login.css
common/
common.scss
Here is part from my gulpfile:
gulp.src("modules/list/*/*.scss")
.pipe(sass())
.pipe(gulp.dest("modules/list/"));
In common.scss there are different variables. It is necessary that variables from common.scss will be used in each module(news.scss, login.scss). How to update my gulpfile that common.scss will be concatenated with each module scss file?
Sounds like a job for stream arrays... here's the solution, please check the comments for what's going on:
var merge = require('merge2');
var glob = require('glob');
var gulp = require('gulp');
var concat = require('gulp-concat');
var sass = require('gulp-sass');
gulp.task('styles', function(done) {
// first, we glob our files like we would with gulp.src
glob('modules/list/**/*.scss', function(er, files) {
// for each of those files we create a new stram
var tasks = files.map(function(file) {
// this gives us the concat name, which is the same
// as the original file's name
var concatStr = file.substr('modules/list/'.length)
// we load common.scss and our file
return gulp.src(['modules/common/common.scss', file])
// concatenate it
.pipe(concat(concatStr))
});
// we merge all our streams
merge(tasks)
// run them through sass
.pipe(sass())
// and save them where we want them
.pipe(gulp.dest('modules/list'));
// ~fin
done();
});
});
You might want to take a look into Sass's #import directive, though.