Gulp sass copies empty scss files to destination folder - javascript

I have a task:
gulp.task('compile_scss, function() {
return gulp.src('/admin_app/scss/*.scss')
.pipe(sass())
.pipe(dest('/admin_app/css/'))
});
When I am adding new empty ".scss" file to '/admin_app/scss/' and running task from above, empty ".scss" files is copied to destination folder. If file is not empty everything is ok: a valid css file( with ".css" extension) is compiled and no ".scss" files are copied. The problem is when I add new ".scss" file to "/admin_app/scss/" directory, a "watch" task is triggered, and because file is empty, it is copied to destination directory. As a result, a lot of unneeded garbage is dest folder. Why this happens and how can I get rid of it?
UPDATED
My "watch" and "default" tasks:
gulp.task('watch', ['compile_scss'], function() {
apps.forEach(function(appName) {
gulp.watch('/admin_app/scss/*.scss', ['compile_scss']);
});
});
gulp.task('default', ['watch']);

One way to solve this problem would be to simply filter the empty files.
Try something like this:
var filter = require('gulp-filter'),
gulp.task('compile_scss, function() {
return gulp.src('/admin_app/scss/*.scss')
.pipe(filter(function(a){ return a.stat && a.stat.size }))
.pipe(sass())
.pipe(dest('/admin_app/css/'))
});
There's also a plugin specifically for this purpose. You can use it like this:
var clip = require('gulp-clip-empty-files'),
gulp.task('compile_scss, function() {
return gulp.src('/admin_app/scss/*.scss')
.pipe(clip())
.pipe(sass())
.pipe(dest('/admin_app/css/'))
});
In addition: there seem to have been several reports of problems in gulp-sass and underlying libraries when compiling empty files. There is a Github issue for gulp-sass, reporting this should be solved in the 2.x versions of the plugin. If you're already running 2.x, the problem you are facing might be an issue introduced by solving the original problem.

If you add empty scss files in your sass folder, prefix them with underscore: _empty.scss.
See "Partials" here: http://sass-lang.com/guide#topic-4
You can create partial Sass files that contain little snippets of CSS
that you can include in other Sass files. This is a great way to
modularize your CSS and help keep things easier to maintain. A partial
is simply a Sass file named with a leading underscore. You might name
it something like _partial.scss. The underscore lets Sass know that
the file is only a partial file and that it should not be generated
into a CSS file. Sass partials are used with the #import directive.

Related

Gulp replace not renaming files but does replace file contents

I have the following gulp task which I want to change the filename and contents of a file replacing any matching strings with the replacement.
The matching strings in the file contents get changed, but the file's name does not. I thought it would as my code appears to match the examples on https://www.npmjs.com/package/gulp-replace
What am I doing wrong?
function renameFileContents() {
return gulp.src([
'**/*',
'!.github/**',
'!languages/**',
'!node_modules/**',
'!.babelrc',
'!.editconfig',
'!.gitignore',
'!.travis.yml',
'!CHANGELOG.md',
'!codesniffer.ruleset.xml',
'!composer.json',
'!composer.lock',
'!config.yml',
'!config-default.yml',
'!gulpfile.babel.js',
'!MIT-LICENSE.txt',
'!package-lock.json',
'!package.json',
'!phpunit.xml.dist',
'!README.md',
'!webpack.config.js'
])
.pipe($.replace('BigTest', 'Tester'))
.pipe($.replace('Bigtest', 'Tester'))
.pipe($.replace('bigtest', 'tester'))
.pipe(gulp.dest('./'));
}
Use gulp-rename to alter filenames. Add:
const rename = require('gulp-rename');
and before .pipe(gulp.dest('./'));:
.pipe(
rename(function(path) {
path.basename = path.basename.replace(/BigTest|Bigtest|bigtest/, function(matched) {
return { BigTest: 'Tester', Bigtest: 'Tester', bigtest: 'tester' }[matched];
});
})
)
You asked in a comment why new files are created (with the new names) but the original files still remain. Why does gulp-rename not actually rename the original files as you might expect?
Gulp-rename is not working with the original files. This can be a little confusing.
It's called gulp-rename because it renames an in-memory gulp file
object. gulp is like functional programming, each plugin takes in
input and produces output in-memory without causing side effects. [emphasis added]
gulp works like this:
read file (gulp.src)
do some stuff, modify the file in-memory (plugins)
commit file changes back to fs (gulp.dest/or others)
From gulp-rename issues: not renaming the original files.
The suggested fix (from gulp recipes: deleting files from a pipeline) which I tested is:
const del = require('del');
const vinylPaths = require('vinyl-paths');
and add this pipe before the replace pipe:
.pipe(vinylPaths(del))
.pipe(
rename(function(path) { ......
and your original files will be deleted, leaving only the newly named files. Obviously, make sure you test this on good test cases before deleting any of your files!

What is the best way to set up an angularjs project with old javascript files, typescript and sourcemap?

I would like to use a bootstrap-template with js-files for my new angularjs project. New modules will be written in typescript.
So my idea was to transcipt all ts files into /build/js/
Then i would concat all js files from /app/**/*.js and from /build/**/*.js into app.js.
My project folder structure looks like this.
app
|-js-files
|-ts-files
build
|js folder with .js.map.files
|-app.js
|-app.js.map
|-vendor.js
On every step sourcemap files will be created.
There are my gulp tasks:
gulp.task('typescript', function () {
var tsResult = tsProject.src()
.pipe(sourcemaps.init()) // sourcemaps will be generated
.pipe(tsProject());
return tsResult.js
.pipe(sourcemaps.write('.')) // Now the sourcemaps are added to the .js file
.pipe(gulp.dest('./build/js'));
});
gulp.task('bundle', function () {
return es.merge(gulp.src(source.js.src), getTemplateStream())
.pipe(sourcemaps.init()) // sourcemaps will be generated
.pipe(concat('app.js'))
.pipe(sourcemaps.write('.')) // Now the sourcemaps are added to the .js file
.pipe(gulp.dest(destinations.js));
});
Is this the right way to set up a project like this?
Source mapping doesn't work...?
Should the folder /build/js be deleted after the bundling into app.js?
Is this the right way to set up a project like this
Personally no. Have all the files .js and .ts in the same folder ./src. Set allowJs:true and outDir:'./dist'. Then slowly start the .js -> .ts migration as needed.
More
As an example checkout this quick video : https://www.youtube.com/watch?v=gmKXXI_ck7w

Gulp glob to ignore file types and not copy empty folders

I have created a glob for gulp which ignores javascript and coffeescript files within a set of directories. I'd like it to copy all other files into a directory which works fine. The only problem is that when there are only javascript or coffeescript files it copies an empty folder. Any ideas how this glob could be amended to not copy empty folders?
gulp.task('copyfiles', function(){
gulp.src('apps/*/static_src/**/!(*.js|*.coffee)')
.pipe(gulp.dest('dest'));
});
Example source files:
apps/appname/static_src/images/image.jpg
apps/appname/static_src/js/script.js
Expected output:
dest/static_src/images/image.jpg
Current output:
dest/static_src/images/image.jpg
dest/static_src/js/
Since gulp.src accepts almost the same options as node-glob, you can add nodir: trueas an option:
gulp.src('apps/*/static_src/**/!(*.js|*.coffee)', { nodir: true })
This will preserve the dir structure from src, but omit empty ones.
gulp.task('copyfiles', function(){
gulp.src(['apps/*/static_src/**/*','!apps/*/static_src/{js/, js/**}'])
.pipe(gulp.dest('dest'));
});
I think you need a pattern '!apps/*/static_src/{js/, js/**}' that matches the directory as well as the files inside to prevent ommiting an empty directory. I am not sure if there is a pattern to match a directory only by specifying its content.

Gulp doesn't copy all files as expected

I tried to create a gulpfile.js for my personal website project. I've never done this before but with a little 'trial and error' it now works in an acceptable way.
The only thing that doesn't work even after 1000 modifications is simple copying files and folders.
var files = {
data_src : [
'./files.json',
'data/**/*.*'
],
distribution_dest : '_distribution'
};
gulp.task('copy-data', function() {
gulp.src(files.data_src, { base: './' })
.pipe(gulp.dest(files.distribution_dest))
.pipe(notify({message: 'Data copied for distribution!'}));
});
This should copy all sub-folders and files to the gulp.dest. But it copies only half of them, some folders will be ignored even if I change their names etc. (no special characters, same subfolder structure as the once that got copied correctly ...) - nothing worked. I just can't see any pattern in this.
There is no error message while running gulp. Nothing that would help me find the error.
Why are some folders or files excluded from copying?
I use base to keep the folder / sub-folder structure; tried with and without 'base' -> no effects on the copying process.
I also changed the position of the 'copy-data' task in the run-list. Actually it's the first task to run. There seems to be no change in behavior no matter if it's the first or the last one.
gulp.task('default', function() {
gulp.run('copy-data', 'custom-sass', 'framework-sass', 'custom-js', 'framework-js', 'replace-tags', 'browser-sync');
... some watches ...
});
The structure of the data folder looks like these:
./data
|-doc
|---content
|---template
|-img
|---chart
|---icon
|---logo
|---pattern
|---people
|---photo
|---symbol
|-----brandklassen
|-----brandschutzzeichen
|-----gebotszeichen
|-----gefahrensymbole
|-----rettungszeichen
|-----verbotszeichen
|-----verkehrsrechtzeichen
|-----warnzeichen
|---wallpaper
/data/doc and all subfolders are ok.
/data/img/chart to /data/img/people are also ok.
Within /data/img/photo only 14 out of 21 images are copied.
/data/img/symbol with sub-folders and /data/img/wallpaper were ignored completely.
SOLVED IT MYSELF! The problem was caused by async operating tasks. Adding a return forced gulp to complete the copying process before continuing!
gulp.task('copy-data', function() {
return gulp.src(files.data_src, { base: './' })
.pipe(gulp.dest(files.distribution_dest))
.pipe(notify({message: 'Data copied for distribution!'}))
});
Now all images will be copied!

Gulp.js event stream merge order

I am trying to merge css and scss files into a main.css file that goes in my build directory.
Its working, but not in the right order. The style attributes from the scss files need to be in the bottom of the main.css file so they overrule the rest.
my Gulp task looks like this:
//CSS
gulp.task('css', function () {
var cssTomincss = gulp.src(['dev/css/reset.css', 'dev/css/style.css','dev/css/typography.css', 'dev/css/sizes.css']);
var cssFromscss = gulp.src(['dev/css/*.scss'])
.pipe(sass());
return es.merge(cssTomincss, cssFromscss)
.pipe(concat('main.css'))
.pipe(minifyCSS())
.pipe(gulp.dest('build/css'))
});
I am defining the sources first with variables. I am using the gulp-sass plugin to convert the scss file into normal css (.pipe(sass)) and later merging the two with the es.merge function and concatenating them into main.css.
The problem is that the style attributes van the .scss files end up somewhere in the top end of the main.css file. I need them to be at the bottom. So they need to be concatenated at the bottom.
Any clue on how to do this?
Try streamqueue.
var streamqueue = require('streamqueue');
gulp.task('css', function () {
return streamqueue({ objectMode: true },
gulp.src(['dev/css/reset.css', 'dev/css/style.css', 'dev/css/typography.css', 'dev/css/sizes.css']),
gulp.src(['dev/css/*.scss']).pipe(sass())
)
.pipe(concat('main.css'))
.pipe(minifyCSS())
.pipe(gulp.dest('build/css'))
});
This cheatsheet will help you. PDF is here.
It seems that the plugin gulp-order fits perfectly well in your case.
It allows you to re-order the passed stream with your own glob pattern, for example based on your code :
return es.merge(cssTomincss, cssFromscss)
.pipe(order([
'dev/css/reset.css',
'dev/css/style.css',
'dev/css/typography.css',
'dev/css/sizes.css',
'dev/css/*.css',
]))
.pipe(concat('main.css'))
.pipe(minifyCSS())
.pipe(gulp.dest('build/css'))
One drawback of this is that you have to re-declare your globs, but you can get around by assign your globs to a value and then concat them in you order pipe, much cleaner.
You may have to set the base option to . of gulp-order as stated in their Readme if the files were not ordered correctly.
One another way would be to use stream-series, basically the same as event-stream, but the order of your stream is preserved, and you don't have to rewrite your globs.
I tried gulp-order without success: the order somehow wasn't taken into account.
The solution which worked for me was using stream-series, mentioned by Aperçu.
return streamSeries(
cssTomincss,
cssFromscss)
.pipe(concat('main.css'))
.pipe(minifyCSS())
.pipe(gulp.dest('build/css'));
I failed with all provided answers, they produced some silent errors. Finally merge2 worked for me (seems like there was gulp-merge and later the project was renamed into merge2). I'm not sure why there is a need in streamify plugin, e.g. streams created with Rollup may produce "stream-not-supported-errors" with gulp-concat, gulp-uglify or gulp-insert.
const mergeStreams = require('merge2');
const streamify = require('streamify');
...
gulp.task('build', () => {
const streams = sources.map(createJSFile);
return mergeStreams(...streams)
.pipe(streamify(concat('bundle.js')))
.pipe(streamify(uglify()))
.pipe(gulp.dest('./dist'));
});

Categories

Resources