Gulp concat, uglify handling ES6 exported libraries - javascript

I use Gulp to merge a few javascripts as well as uglify them. When I tried to do it with countUp (can be other script as well) I've got an error.
Uncaught SyntaxError: Unexpected token 'export'
It tries to export the javascript back to the script tag. Now my javascript file is not just one script, but many.
How can I make it work? Is there a tool to convert it to common js or maybe a better way to include it with gulp?
Script
A part of my gulp-file looks like below:
function script() {
return gulp
.src(js.src)
.pipe(concat(js.filename))
.pipe(gulp.dest(js.dest))
.pipe(uglify())
.pipe(rename({ extname: ".min.js" }))
.pipe(gulp.dest(js.dest));
}

You can use a gulp task to convert es6 modules to other types:
const babel = require('gulp-babel'),
gulp.task('es6-commonjs',['clean-temp'], function(){
return gulp.src(['app/*.js','app/**/*.js'])
.pipe(babel({ modules: 'common' }))
.pipe(gulp.dest('dest/temp'));
});
Then use this task in your gulp pipe. More info here.

Related

Transpile a bunch of ES7 js files into compatible files

I have a folder with a bunch of javascript. I want to be able to use recent js syntax (especially await/async). But the target should compatible with most browsers.
Since these javascript files will be used standalone (will be imported in a 3rd party app as plugin), I want to respect these scheme:
src/file1.js ==> dist/file1.js
src/sub/file2.js ==> dist/sub/file2.js
...
each files should be transpiled into a es5 js file.
I'm using gulp 4 as build tool.
How to reach my goal ?
First try : use babel-gulp:
import gulp from 'gulp';
import sourcemaps from 'gulp-sourcemaps';
import babel from 'gulp-babel';
const javascript = () => {
return gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(babel({
"presets": [
["#babel/preset-env", {
"targets": {
"browsers": [">0.25%", "not ie 11", "not op_mini all"]
}
}]
]
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist'));
};
The build succeeds, but at runtime, it fails with ReferenceError: regeneratorRuntime is not defined
Second try, using browserify and #babel/polyfill, inspired from Browserify + Globs (multiple destination)
Added require("#babel/polyfill"); at top of my javascript files.
in gulp file:
const javascript2 = () => {
return gulp.src('src/**/*.js', {
read: false
}) // no need of reading file because browserify does.
.pipe(tap(function(file) {
file.contents = browserify(file.path).bundle();
}))
.pipe(buffer())
.pipe(sourcemaps.init({
loadMaps: true
}))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('dist'));
};
The build succeed, but the file is not transpiled (async keywords remain) and moreover, the whole babel polyfills are included in the output (and it's quite big) which conflicts with the target app (the app is also redefining startsWith function).
It looks like you are trying to set up a development environment. I would suggest using webpack instead of gulp, 'cause it's more relevant these days. Here's the guide I used to set one up: https://www.valentinog.com/blog/webpack-tutorial/.

ES6 imports and require not working properly with gulp/browserify/babelify

I have a simple Gulp configuration to transpile my javascript with babel :
gulp.task('js_dev', function () {
var bundler = browserify({entries: ['js/index.js'], debug: true});
bundler.external('jquery');
return bundler
.transform("babelify", {presets: ["es2015"]})
.bundle()
.on('error', function (err) {
console.error(err);
this.emit('end');
})
.pipe(source('dev.js'))
.pipe(gulp.dest(jsdest));
});
With this, I can import my development files.
But I can't import some package installed with npm (isotope, textfit, babel-polyfill...).
For example, if I import babel-polyfill in my index.js file :
import "babel-polyfill";
No errors with gulp, and the code seems to be added in dev.js, but it's not working, and I can't require it either : it gives an empty Object.
Same things for other npm modules (isotope for example). When I require them, it just gives an empty object. And Isotope is supposed to work with require.
Any idea what's happening ?
Thanks.
Alright, I found it.
My JavaScript files were added to a CMS which already used AMD/Require.js. This conflicts with browserify.
The solution was here.
What about doing:
import BabelPolyfill from "babel-polyfill"

Import and convert JS files using Gulp & Babel

Consider the following files:
//foo.js
(function(){
console.log('working');
})();
//bar.js
import 'foo.js';
Now I'm using gulp to compiled from ES6 to ES5. Here's the relevant task:
gulp.task('build-js', function() {
return gulp.src('bar.js')
.pipe(babel({
presets: ['es2015']
}))
.pipe(gulp.dest('./dist'));
});
My output file looks like this:
'use strict';
require('foo.js');
The isn't the outcome I expected. I want all code to import into the single output file using the ES5 conversion. This way, the single JS file can be loaded in a browser and run correctly. What do I need to do for the desired outcome?
Since bar.js only imports foo.js, the output file should look exactly like foo.js. Also, since foo.js contains only a self executing function, the output file should execute this immediately and log working to the console.
You should add a 'bundle' task if you want to create a single file for the browser. Take a look at browserify or webpack.
http://browserify.org/
https://webpack.github.io/
You usually need to specify an entry point, and the bundler resolves all the dependencies and creates a single js file.
EDIT:
An example task for gulp, using browserify:
var browserify = require('gulp-browserify');
gulp.task('bundle', function() {
gulp.src('./dist/bar.js') // entry point
.pipe(browserify())
.pipe(gulp.dest('./dist'))
});

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();
});

How to use gulp-traceur and gulp-webpack?

I'm trying to compile ES6 js files. I use gulp-traceur and gulp-wepback in gulp pipe line.
gulp.task('default', function () {
return gulp.src('js/app.js')
.pipe(traceur())
.pipe(webpack())
.pipe(concat('app.js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('build/js'));
When running gulp. I take error: Unexpected reserved word. You may need an appropriate loader to handle this file type. On the line which contains a "class" word. (ES6 Syntax)
I can't figure out how to use these plugins together?
This setup would pass 'js/app.js' to traceur, but none of the related files, and webpack will then start from that transpiled file and process the rest as normal JS. I'm actually not even sure webpack will get the transpile version of app.js.
The proper way is to use webpack for the main entry point, and tell webpack to transpile all files it comes across. I'd also recommend using Webpack's uglifyjs logic instead of tacking it on after-the-fact with gulp.
gulp.task('default', function () {
return gulp.src('js/app.js')
.pipe(webpack({
module: {
loaders: [{
test: /^(?!.*(bower_components|node_modules))+.+\.js$/,
loader: 'traceur'
}]
},
plugins: [
new webpack.optimize.UglifyJsPlugin()
]
})
.pipe(concat('app.js'))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('build/js'));
});

Categories

Resources