Strange gulp syntax - javascript

I am using Gulp v3.9.1, and have run across a gulpfile that is using a syntax that is foreign to me. None of the tasks with this syntax will run.
gulp.task ('serve', [ 'js.lint', 'test' ], () => {
onError = eatError;
browserSync.init ({
ui: false,
files: [
'index2.html',
'tpl/**/*',
opts.srcDir + '/assets/img/**/*',
opts.srcDir + '/assets/less/**/*',
opts.srcDir + '/app/**/*',
opts.testDir + '/**/*',
'src/main/coverage/**/*'
],
proxy: {
target: "localhost:8080",
proxyOptions: {
xfwd: true
}
}
});
gulp.watch ([ 'gulpfile.js', opts.srcDir + '/app/**/*', opts.testDir + '/**/*' ], [ 'js.lint', 'test' ]);
});
In particular, I am referring to the () => on the first line. That is what gulp is complaining about. That syntax looks a little similar to a CoffeScript gulpfile I found, but I am not sure what it is. The project using this gulpfile has a ton of packages, which I am sifting through right now to see if they have anything to do with this syntax. I want to know what the () => represents, and how to get tasks using this syntax to run.

That's the ES2015 syntax for an anonymous function with the outer scope's this as the context.
To get that syntax to work with gulp, make sure the file name is gulpfile.babel.js and not just gulpfile.js. Recent versions of gulp know to look for that file name and transpile it on-the-fly before running it, provided you have Babel installed.

Related

Generate IIFE output with Rollup

I am working on a few web applications and have been trying to use Rollup to bundle my code.
I've made a little program that can do the bundling for me. However I've run into a problem with formatting IIFE.
I've tried other formats like 'es' and 'amd', but ran into different problems. I read a bit and it seems like IIFE is the most fitting format.
I get this error in the console when trying to bundle:
UnhandledPromiseRejectionWarning: Error: UMD and IIFE output formats are not supported for code-splitting builds
Here is the code for the bundling:
function createBundle(slug, destinationPath) {
const config = {
input: './apps/' + slug + '/index.js',
preserveEntrySignatures: false,
plugins: [resolve({preferBuiltins: false}), common()]
}
rollup.rollup(config).then((bundle) => {
bundle.generate({format: 'iife'}).then((result) => { //'es' 'cjs' 'amd'
compileCode('app.js', result.output[0].code, destinationPath);
});
});
}
Does anyone know a fix for this or have suggestions for how to solve it?
Found a bit of an odd solution for this problem.
Uninstalling core-js.

WebPack execute function before build starts

I need to execute one JavaScript function before the Webpack starts its building process. The function just takes .scss files and concatenate them into one.
After that Webpack should take the result file. Is there an option to do that?
At the moment I run the function before the module.exports in webpack.config.js, but it seems that its not synchronous operation. Module.exports execute before the concat() function ends and Webpack can't find .scss file.
function concat(opts) {
(...)
}
concat({ src : styles, dest : './css/style.scss' });
module.exports = [
(...)
]
It seems a little bit odd to concat scss files before running Webpack as those kind of operations are usually handled by Webpack itself.
That being said, there's a few way of solving this.
The most obvious way would be to extract the concat parts to a separate file (e.g. prepare.js) and then run start the build process by running something along this line: node prepare.js && webpack. That'll first run prepare and if that exits without error webpack will be run. Usually that'll be added to the scripts part of your package.json, e.g.
"scripts": {
"build": "node prepare.js && webpack"
}
To achieve the same but in a more Webpack integrated way you could do the same thing where you extract the concat part to a separate file and then let Webpack execute that file, before build starts, with the help of Webpack Shell Plugin, e.g.
const WebpackShellPlugin = require('webpack-shell-plugin');
module.exports = {
...
plugins: [
new WebpackShellPlugin({
onBuildStart:['node prepare.js']
})
],
...
}
You can add any code at any phase of the building, using the Compiler Hooks.
The compile hook is called before (and every time) the compilation begins, so you probably want to use that:
config = {
//...
plugins: [
{
apply: (compiler) => {
compiler.hooks.compile.tap("MyPlugin_compile", () => {
console.log("This code is executed before the compilation begins.");
});
},
},
],
//...
};

Ordering the output using gulp and main-bower-files (gulp-order doesn't work)

Java engineer here, new to the Javascript world, so apologies if I'm not providing enough/correct info!
I have a gulp build script and use bower to manage the dependencies for my JS frontend app. I am struggling to get the (bower controlled) vendor javascript libraries concatenated in the right order so that jQuery and angular come first.
If they aren't first then I get angular is undefined or jQuery is undefined when I load my application, as their corresponding javascript code is buried somewhere further down in the concatenated library.
I've attempted to use gulp-order to order the output from the resulting main-bower-files call, but it appears to have no effect.
My gulp task is as follows:
gulp.task('lib', function () {
var files =
gulp.src(mainBowerFiles({
paths: {
bowerrc: './.bowerrc',
bowerJson: './bower.json'
}, env: 'lib'}))
.pipe(order(["vendor/bower/jquery/**/*.js", "vendor/bower/angular/**/*.js", "vendor/bower/**/*.js" ]))
return processJsFiles('lib', files);
});
processJsFiles does the uglify work and looks pretty much like:
.pipe(uglify(name + '.js', {
outSourceMap: true,
screwIe8: true,
compress: {
hoist_funs: false,
if_return: false
}
}))
.pipe(gulp.dest(build_dir))
.pipe(gzip())
.pipe(gulp.dest(build_dir));
Any clues or better ways I should be doing this?
After much spelunking through the docs I figured out that you need to specify the base of where the order plugin needs to start from, e.g.:
gulp.task('lib', function () {
var files =
gulp.src(mainBowerFiles({
paths: {
bowerrc: './.bowerrc',
bowerJson: './bower.json'
}, env: 'lib'}))
.pipe(order([
"vendor/bower/jquery/**/*.js",
"vendor/bower/angular/**/*.js",
"vendor/bower/**/*.js"
], { base: './' })
);
return processJsFiles('lib', files);
});

How to use both 'gulp-babel' and 'gulp-browserify'

I try to write these code
gulp.task('script', function() {
'use strict'
return gulp.src(['app.js', 'components/**/*.jsx'])
.pipe(babel())
.pipe(browserify())
.pipe(gulp.dest("dist"));
});
but it shows some error:
SyntaxError:
/Users/Zizy/Programming/learn-react-js/components/CommentBox.jsx:58
<div className="commentBox">
^
ParseError: Unexpected token
at wrapWithPluginError (/Users/Zizy/Programming/learn-react-js/node_modules/gulp-browserify/index.js:44:10)
It seems that before .pipe(browserify()) the gulp did't transform the jsx code. But if I just remove .pipe(browserify()) I find that did transform, just cannot let babel and browserify work together.
I know maybe I can use like babelify or browserify plugin for babel though, I just want figure out the reason.
gulp-browserify doesn't quite work like that. You don't give it a bunch of buffers to collect and bundle.
You give it one file—the entry file—which it passes into Browserify. Browserify checks to see what other files the entry file references, then loads those files directly from the file system, meaning that you can't modify them with gulp plugins beforehand.
So, really, if we pretend you don't want to use Babel on your source files, your gulpfile should look like this, only passing in the entry file:
gulp.task('script', function() {
'use strict'
return gulp.src('app.js')
.pipe(browserify())
.pipe(gulp.dest("dist"));
});
However, note that gulp-browserify is no longer maintained, and this is exactly why. gulp plugins aren't supposed to read directly from the file system. That's why you're supposed to use Browserify (or, in your case, Babelify) directly with vinyl-source-stream as recommended in the gulp recipes. It's more idiomatic and less confusing.
That wraps up my answer to your question, but I'd like to add: if you're using the ES2015 module syntax (and you probably should be), there's a better way to do this. Browserify wraps all your modules separately in a bunch of code to make the programmatic CommonJS API work properly, but ES2015 modules have a declarative syntax, which makes it much easier for tools to operate on them statically. There's a tool called Rollup that takes advantage of this, allowing it to produce bundles that are smaller, faster, and more minfication-friendly than Browserify's.
Here's how you might use it with gulp:
var gulp = require('gulp'),
rollup = require('rollup-stream'),
babel = require('gulp-babel'),
source = require('vinyl-source-stream'),
buffer = require('vinyl-buffer');
gulp.task('script', function() {
return rollup({entry: 'app.js'})
.pipe(source('app.js'))
.pipe(buffer())
.pipe(babel())
.pipe(gulp.dest('dist'));
});
Starting from Babel 6 you need to declare the presets manually, check this.
Basically, in the root of your project you need a .babelrc with the following content:
{
"presets": [ "es2015", "react" ]
}
And the corresponding npm modules in package.json:
// package.json
{
"devDependencies": {
...
"babel-preset-es2015": "^6.1.18",
"babel-preset-react": "^6.1.18",
...
}
}
Here is a sample repository with gulp, babel and browserify
Following is the code snippet
gulp.task("js", (done) => {
const bundler = browserify({ entries: paths.js.source }, { debug: true }).transform(babel);
bundler.bundle()
.on("error", function (err) { console.error(err); this.emit("end"); })
.pipe(source(paths.build.destMinJSFileName))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(uglify())
.pipe(sourcemaps.write(paths.js.destMapFolder))
.pipe(gulp.dest(paths.build.destBuildFolder));
done();
});

Grunt plugins not found using load-grunt-config

I've split out my grunt plugins into their own files and I'm using the load-grunt-config (https://github.com/firstandthird/load-grunt-config) to call them:
module.exports = function (grunt) {
'use strict';
require('load-grunt-config')(grunt);
};
I've got sass, autoprefixer, cssmin and watch tasks working but I'm also using Browsersync and px-to-rem these two plugins return:
Warning: Task "remify" not found. Use --force to continue.
and
Warning: Task "browsersync" not found. Use --force to continue.
when called individually or as part of a bigger task.
I've followed the syntax for the separate.js files for these two plugin so I'm at a loss. For example the remify.js file which is called when running grunt is written like this
module.exports = {
dist: {
options: {
base: 16,
fallback: true,
fallback_existing_rem: true,
ignore: []
},
files: {
'css/style.css': 'css/style.css'
}
}
};
Any ideas where this is going wrong?
I've also set up a gist of the example code, include package.json and a aliases.yml
https://gist.github.com/sturobson/f88258fd010e901e24d9
You have to call the grunt plugin exactly what it is. So where I've got remify I should be using px_to_rem and where I've got browsersync and I should have browserSync.
Silly me.
you can pass a second argument to load-grunt-config to provide some options where you could also define some pattern which can be used by load-grunt-tasks which is used internally.
if you don't pass a second argument, it uses the default-pattern of load-grunt-tasks which is grunt-*.
so if you want to load all devDependencies without defining them seperatly, do it like this:
require('load-grunt-config')(grunt, {
loadGruntTasks: {
pattern: '*',
scope: 'devDependencies'
}
});

Categories

Resources