I have the following gulp file:
var paths = {
all: ['*.js', '**/*.js', 'index.html'],
js: ['*.js', '**/*.js'],
html: 'index.html',
dist: 'dist'
};
var gulp = require("gulp");
var babel = require("gulp-babel");
gulp.task("default", function () {
gulp.src(paths.html)
.pipe(gulp.dest(paths.dist));
return gulp.src(paths.js)
.pipe(babel())
.pipe(gulp.dest(paths.dist));
});
gulp.task('watch', function(){
gulp.watch(paths.all, ['default']);
});
When I run it, I get this error
SyntaxError: d:/project_folder/node_modules/gulp-babel/node_modules/gulp-util/node_modules/beeper/index.js: 'return' outside of function (9:1) ...`
I read somewhere that I shouldn't compile dependencies. I run just gulp with no following flags. So I don't know wehether or not I do compile them. But gulp seems slow because it takes few seconds to get to first task. How to get rid of this error? And am I doing something wrong with dependencies?
Yes, you are currently including all .js files from the current directory, not the source directories. Your application code (lets assume app.js) will "include" your dependencies by using common js requires, such as:
var request = require('request');
In order to actually map the require statements you would want to use a module loader, or packer such as: Browserify or Webpack
The following gulp task will solve the module errors:
var paths = {
all: ['./src**/*.js', 'index.html'],
js: ['./src/**/*.js'],
html: 'index.html',
dist: 'dist'
};
var gulp = require('gulp');
var babel = require('gulp-babel');
gulp.task('default', function () {
gulp.src(paths.html)
.pipe(gulp.dest(paths.dist));
return gulp.src(paths.js)
.pipe(babel())
.pipe(gulp.dest(paths.dist));
});
gulp.task('watch', function(){
gulp.watch(paths.all, ['default']);
});
This only includes all the .js files in the src folder, not **/*.js which will include all *.js files in every folder including node_modules bower_components.
Regarding module loading:
You would probably want to use a loader task to bundle all your client code instead of just copying them to the dist, such as:
gulp.task("webpack", function(callback) {
// run webpack
webpack({
// configuration
}, function(err, stats) {
if(err) throw new gutil.PluginError("webpack", err);
gutil.log("[webpack]", stats.toString({
// output options
}));
callback();
});
});
Related
I have two folders both of which contain some html template files. I need to minify these files to separate folders.
folder structure
|src
|--clientTemplates
|----abc.html
|----xyz.html
|--serverTemplates
|----abc.html
|----xyz.html
required destination folder
|dist
|--client
|----abc.html
|----xyz.html
|--server
|----abc.html
|----xyz.html
following is my gulpfile where I have my tasks defined for the
var gulp = require('gulp');
var htmlmin = require('gulp-htmlmin');
var replace = require('gulp-replace');
var del = require('del');
var minOptions = {
collapseWhitespace: true,
minifyJS: { output: { quote_style: 1 } },
minifyCSS: true
};
gulp.task('clean', function(done) {
del(['dist'], done());
});
gulp.task('minify:serverTemplates', function() {
return gulp
.src('src/serverTemplates/*.html')
.pipe(htmlmin(minOptions))
.pipe(replace('\\', '\\\\'))
.pipe(replace('"', '\\"'))
.pipe(gulp.dest('dist/server'));
});
gulp.task('minify:clientTemplates', function() {
return gulp
.src('src/clientTemplates/*.html')
.pipe(htmlmin(minOptions))
.pipe(gulp.dest('dist/client'));
});
gulp.task(
'default',
gulp.series('clean', 'minify:serverTemplates', 'minify:clientTemplates', function inSeries(done) {
done();
})
);
when I run the gulp command it works fine for the first time, but throws errors on alternate runs.
running gulp command first time
running gulp command second time
can't figure out what exactly is wrong there.
Also is there a way to run the two minification task parallel once the clean task has finished?
thanks for the help.
The callback you pass to del is wrong. Just return the promise:
gulp.task('clean', function() {
return del(['dist']);
});
As for running the minification tasks in parallel, use gulp.parallel:
gulp.task(
'default',
gulp.series(
'clean',
gulp.parallel('minify:serverTemplates', 'minify:clientTemplates')
)
);
I have a problem with the linting and live reloading in my gulp file. They take to much time to finish.
Here is my gulp file, what do I do wrong :
'use strict';
console.time("Loading plugins"); //start measuring
var gulp = require('gulp');
var connect = require('gulp-connect');
var open = require('gulp-open');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var concat = require('gulp-concat');
var babelify = require('babelify');
var sass = require('gulp-sass');
var merge = require('merge-stream'); // Merge all styles (css, sass and less) in one big bundle
var lint = require("gulp-eslint");
var config = {
port: 8001,
devBaseUrl: 'http://localhost',
paths: {
html: "./src/*.html",
externals: "./src/assets/externals/*.js",
js: "./src/**/*.js",
images: './src/assets/images/**/*',
fonts: './src/assets/css/fonts/*',
css: [
"./src/assets/css/*",
],
sass: './src/assets/css/*.scss',
dist: "./dist",
mainJS: "./src/main.js"
}
};
gulp.task('connect', ['watch'], function () {
connect.server({
root: ['dist'],
port: config.port,
base: config.devBaseUrl,
livereload: true,
fallback: './dist/index.html'
})
});
gulp.task('open', ['connect'], function () {
gulp.src('dist/index.html')
.pipe(open({uri: config.devBaseUrl + ":" + config.port + "/"}));
});
gulp.task('html', function () {
gulp.src(config.paths.html)
.pipe(gulp.dest(config.paths.dist))
.pipe(connect.reload());
});
gulp.task('externals', function () {
gulp.src(config.paths.externals)
.on('error', console.error.bind(console))
.pipe(concat('external.js'))
.pipe(gulp.dest(config.paths.dist + '/externals'))
.pipe(connect.reload());
});
gulp.task('js', function () {
browserify(config.paths.mainJS)
.transform('babelify', {presets: ['es2015', 'react']})
.bundle()
.on('error', console.error.bind(console))
.pipe(source('bundle.js'))
.pipe(gulp.dest(config.paths.dist + '/scripts'))
.pipe(connect.reload());
});
gulp.task('images', function () {
gulp.src(config.paths.images)
.pipe(gulp.dest(config.paths.dist + '/images'));
});
gulp.task('styles', function () {
gulp.src(config.paths.css)
.pipe(sass())
.pipe(concat('bundle.css'))
.pipe(gulp.dest(config.paths.dist + '/css'))
.pipe(connect.reload());
});
gulp.task('fonts', function () {
gulp.src(config.paths.fonts)
.pipe(gulp.dest(config.paths.dist + '/css/fonts'));
});
gulp.task('lint', function () {
return gulp.src(config.paths.js)
.pipe(lint())
.pipe(lint.format());
});
gulp.task('watch', function () {
gulp.watch(config.paths.js, ['js', 'lint']);
gulp.watch(config.paths.css, ['styles']);
});
console.timeEnd('Loading plugins');
gulp.task('default', ['js', 'styles', 'lint', 'open', 'watch']);
The lint takes almost 20s to finish and liverolading takes 5-6s to refresh the browser after I make some changes.
Any advice?
Gulp ESLint plugin is generally very slow. I compared it to Grunt at some point (a while back) and it was about 5-10 times slower. Don't know why.
Make sure you are running latest version of ESLint and also that you don't have node_modules directory under your src folder. If you do, you can run eslint with --debug flag to make sure that ESLint is not linting files in your node_modules directory. If for some reason it does, add .eslintignore file and specify everything that you don't want to lint there.
In general, if you want instant feedback while coding, I would suggest looking into editor integrations. Pretty much every editor out there has ESLint plugin at this point. They show you errors directly in the window you are writing your code in.
We've recently come across the same issue on my team. The best workaround was to run ESLint only on the modified files, instead of all js files.
We use nodemon to watch for changed files, though gulp-watch has the same idea.
See the change event on gulp-watch.
Then you'd just run a lint function on the changed file.
You may need to resolve the relative file path.
gulp.watch(config.paths.js, ['js'])
.on('change', lintFile);
const lintFile = (file) => {
return gulp.src(file)
.pipe(eslint());
};
Is it necessary to check you code while developing?
We use another approach:
1)Do not check code while developing, because it is long, also it sometimes doesn't allow to create "fast" mock for something while debugging.
2)Check style only before commit. If something is wrong, fix style and check everything works. Also CI system could control your commits.
So, my suggestion is to remove lint from watch task.
I'm having a strange problem. I'm using gulp to compile a react app and am having it copy index.html to the appropriate web directory. When I first run gulp, all runs as expected, but when the file changes and the watch task is run, gulp copies an empty version of the file to the web directory. Does anyone know why this might be happening? Here is my gulpfile.js:
var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
var livereload = require('gulp-livereload');
gulp.task('livereload', function() {
console.log('reloading');
livereload();
});
gulp.task('copyindextodist', function() {
gulp.src('app/index.html')
.pipe(gulp.dest('dist'));
});
gulp.task('compilejs', function() {
browserify({
entries: 'app/index.js',
extensions: ['.js'],
debug: true
})
.transform('babelify', {presets: ['es2015', 'react']})
.bundle()
.pipe(source('app.js'))
.pipe(gulp.dest('dist'));
});
gulp.task('publishapp', function() {
gulp.src('dist/*.*')
.pipe(gulp.dest('../public'));
});
gulp.task('copypaste', function() {
gulp.src('app/index.html')
.pipe(gulp.dest('../public'));
});
gulp.task('watch', function() {
livereload.listen();
gulp.watch('app/index.html', ['copyindextodist']);
gulp.watch('dist/index.html', ['publishapp']);
gulp.watch('app/index.js', ['compilejs']);
gulp.watch('dist/app.js', ['publishapp']);
});
gulp.task('default', ['copyindextodist', 'compilejs', 'publishapp', 'watch']);
I had the same problem until I defined the dependencies correctly. You can define which tasks should be completed, before the current task starts:
gulp.task('compress', ['copy'], function() {
//.... your job
});
This means that the compress task will wait for the copy task to be finished. If you don't do that, you might end up with empty/truncated files and other strange results.
Just take care that your copy tasks return a stream object.
gulp.task('copy', function() {
// "return" is the important part ;-)
return gulp.src(['filepath/**/*'])
.pipe(gulp.dest('lib/newpath'))
});
If you have multiple copy commands running in your task this is tricky, but there is an extension for this:
var gulp = require('gulp');
var merge = require('merge-stream');
gulp.task('copy', function() {
var allStreams = [
gulp.src(['node_modules/bootstrap/dist/**/*'])
.pipe(gulp.dest('lib/bootstrap')),
gulp.src(['node_modules/jquery/dist/**/*'])
.pipe(gulp.dest('lib/jquery')),
];
return merge.apply(this, allStreams);
});
gulp.task('nextTask', ['copy'], function() {
// this task formerly produced empty files, but now
// has a valid dependency on the copy stream and
// thus has all files available when processed.
});
I have been playing with gulp and babel for the past few days. I am getting a solid grasp of setting up babel with gulp through tutorials. I've noticed that the newer the tutorial the more changes that develop.
Here is one way I was able to set up es6 to es5 with a transpiler.
var gulp = require('gulp');
var babel = require('gulp-babel');
gulp.task('es6to5', function () {
return gulp.src('js/src/app.js')
.pipe(babel())
.pipe(gulp.dest('dist'));
});
However, I do not want to rerun gulp each time, and I want the dist/ folder to update on each save.
I added browser-sync and delete.
var gulp = require('gulp');
var babel = require('gulp-babel');
var browserSync = require('browser-sync');
var del = require('del');
gulp.task('clean:dist', function() {
return del([
'dist/app.js'
]);
});
gulp.task('es6to5', function () {
return gulp.src('js/src/app.js')
.pipe(babel())
.pipe(gulp.dest('dist'));
});
gulp.task("browserSync", function() {
browserSync({
server: {
baseDir: './dist'
}
});
});
gulp.task("copyIndex", ['clean:dist'], function() {
gulp.src("src/index.html")
.pipe(gulp.dest('./dist'))
.pipe(browserSync.reload({stream: true}));
});
gulp.task('watchFiles', function() {
gulp.watch('src/index.html', ['copyIndex']);
gulp.watch('src/**/*.js', ['babelIt']);
});
gulp.task('default', ['clean:dist', 'es6to5','browserSync','watchFiles']);
I set up a default that will clean out the dist folder then run es6to5. Afterwards I want it to sync and update. I called watchFiles last.
However, I am no longer getting updated js files. The files in the dist folder Are not compiling to es5 and everything is going to a 404.
The task
copyIndex seems to be the problem but I am not sure how to fix it or if it is the only problem. Any direction helps.
You have a typo.
It should be gulp.watch('src/**/*.js', ['es6to5']);, not gulp.watch('src/**/*.js', ['babelIt']);
Anyway i suggest to use gulp-watch instead of the built-in watch function. It has several advantages, mainly it recompile on new file creation.
I'm trying to write a gulp task allowing me to use modules in JS (CommonJS is fine), using browserify + 6to5. I also want source mapping to work.
So:
1. I write modules using ES6 syntax.
2. 6to5 transpiles these modules into CommonJS (or other) syntax.
3. Browserify bundles the modules.
4. Source maps refers back to the original ES6 files.
How to write such a task?
Edit: Here's what I have so far:
gulp task
gulp.task('browserify', function() {
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var to5ify = require('6to5ify');
browserify({
debug: true
})
.transform(to5ify)
.require('./app/webroot/js/modules/main.js', {
entry: true
})
.bundle()
.on('error', function(err) {
console.log('Error: ' + err.message);
})
.pipe(source('bundle.js'))
.pipe(gulp.dest(destJs));
});
modules/A.js
function foo() {
console.log('Hello World');
let x = 10;
console.log('x is', x);
}
export {
foo
};
modules/B.js
import {
foo
}
from './A';
function bar() {
foo();
}
export {
bar
};
modules/main.js
import {
bar
}
from './B';
bar();
The code seems to be working, but it's not minified and the source map is inline (which is not really working for production).
Use this as your start point:
var gulp = require('gulp');
var gutil = require('gulp-util');
var sourcemaps = require('gulp-sourcemaps');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var browserify = require('browserify');
var to5ify = require('6to5ify');
var uglify = require('gulp-uglify');
gulp.task('default', function() {
browserify('./src/index.js', { debug: true })
.transform(to5ify)
.bundle()
.on('error', gutil.log.bind(gutil, 'Browserify Error'))
.pipe(source('bundle.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true})) // loads map from browserify file
.pipe(uglify())
.pipe(sourcemaps.write('./')) // writes .map file
.pipe(gulp.dest('./build'));
});
I didn't understand why we had to use certain things in order to get this to work so I'm adding my own answer here. For those looking for a solution with babelify, I added one below. I also thought it'd be good to talk about what each line does.
For those that want to use ES6 in their Gulpfile, you can look here but Gulp supports it if you rename your file to Gulpfile.babel.js as of Gulp 3.9
One big thing to note is you need to use vinyl-source-stream with Browserify in order to convert the output into something Gulp can understand. From there a lot of gulp plugins require vinyl buffers which is why we buffer the source stream.
For those not familiar with sourcemaps, they are essentially a way for you to map your minifed bundled file to the main source file. Chrome and Firefox support it so when you debug you can look at your ES6 code and where it failed.
import gulp from 'gulp';
import uglify from 'gulp-uglify';
import sourcemaps from 'gulp-sourcemaps';
import source from 'vinyl-source-stream';
import buffer from 'vinyl-buffer';
import browserify from 'browserify';
import babel from 'babelify';
gulp.task('scripts', () => {
let bundler = browserify({
entries: ['./js/main.es6.js'], // main js file and files you wish to bundle
debug: true,
extensions: [' ', 'js', 'jsx']
}).transform(babel.configure({
presets: ["es2015"] //sets the preset to transpile to es2015 (you can also just define a .babelrc instead)
}));
// bundler is simply browserify with all presets set
bundler.bundle()
.on('error', function(err) { console.error(err); this.emit('end'); })
.pipe(source('main.es6.js')) // main source file
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true })) // create sourcemap before running edit commands so we know which file to reference
.pipe(uglify()) //minify file
.pipe(rename("main-min.js")) // rename file
.pipe(sourcemaps.write('./', {sourceRoot: './js'})) // sourcemap gets written and references wherever sourceRoot is specified to be
.pipe(gulp.dest('./build/js'));
});
Other useful readings:
Gulp browserify the gulp-y way