I have a js linting task:
js-lint.js
import eslint from 'gulp-eslint';
import gulp from 'gulp';
import util from 'gulp-util';
import config from '../config';
gulp.task('js-lint', (callback) => {
gulp
.src(config.js.lint)
.pipe(eslint({ envs: ['browser'] }))
.pipe(eslint.format())
.on('end', callback);
});
This and other tasks are used in my main gulpfile like so:
gulpfile.babel.js
gulp.task('build', (callback) => {
runSequence(
'clean',
'js-lint',
'scss-lint',
[
'fonts',
'images:production',
'js:production',
'scss:production',
'svg-sprite:production',
],
callback,
);
});
The build task runs clean and js-lint (which passes) but then stops the runSequence. If I comment out the usage of js-lint the build completes as expected.
I am not using eslint.failAfterError() and the linting is working correctly as expected. So why does the process stop?
Related
I am trying to create a gulpfile.js to compile scss to css and JS components to a main JS file. But it's not working properly.
The issues i am facing, when I run the command gulp:
It doesn't compile JS components to a main JS file.
It compiles SCSS but when i save any file, the git-bash terminal executing files infinitely, here is the screenshot:
Here is my gulpfile.js:
"use strict";
const source = 'assets/';
// Load Modules
const { src, dest, watch, series } = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const postcss = require('gulp-postcss');
const cssnano = require('cssnano');
const terser = require('gulp-terser');
const browsersync = require('browser-sync').create();
// Scss Task
function scssTask() {
return src(`${source}/scss/zaincss.scss`)
.pipe(sass())
.pipe(postcss([cssnano()]))
.pipe(dest(`${source}/css`));
}
// Javascript Task
function jsTask() {
return src(`${source}/js/scripts/*.js`)
.pipe(terser())
.pipe(dest(`${source}/js/scripts/`));
}
// BrowserSync Tasks
function browserSyncServe(done) {
browsersync.init({
server: {
baseDir: '.'
},
injectChanges: true
});
done()
}
function browserSyncReload(done) {
browsersync.reload();
done();
}
// Watch Task
function watchTask() {
watch('*.html', browserSyncReload);
watch(['assets/scss/**/*.scss', 'assets/js/**/*.js'], series(scssTask, jsTask, browserSyncReload));
}
// Default Gulp Task
exports.default = series(
scssTask, jsTask, browserSyncServe, watchTask
);
I have googled a lot, but i am stuck. Please help me.
Part of the problem is you are watching the same directory that you are storing your js files in:
// Javascript Task
function jsTask() {
return src(`${source}/js/scripts/*.js`)
.pipe(terser())
.pipe(dest(`${source}/js/scripts/`));
}
So you send the files to ${source}/js/scripts/ but you are watching that location in your watch task: 'assets/js/**/*.js'. So any change in that location starts the process all over again.
Store you minified js files someplace else than the same directory you are watching for changes.
So for some reason, I'm having some problems with my gulp scripts where gulp scripts won't write the appropriate js to the bundled file.
So I have the following folder structure:
theme/
- dist/
--- css/
----- bundle.css
--- js
----- bundle.js
- src/
--- scss/
----- bundle.scss
--- js/
----- bundle.js
----- components/
------- test.js
Here is the gulp styles task which works perfect - What it does is that it takes all of the contents inside src/scss/ and bundles it and exports it to dist/css/bundle.css.
export const styles = () => {
return src(['src/scss/bundle.scss', 'src/scss/admin.scss', 'src/scss/bulmapress.scss'])
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(cleanCss({compatibility:'ie8'})
.pipe(dest('dist/css'))
.pipe(server.stream());
}
My src/scss/bundle.scss file has the following:
#import "components/header";
#import "components/footer";
Here is the task that I have for gulp scripts where once I run the task, it doesn't compile the content inside src/js/components etc.. it compiled things that are inside src/js/bundle.js which is just a storage component to define import "components/test". Here is the task:
export const scripts = () => {
return src(['src/js/bundle.js'])
.pipe(dest('dist/js'));
}
I'm not sure what I'm doing wrong, or if this is natural behavior? What might be a better alternative to do this? Below is the full gulpfile.babel.js if anyone wants to check it out.
Would it be better for js to not be bundled into bundle.js and just be minimized into it's own separate file?
import { src, dest, watch, series, parallel } from 'gulp'; //import { src, dest, watch, series, parallel } from 'gulp';
import yargs from 'yargs';
import sass from 'gulp-sass';
import cleanCss from 'gulp-clean-css';
import gulpif from 'gulp-if';
import sourcemaps from 'gulp-sourcemaps';
import imagemin from 'gulp-imagemin';
import del from 'del';
import browserSync from "browser-sync";
import zip from "gulp-zip";
import info from "./package.json";
import replace from "gulp-replace";
const PRODUCTION = yargs.argv.prod;
const server = browserSync.create();
export const serve = done => {
server.init({
proxy: "http://localhost:8888/starter"
});
done();
};
export const reload = done => {
server.reload();
done();
};
export const styles = () => {
return src(['src/scss/bundle.scss', 'src/scss/admin.scss', 'src/scss/bulmapress.scss'])
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(cleanCss({compatibility:'ie8'})
.pipe(dest('dist/css'))
.pipe(server.stream());
}
export const scripts = () => {
return src(['src/js/bundle.js'])
.pipe(dest('dist/js'));
}
You have to transpile ES6 code to ES5 code using gulp-babel before you do uglification or minification.
Read this article about gulp tasks to understand how gulp works:
https://medium.com/#sudoanushil/how-to-write-gulp-tasks-ce1b1b7a7e81
I am using browserify and babel to compile and bundle my react app. The files from client/ are bundled up into a single file static/bundle.js. But I use a relative import which seems to not be handled correctly.
Here's my file structure
client/
components/
main.js
App.js
static/
bundle.js
gulpfile.js
and here's my gulpfile and the offending import
// client/App.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import App from './components/main.js';
render(
<App />,
document.getElementById('root'),
);
// gulpfile.js
var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
gulp.task('build', function() {
browserify({
entries: 'client/App.js',
extensions: ['.js'],
debug: true
})
.transform(babelify, {presets: ['es2015', 'react']})
.bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest('static'));
});
The problem is the line import App from './components/main.js';.
When I look in static/bundle.js, there is a line var _main = require('./components/main.js');, which doesn't make sense because relative to bundle.js there is no ./components/main.js. That was defined relative to client/App.js.
Does browserify not handle such things and is there another tool I should be using in addition, or am I doing something else incorrect?
You have to add paths to your browserify options. If you do not add that browserify doesn't know where to look for to find your module.
module.exports = function(grunt){
grunt.initConfig({
browserify: {
options:{
browserifyOptions: {
// ...
paths: [
'./node_modules',
'./client'
]
}
},
// ...
},
// ...
});
}
This was an issue before they solve it.
I have a gulp project that runs certain tasks in a particular order. I'm trying to use browserSync to inject CSS styles as the sources are changed then compiled, same with my HTML files. I've tried various methods to get browserSync to update my changes such as appending browserSync.reload in my tasks, as well as adding .on('change', reload) to the end of the files I want to watch in my watch task.
My watch task:
import gulp from 'gulp';
import config from '../config';
import browserSync from 'browser-sync';
gulp.task('watch', () => {
const reload = browserSync.reload;
gulp.watch(config.src.styles, ['styles']).on('change', reload);
gulp.watch(config.src.js, ['browserify']).on('change', reload);
gulp.watch(config.src.views, ['pug']).on('change', reload);
});
Styles task:
import gulp from 'gulp';
import sass from 'gulp-sass';
import gulpif from 'gulp-if';
import sourcemaps from 'gulp-sourcemaps';
import browserSync from 'browser-sync';
import autoprefixer from 'gulp-autoprefixer';
import handleErrors from '../util/handle-errors';
import config from '../config';
// SASS -> CSS
gulp.task('styles', () => {
//const reload = browserSync.reload;
return gulp.src(config.src.styles)
.pipe(gulpif(!global.isProd, sourcemaps.init()))
.pipe(sass({
sourceComments: global.isProd ? false : 'map',
outputStyle: global.isProd ? 'compressed' : 'nested'
}))
.on('error', handleErrors)
.pipe(autoprefixer('last 2 versions', '> 1%', 'ie 8'))
.pipe(gulpif(!global.isProd, sourcemaps.write('.')))
.pipe(gulp.dest(config.dest.styles))
.pipe(browserSync.stream()); // stream
//.pipe(gulpif(browserSync.active, browserSync.reload({ stream: true })));
});
Is there anything I can check further or that needs to be changed?
Not sure if you are still looking for an answer, but for reference:
If you are running the browserSync.stream() pipe and the on('change', reload) watch function that might be what is causing your issue. When using Browsersync you want to use one or the other for each task as they do the same; one is inline in the task vs. the other gets called with the watch. In my case I like using the restart action on the watch in the array function as shown below.
gulp.task('styles', () => {
return gulp.src(config.src.styles)
.pipe(gulpif(!global.isProd, sourcemaps.init()))
.pipe(sass({
sourceComments: global.isProd ? false : 'map',
outputStyle: global.isProd ? 'compressed' : 'nested'
}))
.on('error', handleErrors)
.pipe(autoprefixer('last 2 versions', '> 1%', 'ie 8'))
.pipe(gulpif(!global.isProd, sourcemaps.write('.')))
.pipe(gulp.dest(config.dest.styles))
});
gulp.task('watch', () => {
gulp.watch(config.src.styles, ['styles',browserSync.reload]);
gulp.watch(config.src.js, ['browserify', browserSync.reload]);
gulp.watch(config.src.views, ['pug', browserSync.reload]);
});
I'm attempting to use browser-sync with Gulp 4, but bs is not preserving state, and instead does a full refresh. This is not very useful. It seems bs no longer supports true injection. I filed an issue on GH if you want to contribute.
Here is the pertinent code:
// styles:dev task
gulp.task('styles:dev', function() {
return gulp.src(config.src)
.pipe(sourcemaps.init())
.pipe(postcss(config.postcss.dev))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(config.dest.dev))
.pipe(browserSync.stream());
});
// browserSync task
gulp.task('browserSync', function(cb) {
browserSync.init(config, cb);
});
// Watch task:
gulp.task('watch:styles', function() {
return gulp.watch(config.paths.css,
gulp.series('styles:dev'));
});
gulp.task('watch', gulp.parallel('watch:styles'));
// default task
gulp.task('default',
gulp.series('clean:dev',
gulp.parallel('copy:dev', 'styles:dev'), 'browserSync', 'watch')
);
Thanks in advance.
Fixed. Here's where I went wrong:
The browser-sync constructor takes an options object, which can include a files array. Most of the tutorials I've read, including the gulpfile for Google's very own Web Starter Kit, do not include this. As it turns out, this is required for style injection to preserve state.
Furthermore, do not pass .stream() or .reload() as the final pipe in your styles task. It is not needed, and will short circuit style injection, forcing a full refresh.
Finally, the browserSync process must not be terminated, and watch and browserSync tasks must execute in parallel in order for live style injection to take place.
Hope this helps anybody facing this issue.
I also closed the corresponding github issue, and posted my gulpfile
Almost 3 years later Gulp 4 now looks a little bit different, see https://gulpjs.com/docs/en/getting-started/creating-tasks
To have a complete Gulp 4 kickstart example, see https://gist.github.com/leymannx/8f6a75e8ad5055276a71d2901813726e
// Requires Gulp v4.
// $ npm uninstall --global gulp gulp-cli
// $ rm /usr/local/share/man/man1/gulp.1
// $ npm install --global gulp-cli
// $ npm install
const { src, dest, watch, series, parallel } = require('gulp');
const browsersync = require('browser-sync').create();
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const sourcemaps = require('gulp-sourcemaps');
const plumber = require('gulp-plumber');
const sasslint = require('gulp-sass-lint');
const cache = require('gulp-cached');
// Compile CSS from Sass.
function buildStyles() {
return src('scss/ix_experience.scss')
.pipe(plumber()) // Global error listener.
.pipe(sourcemaps.init())
.pipe(sass({ outputStyle: 'compressed' }))
.pipe(autoprefixer(['last 15 versions', '> 1%', 'ie 8', 'ie 7']))
.pipe(sourcemaps.write())
.pipe(dest('css/'))
.pipe(browsersync.reload({ stream: true }));
}
// Watch changes on all *.scss files, lint them and
// trigger buildStyles() at the end.
function watchFiles() {
watch(
['scss/*.scss', 'scss/**/*.scss'],
{ events: 'all', ignoreInitial: false },
series(sassLint, buildStyles)
);
}
// Init BrowserSync.
function browserSync(done) {
browsersync.init({
proxy: 'blog.localhost', // Change this value to match your local URL.
socket: {
domain: 'localhost:3000'
}
});
done();
}
// Init Sass linter.
function sassLint() {
return src(['scss/*.scss', 'scss/**/*.scss'])
.pipe(cache('sasslint'))
.pipe(sasslint({
configFile: '.sass-lint.yml'
}))
.pipe(sasslint.format())
.pipe(sasslint.failOnError());
}
// Export commands.
exports.default = parallel(browserSync, watchFiles); // $ gulp
exports.sass = buildStyles; // $ gulp sass
exports.watch = watchFiles; // $ gulp watch
exports.build = series(buildStyles); // $ gulp build