Gulp Command Run Never Finish - node.js

I have bought template MaterialPro from wrappixel website. After I got the template package already, I have followed getting started installation from document attached with template as the following:
Install Node.js From https://nodejs.org/en/download/
Open terminal navigating to material-pro/
Install npm: npm install --global npm#latest
Install yarn: npm install --global yarn
Install gulp: npm install --global gulp-cli
Copy gulp: gulp copy
The gulpfile.js inside root template is like this:
//gulpfile.js
console.time("Loading plugins"); //start measuring
const gulp = require('gulp'),
minifyCSS = require('gulp-clean-css'),
uglify = require('gulp-uglify'),
rename = require("gulp-rename"),
sass = require('gulp-sass'),
npmDist = require('gulp-npm-dist');
console.timeEnd('Loading plugins');
const sassFiles = 'src/assets/scss/*.scss',
cssDest = 'dist/css/';
//compile scss into css
function style() {
return gulp.src(sassFiles)
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest(cssDest));
}
//This is for the minify css
async function minifycss() {
return gulp.src(['dist/css/*.css', '!dist/css/**/*.min.css'])
.pipe(rename({
suffix: '.min'
}))
.pipe(minifyCSS())
.pipe(gulp.dest(cssDest));
}
// This is for the minifyjs
async function minifyjs() {
return gulp.src(['dist/js/custom.js','dist/js/app.js', '!dist/js/custom.min.js', '!dist/js/app.min.js'] )
.pipe(rename({
suffix: '.min'
}))
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
}
// Copy dependencies to ./public/libs/
async function copy() {
gulp.src(npmDist(), {
base: './node_modules'
})
.pipe(gulp.dest('./src/assets/libs'));
};
async function watch() {
gulp.watch(['src/assets/scss/**/*.scss'], style);
gulp.watch(['dist/css/style.css'], minifycss);
gulp.watch(['dist/js/**/*.js', '!dist/js/**/*.min.js'], minifyjs);
}
gulp.task('default', watch);
exports.style = style;
exports.minifycss = minifycss;
exports.minifyjs = minifyjs;
exports.copy = copy;
exports.watch = watch;
After all, I made some changes to the template scss file, and run gulp command. At this point, the gulp command run never finished unitl now with output on terminal like this
Loading plugins: 539.410ms
[17:01:03] Using gulpfile ~/Documents/documentation/materialpro-bootstrap-latest/material-pro/gulpfile.js
[17:01:03] Starting 'default'...
[17:01:03] Finished 'default' after 18 ms
What was going wrong with this? Please kindly help, thanks.
P.S: Pls apologized if my question is incomplete or something, if I will try to add some more detail if suggested.

Your gulp code is fine. Made some change on your scss or js file it will show some changes.
Exaplantion
Your default command is gulp.task('default', watch);
when you run gulp it starts to watch your scss, css, js code. If there is new change it will execute the command.
Suggestion. Use like this.
async function watch() {
gulp.watch(['src/assets/scss/**/*.scss'], style, minifycss);
gulp.watch(['dist/js/**/*.js', '!dist/js/**/*.min.js'], minifyjs);
}

Related

Task never defined: default, To list available tasks, try running: gulp --tasks

When running the following code I receive the following error:
[23:00:29] Task never defined: default
[23:00:29] To list available tasks, try running: gulp --tasks
gulp -v
CLI version: 2.2.0
Local version: 4.0.1
Can you let me know what I'm doing wrong here?
const gulp = require('gulp');
const sass = require('gulp-sass');
const browserSync = require('browser-sync').create();
//compile scss into css
function style() {
//1. where is my sass file going to be
return gulp.src('./scss/**/*.sass')
//2. pass that file through sass compiler
.pipe(sass())
//3.Where do I save the compiled css
.pipe(gulp.dest('./css'))
}
exports.style = style;
Like the error says, you aren't defining a default task.
Either
run gulp style, or
export style as default (exports.default = style)

gulp can't find module source-map

I'm having an issue with sourcemaps in gulp: when I try to implement gulp-sourcemaps directly through a pipe, but also when I try to feed it in via webpack, which if I've understood correctly, has sourcemaps by default, I keep getting the same confusing error:
Error: Cannot find module 'source-map'
I can see the #gulp-sourcemaps folder in my node_modules, which contains within it an identity-map folder containing a bunch more node_modules including the source-map module in question, so I think everything is hooked up as it should be. That being said, I'm new to gulp, so I might be missing something really obvious.
Can anyone offer me some guidance on how to help gulp find the module?
// package vars
const pkg = require("./package.json");
// gulp
const gulp = require("gulp");
const gulpIf = require("gulp-if");
// webpack
const webpack_config = require("./webpack.config");
// load all plugins in "devDependencies" into the variable $
const $ = require("gulp-load-plugins")({
pattern: ["*"],
scope: ["devDependencies"]
});
// ...
gulp.task("sass", function() {
return gulp
.src(pkg.paths.app.scss + "**/*.scss")
.pipe($.sourcemaps.init())
.pipe($.sass())
.pipe($.autoprefixer())
.pipe($.sourcemaps.write("./maps"))
.pipe(gulp.dest(pkg.paths.app.css))
.pipe(
$.browserSync.reload({
stream: true
})
);
});
// ...
gulp.task("webpack", function() {
return gulp
.src(pkg.paths.app.js + "**/*.js")
.pipe($.webpack(webpack_config))
.pipe(gulp.dest(pkg.paths.public.js));
});
// ...

Gulp play sound on error

Anyone know how to have a sound ( like grunt ) when gulp throw a error during compile/watch ?
l need to setup something special for gulp for have this feature ?
UPDATE: It should be noted that gulp-util has been deprecated and should not be used.
There is the ubituious gulp-util plugin. One of the features that it provides is the "gutil.beep();" function.
in your project's root execute:
npm install gulp-util --save-dev
then in your Gulpfile.js:
var gutil = require('gulp-util');
gutil.beep();
You can work with gulp-plumber which is excellent for handling errors in gulp streams. Setup the errorHandler method which will call the beeper() method provided by the NPM library - beeper
var gulp = require('gulp');
var plumber = require('gulp-plumber');
var sass = require('gulp-sass');
var beeper = require('beeper'); //https://www.npmjs.com/package/beeper
gulp.task('compile-sass', function () {
return gulp.src('blob/for/files.scss')
.pipe(plumber(errorHandler))
.pipe(sass())
.pipe(gulp.dest('dest/'));
});
function errorHandler(error) {
// 3 beeps for error
beeper(3); // https://www.npmjs.com/package/beeper
return true;
}
Now, whenever there is an error in compiling sass, you will get 3 beeps to notify you that there was an error.
Good Luck.
npm install -g gulp-crash-sound
Source: https://www.npmjs.com/package/gulp-crash-sound

Why won't browser-sync update my browser?

Awe, why won't browser sync update chrome. =[ I'm using gulp to run browser sync which appears to be hosting correctly. I've set up the server like this in my gulp file:
var gulp = require('gulp');
var browser = require('browser-sync');
var reload = browser.reload;
gulp.task('webserver', function() {
browser({
server:{
baseDir: './'
}
});
});
gulp.task('reload', function(){reload();});
I run the webserver task in webstorm and I get a new chrome tab with a little message saying "Connected to Browser Sync". Awesome. I also get this in the output window.
[18:47:45] Using gulpfile ...\gulpfile.js
[18:47:45] Starting 'webserver'...
[18:47:45] Finished 'webserver' after 27 ms
[BS] Access URLs:
-------------------------------------
Local: http://localhost:3000
External: http://192.168.1.17:3000
-------------------------------------
UI: http://localhost:3001
UI External: http://192.168.1.17:3001
-------------------------------------
[BS] Serving files from: ./
Everything looks great. Then I change some HTML in my index.html and run the reload task. I get this output:
[19:02:55] Using gulpfile ...\gulpfile.js
[19:02:55] Starting 'reload'...
[19:02:55] Finished 'reload' after 121 μs
Process finished with exit code 0
But the browser isn't updates with my latest content. I've tried to boil this down to the most basic code that should work, but I can't get it to update the browser. =[ Am I missing anything that would keep this from working?
TL;DR
I do believe your answer is how you are watching the files, and then calling load. So basically, if you are using sass or less, or typescript, etc. You need to have your browsersync task:
watch for those files first, then execute their task to transpile (compile) to your .css, .js, etc...
Once it detects the changes in the .css, .js, .html files (which will occur after they transpiler tasks converts them to those files), have it reload the browser.
But whether or not you are using those, you still watch all the folders locations and file extensions. This is done by putting all the locations you are watching into an array, and watching the array of files.
NOTE: Browsersync has a separate .watch() from gulp's watch. Using browsersyncs watch function instead of gulp will see new files, where as gulps watch command does not. See example's below.
I apologize for providing such a needlessly verbose response, but I use gulp-cli (gulp 4) w/ multiple task files and external config), and haven't used gulp 3 in a while, so I will try to port it over in a single task to gulp 3.
Some examples
I am providing both versions since gulp 4 may soon be released. And I will just copy and paste mine, and slightly modify it. And that means I will be using the multiple task files version.
So here is an overview of the two versions that I will provide:
The one I use, which is: gulp 4 w/ multiple task files and an external config
The gulpfile
The external task
The external config
I will also include an example sass and typescript config to show globbing with browser-sync's watch task
The gulpfile with the browser-sync task that I will try to port to gulp 3
1. Gulp 4 w/ multiple task files and external config
I will provide some notes in each file as I do in each of my own. And I will provide install instructions if interested, as I do in each of mine as well. This is mostly for copy and paste reasons. And also I will provide the config for sass and typescript, since it is out of scope for the answer, I will not be providing the task files.
And here is a brief overview of the gulp folder structure to help clarify:
| -- Project-Folder/
| | -- gulp/
| | | -- tasks/
| | | ' -- browser-sync.js
| | ' -- config.js
| ' -- gulpfile.js
The gulpfile
gulpfile.js
// =========================================================
// Project: PROJECT-TITLE
//
// NOTES: Using Gulp 4, in order to use, please uninstall gulp 3 globally and locally, and install gulp 4 both globally and locally
// Dependencies: ---
// Global: npm install -g gulpjs/gulp.git#4.0 browser-sync
// Local: npm install --save-dev gulpjs/gulp.git#4.0 browser-sync gulp-load-plugins
// =========================================================
// ------------------------------------------------ Requires
var gulp = require('gulp'),
config = require('./gulp/config'),
plugins = require('gulp-load-plugins')();
// --------------------function to get tasks from gulp/tasks
function getTask(task) {
return require('./gulp/tasks/' + task)(gulp, plugins);
}
// ---------------------------------------------- Gulp Tasks
gulp.task('sass' , getTask( 'sass' ));
gulp.task('ts' , getTask( 'typescript' ));
gulp.task('sync' , getTask( 'browsersync' ));
// --------------------------------------- Default Gulp Task
gulp.task('default', gulp.series(
gulp.parallel('sass', 'ts'), 'sync')
);
The external task file
browser-sync.js
// =========================================================
// Gulp Task: browsersync
// NOTE: Using gulp v4
// Description: Sync sass, typescript, html, and browser
// using an external config, or modify src and config options
// npm install --save-dev browser-sync gulp-typescript gulpjs/gulp.git#4.0
// Options: node-sass gulp-sass || gulp-ruby-sass
// =========================================================
var config = require( '../config.js' );
var browserSync = require( 'browser-sync' ).create();
module.exports = function( gulp, plugins ) {
return function () {
var stream =
// -------------------------------------------- Start Task
browserSync.init( config.browsersync.opts );
browserSync.watch( config.sass.src, gulp.series( 'sass' ) );
browserSync.watch( config.typescript.src, gulp.series( 'ts' ) );
browserSync.watch( config.browsersync.watch ).on( 'change', browserSync.reload );
// ---------------------------------------------- End Task
return stream;
};
};
The external config
NOTE: These configs are easily added into the tasks file if this seems unnecessary. I am only providing so that I can easily copy and paste some tasks from my own project.
// =========================================================
// Project: PROJECT-TITLE
// =========================================================
// ------------------------------------------ Export Configs
module.exports = {
production: false,
// --------------------------------------------- browsersync
browsersync: {
opts: {
server: './src/',
// proxy: 'localhost:3000',
port: 8000
},
watch: [
'./src/assets/styles/css/**/*.css',
'./src/assets/scripts/js/**/*.js',
'./src/**/*.html'
]
},
// ---------------------------------------------------- sass
sass: {
src: [
"./src/assets/styles/sass/**/*.{scss,sass}"
],
opts: { },
outputName: 'main.css',
dest: './src/assets/styles/css/'
},
// ---------------------------------------------- typescript
typescript: {
src: [
'./src/assets/scripts/ts/**/*.ts'
],
dest: './src/assets/scripts/js',
opts: {
noImplicitAny: true,
}
}
}
Gulp 3 version
NOTE: In the config section, I will only be putting the sass and typescript src folders with extensions, and will leave the rest empty as they are not pertinent to this example.
gulpfile.js
// =========================================================
// Project: PROJECT-TITLE
//
// NOTES: Using Gulp 4, in order to use, please uninstall gulp 3 globally and locally, and install gulp 4 both globally and locally
// Dependencies: ---
// Global: npm install -g gulpjs/gulp.git#4.0 browser-sync
// Local: npm install --save-dev gulpjs/gulp.git#4.0 browser-sync gulp-load-plugins
// =========================================================
// ------------------------------------------------ Requires
var gulp = require( 'gulp' ),
sass = require( 'gulp-sass' ),
ts = require( 'gulp-typescript' )
browsersync = require( 'browser-sync' ).create();
// -------------------------------------------------- Config
var config = {
browsersync = {
opts: {
server: './src/',
// proxy: 'localhost:3000',
port: 8000
},
watch: [
'./src/assets/styles/css/**/*.css',
'./src/assets/scripts/js/**/*.js',
'./src/**/*.html'
]
},
sass = { src: './src/assets/styles/sass/**/*.{scss,sass}', ... },
ts = { src: './src/assets/scripts/ts/**/*.ts', ... }
}
// ---------------------------------------------- Gulp Tasks
gulp.task( 'sass', function() {
// task code here
});
gulp.task( 'ts', function() {
// task code here
});
gulp.task('browsersync', [ 'sass', 'ts' ], function() {
browserSync.init( config.browsersync.opts );
// Transpile your preprocessors to their .css, .js, .html versions first
browserSync.watch( config.sass.src, [ 'sass' ] );
browserSync.watch( config.typescript.src, [ 'ts' ] );
// Then under watch, watch all of the locations in an array glob
// such as in the config object at the top of this file.
// Once the preprocessors change to their .css, .js, .html
// counterparts, that will trigger the reload
browserSync.watch( config.browsersync.watch ).on( 'change', browserSync.reload );
});
// --------------------------------------- Default Gulp Task
gulp.task( 'default', [ 'browsersync' ] );
Again, sorry for the very long and detailed response. Just tried for clarity. I hope it helps you and anyone else in the future.

Importing Sass through npm

Currently in our Sass files we have something like the following:
#import "../../node_modules/some-module/sass/app";
This is bad, because we're not actually sure of the path: it could be ../node_modules, it could be ../../../../../node_modules, because of how npm installs stuff.
Is there a way in Sass that we can search up until we find node_modules? Or even a proper way of including Sass through npm?
If you are looking for a handy answer in 2017 and are using Webpack, this was the easiest I found.
Suppose your module path is like:
node_modules/some-module/sass/app
Then in your main scss file you can use:
#import "~some-module/sass/app";
Tilde operator shall resolve any import as a module.
As Oncle Tom mentioned, the new version of Sass has this new importer option, where every "import" you do on your Sass file will go first through this method. That means that you can then modify the actual url of this method.
I've used require.resolve to locate the actual module entry file.
Have a look at my gulp task and see if it helps you:
'use strict';
var path = require('path'),
gulp = require('gulp'),
sass = require('gulp-sass');
var aliases = {};
/**
* Will look for .scss|sass files inside the node_modules folder
*/
function npmModule(url, file, done) {
// check if the path was already found and cached
if(aliases[url]) {
return done({ file:aliases[url] });
}
// look for modules installed through npm
try {
var newPath = path.relative('./css', require.resolve(url));
aliases[url] = newPath; // cache this request
return done({ file:newPath });
} catch(e) {
// if your module could not be found, just return the original url
aliases[url] = url;
return done({ file:url });
}
}
gulp.task("style", function() {
return gulp.src('./css/app.scss')
.pipe(sass({ importer:npmModule }))
.pipe(gulp.dest('./css'));
});
Now let's say you installed inuit-normalize using node. You can simply "require" it on your Sass file:
#import "inuit-normalize";
I hope that helps you and others. Because adding relative paths is always a pain in the ass :)
You can add another includePaths to your render options.
Plain example
Snippet based on example from Oncle Tom.
var options = {
file: './sample.scss',
includePaths: [
path.join(__dirname, 'bower_components'), // bower
path.join(__dirname, 'node_modules') // npm
]
};
sass.render(options, function(err, result){
console.log(result.css.toString());
});
That should do. You can include the files from package using #import "my-cool-package/super-grid
Webpack and scss-loader example
{
test: /\.scss$/,
loader: 'style!css!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded&sourceMap=true&sourceMapContents=true&includePaths[]=./node_modules'
},
Notice the last argument, includePaths has to be array. Keep in mind to use right format
You can use a Sass importer function to do so. Cf. https://github.com/sass/node-sass#importer--v200.
The following example illustrates node-sass#3.0.0 with node#0.12.2:
Install the bower dependency:
$ bower install sass-mq
$ npm install sass/node-sass#3.0.0-pre
The Sass file:
#import 'sass-mq/mq';
body {
#include mq($from: mobile) {
color: red;
}
#include mq($until: tablet) {
color: blue;
}
}
The node renderer file:
'use strict';
var sass = require('node-sass');
var path = require('path');
var fs = require('fs');
var options = {
file: './sample.scss',
importer: function bowerModule(url, file, done){
var bowerComponent = url.split(path.sep)[0];
if (bowerComponent !== url) {
fs.access(path.join(__dirname, 'bower_components', bowerComponent), fs.R_OK, function(err){
if (err) {
return done({ file: url });
}
var newUrl = path.join(__dirname, 'bower_components', url);
done({ file: newUrl });
})
}
else {
done({ file: url });
}
}
};
sass.render(options, function(err, result){
if (err) {
console.error(err);
return;
}
console.log(result.css.toString());
});
This one is simple and not recursive. The require.resolve function could help to deal with the tree – or wait until npm#3.0.0 to benefit from the flat dependency tree.
I made the sass-npm module specifically for this.
npm install sass-npm
In your SASS:
// Since node_modules/npm-module-name/style.scss exists, this will be imported.
#import "npm-module-name";
// Since just-a-sass-file isn't an installed npm module, it will be imported as a regular SCSS file.
#import "just-a-sass-file";
I normally use gulp-sass (which has the same 'importer' option as regular SASS)
var gulp = require('gulp'),
sass = require('gulp-sass'),
sassNpm = require('sass-npm')();
Then, in your .pipe(sass()), add the importer as an option:
.pipe(sass({
paths: ['public/scss'],
importer: sassNpm.importer,
}))
For dart-sass and commandline user at 2022, just use the --load-path option:
$ npx sass --load-path=node_modules
Important: the whole node_modules folder contains so much, just set it launch extremely slow in watch mode. Your should only set your package paths, eg:
$npx sass -w --load-path=node_modules/foo --load-path=node_modules/bar/scss
From offical docuumentation of Sass, adding ~ to imports should do the job.
However, for some reason it did'nt work for me, and sass compiler still complains that the module cannot be found.
Hence, I tried another method which worked for me without any issues. Here's the solution:
If you are compiling sass files directly from CLI try this:
sass src/main.scss dist/main.css --load-path=node_modules
If you are using npm and/or webpack for compiling sass files, add something like this to the scripts of package.json:
"scripts": {
...
"build": "sass src/main.scss dist/main.css --load-path=node_modules",
...
}
Then Run:
npm run build
Finally, import your modules like this:
#import "some-module/sass/app";
To wrap it up, adding --load-path=node_modules flag solved the issue permanently. For more information you can check:
sass --help

Resources