How to use uglify-es with gulp? - javascript

I'm using gulp to uglify my files and it works fine for older Javascript.
There has already been a question about how to uglify an ES6-javascript file: how to uglify javascript classes?
That's because my code does not work (classes are ES5 or smth):
gulp.task('handleJs', () => {
gulp.src('src/frontend/xy/js/file.js')
.pipe(uglify());
}
The answer doesn't seem to be up-to-date anymore because uglify-js-harmony is deprecated (https://www.npmjs.com/package/uglify-js-harmony).
It says, I should use uglify-es (not -js) but I don't find a solution, how to use it with gulp? Which npm-packages do I really need for that and how does the code have to look like?

This is documented to a degree in the README for gulp-uglify. For clarity, I've slightly modified the example there to match your snippet.
You need to npm install the pump, gulp-uglify, and uglify-es packages first (along with any other packages your project needs. Then, you can setup your gulp task similar to as follows:
var uglifyjs = require('uglify-es');
var composer = require('gulp-uglify/composer');
var pump = require('pump');
var minify = composer(uglifyjs, console);
gulp.task('handleJs', function (cb) {
var options = {};
pump([
gulp.src('src/frontend/xy/js/file.js'),
minify(options),
gulp.dest('dist')
],
cb
);
});

Related

gulp error with formatting

I am learning to use gulp and have followed through a tutorial. I am trying to concat js files my code is:
var gulp = require('gulp'),
concat = require('gulp-concat');
gulp.task["concatScripts", function() {
return gulp.src(['js/jquery.js',
'js/foundation.equalizer.js', 'js/foundation.reveal.js'])
.pipe(concat("app.js"))
.pip(gulp.dest("js"));
}];
my error code is:
$ gulp concatScripts
[21:33:21] Using gulpfile ~\Documents\Treehouse notes\website-optimization\work\gulpfile.js
[21:33:21] Task 'concatScripts' is not in your gulpfile
[21:33:21] Please check the documentation for proper gulpfile formatting
Can anyone see where I am going wrong? Also it did not state to, however I linked the gulp.js file to write the code for gulp in to my html, is this correct?
Thank you in advance.
Check the documentation at gulp-concat and the code example: Instead of calling gulp.task[' you should make a function call:
var gulp = require('gulp'),
concat = require('gulp-concat');
gulp.task('concatScripts', function() {
return gulp.src('./js/*.js') // <-- Or an array of files
.pipe(concat('app.js'))
.pipe(gulp.dest('./js/'));
});

How to create a single codebase that works with both google apps script and browser?

This is an issue that I can't get my head around of how to get it working the best way, i.e. when updates are made to the codebase BOTH google apps script Docs Add-on and browser version are updated.
Let’s say I have a google apps script project that I want to publish, available both for Docs as an add-on and for the browser. This project however has a different implementation for the GAS version compared to the browser version.
Unfortunately, Browserify cannot be an option anymore as it appears to have broken backwards compatibility with Browserify in GAS. Any suggestion on how to tackle this problem?
One way is to us a tool like Gulp Expose.
https://www.npmjs.com/package/gulp-expose
For you browser build you would expose to window. For your apps script build you would expose to this. Here is an example a Gulp task that builds a module out of Apps Script code. This is from the official Apps Script Oauth2 library found at https://github.com/googlesamples/apps-script-oauth2
var gulp = require('gulp');
var concat = require('gulp-concat');
var expose = require('gulp-expose');
var stripLine = require('gulp-strip-line');
var gulpif = require('gulp-if');
var del = require('del');
var rename = require("gulp-rename");
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
gulp.task('dist', ['clean'], function() {
gulp.src('src/*.gs')
.pipe(gulpif(/OAuth2\.gs$/,
stripLine('var _ =')))
.pipe(concat('OAuth2.gs'))
.pipe(expose('this', 'OAuth2'))
.pipe(gulp.dest('dist'));
gulp.src('node_modules/underscore/underscore.js')
.pipe(rename('Underscore.gs'))
.pipe(gulp.dest('dist'));
});
gulp.task('clean', function() {
del([
'dist/*'
]);
});
gulp.task('lint', function() {
return gulp.src('src/*.gs')
.pipe(jshint())
.pipe(jshint.reporter(stylish));
});

How to set up gulp to bundle several files into one?

This seems like a very simple question, but spent the last 3 hours researching it, discovering it can be slow on every save on a new file if not using watchify.
This is my directory tree:
gulpfile.js
package.json
www/
default.htm
<script src="toBundleJsHere/file123.js"></script>
toBundletheseJs/
componentX/
file1.js
componentY/
file2.js
componentZ/
file3.js
toPutBundledJsHere/
file123.js
Requirements.
On every creation or save of a file within the folder toBundleTheseJs/ I want this file to be rebundled into toBundleJsHere/
What do I need to include in my package.json file?
And whats the minimum I need to write into my gulp file?
This should be as fast as possible so think I should be using browserify and watchify. I want to understand the minimum steps so using package manager like jspm is overkill a this point.
thanks
First you should listen to changes in the desired dir:
watch(['toBundletheseJs/**/*.js'], function () {
gulp.run('bundle-js');
});
Then the bundle-js task should bundle your files. A recommended way is gulp-concat:
var concat = require('gulp-concat');
var gulp = require('gulp');
gulp.task('bundle-js', function() {
return gulp.src('toBundletheseJs/**/*.js')
.pipe(concat('file123.js'))
.pipe(gulp.dest('./toPutBundledJsHere/'));
});
The right answer is: there is no legit need for concatenating JS files using gulp. Therefore you should never do that.
Instead, look into proper JS bundlers that will properly concatenate your files organizing them according to some established format, like commonsjs, amd, umd, etc.
Here's a list of more appropriate tools:
Webpack
Rollup
Parcel
Note that my answer is around end of 2020, so if you're reading this in a somewhat distant future keep in mind the javascript community travels fast so that new and better tools may be around.
var gulp = require('gulp');
var concat = require('gulp-concat');
gulp.task('js', function (done) {
// array of all the js paths you want to bundle.
var scriptSources = ['./node_modules/idb/lib/idb.js', 'js/**/*.js'];
gulp.src(scriptSources)
// name of the new file all your js files are to be bundled to.
.pipe(concat('all.js'))
// the destination where the new bundled file is going to be saved to.
.pipe(gulp.dest('dist/js'));
done();
});
Use this code to bundle several files into one.
gulp.task('scripts', function() {
return gulp.src(['./lib/file3.js', './lib/file1.js', './lib/file2.js']) //files separated by comma
.pipe(concat('script.js')) //resultant file name
.pipe(gulp.dest('./dist/')); //Destination where file to be exported
});

How to conditionally compile (using Grunt) only changed jade files with template includes

Using a version of what grunt-contrib-watch recommends for compiling only changed files in here: https://github.com/gruntjs/grunt-contrib-watch#compiling-files-as-needed
var changedFiles = Object.create(null);
var onChange = grunt.util._.debounce(function() {
grunt.config('jshint.all.src', Object.keys(changedFiles));
changedFiles = Object.create(null);
}, 200);
grunt.event.on('watch', function(action, filepath) {
changedFiles[filepath] = action;
onChange();
});
This works fine (again with a variation I wrote for it here: https://gist.github.com/pgilad/6897875)
The problem is when using include inside Jade templates, meaning you are including other Jade templates in order to build the complete html file.
Using the singular solution for compile doesn't work because if a .jade file you are working on is embeded using include current_working_jade.jade - the including file won't get recompiled.
Are there any workarounds for this besides compiling all of your jade files from scratch? This causes a problem when you have around ~60 large jade files to compile every time.
The only possible solution I can think of is either mapping jade templates dependencies either externally or with directories, but I don't know any tools/plugins which do that...
After already starting to work on a scaffold that will generate a sortof jade sourcemap I found this great project, that already solves this issue:
Jade Inheritance
Usage is as follows:
Install package using: npm install jade-inheritance --save-dev
Where you want to get a list of dependent files from a jade:
var JadeInheritance = require('jade-inheritance');
var inheritance = new JadeInheritance(file, basedirname, {basedir:basedirname});
Then when you want to get the file:
depenedentFiles = inheritance.files;
The project also demonstrates how to apply the concept with grunt.watch in order to compile only changed jade files with their dependents, exactly what I needed:
Using jade-inheritance with grunt watch
I imagine something like checking all jade files and if they include your changed file then recompile that as well. Shouldn't be too hard. Pseudo code:
var allFiles = getAllJadeFileWithIncludesAndProjectPathMap();
//allFiles now contains something like this
{
'jade/index.jade': ['jade/menu.jade', 'jade/home.jade'],
'jade/about.jade': ['jade/menu.jade']
}
var rootFiles = [];
_.each(allFiles, function (includes, parent) {
_.each(includes, function (includePath) {
var parent;
while (parent = getParentPath(includePath)) {
//nothing needed if getParentPath returns null for files that aren't included
}
if (rootFiles.indexOf(parent) !== -1) {
rootFiles.push(parent);
}
});
});
Now add these files to the compile task.

How do you compile CoffeeScript in a Jakefile?

I would like to create a Jakefile which compiles some CoffeeScripts to install a NodeJS application.
How do you do that?
I tried with:
https://gist.github.com/1241827
but it's a weak approach, definitely not classy.
Any hints?
Approx snippet I have used:
var fs = require('fs')
var coffee = require('coffee-script')
// If you'd like to see compiled code..
// console.log(coffee.compile(fs.readFileSync('coffee.coffee')))
// ..otherwise
fs.writeFileSync('output.js', coffee.compile(fs.readFileSync('input.coffee')))
..assumes you have the coffee-script node module installed, of course.
Translated from this Cakefile of mine.

Categories