GulpUglifyError:Unable to minify JavaScript - javascript

I am trying to minify my script files for which i am using gulp task runner
And I am trying gulp-uglify plugin
Code:
gulp.task('concat', function() {
return gulp.src('app/**/*.js')
// .pipe(concat('script.js'))
.pipe(uglify())
.pipe(gulp.dest('./dist/'))
});
but i am getting error as
when i try to run gulp task as gulp concat
Any help would be appreciated

The main error is generated when you're using ES6 format. Use the gulp-uglify-es module instead of 'gulp-uglify' to overcome this error.
var uglify = require('gulp-uglify-es').default;
Note: gulp-uglify-es is no longer being maintained. You may want to use terser/gulp-terser instead:

To see the error in console:
var gutil = require('gulp-util');
gulp.task('concat', function() {
return gulp.src('app/**/*.js')
// .pipe(concat('script.js'))
.pipe(uglify())
.on('error', function (err) { gutil.log(gutil.colors.red('[Error]'), err.toString()); })
.pipe(gulp.dest('./dist/'))
});
To find the exact file, with line number of error register and run this task:
var pump = require('pump');
gulp.task('uglify-error-debugging', function (cb) {
pump([
gulp.src('app/**/*.js'),
uglify(),
gulp.dest('./dist/')
], cb);
});

I think the top answers here are not explaining how to get the error. The docs have a section on error handling:
gulp-uglify emits an 'error' event if it is unable to minify a
specific file
So, just capture the error and do whatever you want with it (such as logging to console) to see the filename, line number, and additional info:
uglify().on('error', console.error)
or in a larger context:
gulp.task('foo', () => {
return gulp.src([
'asset/src/js/foo/*.js',
'asset/src/js/bar/*.js',
])
.pipe(uglify().on('error', console.error))
.pipe(concat('bundle.js'))
.pipe(gulp.dest('./'));
});
This gives you a super helpful error!
{ GulpUglifyError: unable to minify JavaScript
at [stack trace])
cause:
{ SyntaxError: Continue not inside a loop or switch
[stack trace]
message: 'Continue not inside a loop or switch',
filename: 'ProductForm.js',
line: 301,
col: 37,
pos: 10331 },
plugin: 'gulp-uglify',
fileName:
'/asset/src/js/foo/ProductForm.js',
showStack: false }

Have you used ES6 format in your script file?
If so try ES5 now because when you do gulp-uglify it doesnt understand ES6 format as of now
and after that try your code
gulp.task('concat', function() {
return gulp.src('app/**/*.js')
.pipe(concat('script.js'))
.pipe(uglify())
.pipe(gulp.dest('./dist/'))
});
and run the task gulp concat it will work

For me, it was a deprecated option "preserveComments" that generated the error (and completely crashed the script).
Found the issue using:
gulp.task('concat', function() {
return gulp.src('app/**/*.js')
.pipe(uglify())
.on('error', function (err) { console.log( err ) })
.pipe(gulp.dest('./dist/'))
});

Try using this
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var minifyJS = require('gulp-minify');
gulp.task('concat', function() {
return gulp.src('app/**/*.js')
.pipe(minifyJS())
.pipe(concat('bundle.min.js'))
.pipe(uglify({ mangle: false }))
.pipe(gulp.dest('./dist/'));
});

you may have syntax error or used ES6 syntax. you can try https://skalman.github.io/UglifyJS-online/ firstly.

The main error to Unable to minifies JavaScript is the path not found. You can use the task usemin For this you need:
$ sudo npm install gulp-usemin --save-dev
$ sudo npm install gulp-livereload --save-dev
$ sudo npm install gulp-util --save-dev
and requires :
var usemin = require('gulp-usemin');
var livereload = require('gulp-livereload');
var gutil = require('gulp-util'); //gutil for error display
gulp.task('usemin',['jshint'], function(){
return gulp.src('./app/index.html')
.pipe(usemin({
css: [minifycss(),rev()],
scripts: [uglify().on('error', function(err) {gutil.log(gutil.colors.red('[Error]'), err.toString());this.emit('end');}),rev()]
}))
.pipe(gulp.dest('dist'))
.pipe(livereload());
});
Change the js: [uglify(), rev()] to scripts: [uglify(), rev()]

Related

Clean-Css task gives error in gulpfile : cannot read property 'on'

I am totally new to gulp and I wanted to add a task to minify and eventually clean any duplicates or unused css. My gulpfile is below, and for the moment I'm still in the process of learning.
I know I will be using post-css and the modules that can go with it, later on. Right now I get an error: "Cannot read property 'on' of undefined at DestroyableTransform.Readable.pipe". It comes from the cleancss task, when I take it out, there's no errors. Any help and suggestions would be appreciated.
//JS
var gulp = require('gulp');
var sass = require('gulp-sass');
var browserSync = require('browser-sync');
var cleancss = require('clean-css');
var autoPrefixer = require('gulp-autoprefixer');
gulp.task('autoPrefixer', function() {
return gulp.src('../css/*.css')
.pipe(autoPrefixer ({
browsers: ['last 2 versions'],
}))
.pipe(gulp.dest('../css'))
});
gulp.task('cleancss', function() {
return gulp.src('../css/*.css')
.pipe(cleancss({compatibility: 'ie8'}))
.pipe(gulp.dest('../css/min'));
});
gulp.task('sass', function(){
return gulp.src('../scss/*.scss')
.pipe(sass().on('error', function(err) {
console.error('\x07'); // so it doesn't just fail (literally) silently!
sass.logError.bind(this)(err);
})) // Converts Sass to CSS with gulp-sass
.pipe(gulp.dest('../css'))
.pipe(autoPrefixer())
.pipe(browserSync.reload({
stream: true
}))
});
gulp.task('watch', ['browserSync','sass','autoPrefixer','cleancss'], function() {
gulp.watch('../scss/*.scss', ['sass']);
gulp.watch('../*.php', browserSync.reload);
gulp.watch('../js/*.js', browserSync.reload);
});
gulp.task('browserSync', function() {
browserSync.init ({
open: 'external',
host: 'testsite.local',
proxy: 'testsite.local',
port: 3000
})
browserSync ({
server: {
baseDir: 'app'
},
})
});
You should use the gulp plugin for cleancss, rather than cleancss directly.
var cleancss = require('gulp-clean-css');
instead of
var cleancss = require('clean-css');
Remember to install it if you haven't done that already:
npm install gulp-clean-css --save-dev
I actually managed to make it work by using "vynil-map" as discussed on here : https://github.com/jakubpawlowicz/clean-css/issues/342. Hope this link could help anybody else having the same problem.

Gulp uglify unable to handle arrow functions

I'm trying to compress my project using gulp-uglify, however gulp seems to throw the error Unexpected token: punc () whenever it encounters an arrow function in the code. Is there anything I can do to fix this? Thank you.
gulp-crash-test.js
// Function with callback to simulate the real code
function test(callback) {
if (typeof callback === "function") callback();
}
// Causes a crash
test(() => {
console.log("Test ran successfully!");
});
// Doesn't cause a crash
test(function () {
console.log("Test ran successfully!");
});
gulpfile.js
var gulp = require("gulp");
var concat = require("gulp-concat");
var uglify = require("gulp-uglify");
gulp.task("scripts", function() {
gulp.src([
"./gulp-crash-test.js"
]).pipe(
concat("gulp-crash-test.min.js")
).pipe(
uglify().on('error', function(e){
console.log(e);
})
).pipe(
gulp.dest("./")
);
});
gulp.task("watch", function() {
gulp.watch("./gulp-crash-test.js", ["scripts"]);
});
gulp.task("default", ["watch", "scripts"]);
Arrow functions are an ES6 feature. Babel (and others) are designed to translate ES6 to ES5 or earlier as part of your build process. Luckily there are Babel plug-ins for Gulp and Grunt. Run Babel before uglify.
https://www.npmjs.com/package/gulp-babel
I hope this steers you in the right direction/somebody can demonstrate some code.
There is no supporting ugilify(minify) tools for ES6 Syntax.
you should be build gulp task after babel compile (es6 -> es5)
1.Install packages
npm install gulp-babel babel-preset-es2015
2.change your code as below.
var gulp = require("gulp");
var concat = require("gulp-concat");
var uglify = require("gulp-uglify");
var babel = require('gulp-babel');
gulp.task("scripts", function() {
return gulp.src(["./gulp-crash-test.js"])
.pipe(babel({presets: ['es2015']}))
.pipe(concat("gulp-crash-test.minjs"))
.pipe(uglify().on('error', function(e){
console.log(e);
}))
.pipe(gulp.dest("./"))
});
You can use babel minify (previously Babili) a library based on babel to minify ES6 code without transpiling:
First install via npm:
npm install --save-dev babel-preset-minify
Then in your gulp file:
var gulp = require('gulp')
var babel = require('gulp-babel')
gulp.task('default', () => {
return gulp.src('src/app.js')
.pipe(babel({presets: ['minify']}))
.pipe(gulp.dest('dist'))
})
It uses babel as a parser, but there is no transpilation.
I tried babeli it kinda sucked. build time took me 40s. And I am not looking to transpile the code into es5 anyway
I prefer using uglify-es follow the descriptions
https://www.npmjs.com/package/uglify-es
https://www.npmjs.com/package/gulp-uglify
My build times are now 10s. I have the patience to wait 10s.
This is my gulpfile
var gulp = require('gulp');
var uglifycss = require('gulp-uglifycss');
var htmlminifier = require('gulp-html-minifier');
var useref = require('gulp-useref');
var gulpif = require('gulp-if');
var clean = require('gulp-clean');
var uglifyes = require('uglify-es');
var composer = require('gulp-uglify/composer');
var minifyes = composer(uglifyes, console);
.pipe(gulpif('*.js', minifyes()))
This is what i use for useref with angular and babel.
gulp.task('concat-js', ['your dependency task'],function(){
return gulp.src('dev/dev_index/index.html')
.pipe(useref())
.pipe(gulpif('*.js', ngAnnotate())) // if you use angular
.pipe(gulpif('*.js',babel({
compact: false,
presets: [['es2015', {modules: false}]]
})))
.pipe(gulpif('*.js', uglify({ compress: false })
.pipe(gulp.dest('./'));
});
first 'babel' the .js file
var babel = require('gulp-babel');
gulp.task('babel-js', () =>
gulp.src('js/main.js')
.pipe(babel({presets: ['env']}))
.pipe(gulp.dest('build/babel'))
);
https://www.npmjs.com/package/gulp-babel
than 'uglify' it
var uglify = require('gulp-uglify'), pump = require('pump');
gulp.task('uglify-js', function (cb) {
pump([
gulp.src('build/babel/main.js'),
uglify(),
gulp.dest('build/js')
],
cb
);
});
https://www.npmjs.com/package/gulp-uglify
To be installed
npm install --save-dev gulp-babel babel-core babel-preset-env
npm install uglify-es -g
npm install pump

Gulp-browserify Error

I am pretty new to gulp and browserify. I have written a gulpfile.js like this.
gulp.task('default', function (done) {
var b = browserify({
entries: ['app/app.js'],
});
var browserifiedCode = b
.transform(bulkify)
.bundle()
.on('error', function(err) {
gutil.log('Browserify Error', gutil.colors.red(err));
gutil.beep();
this.emit('end');
})
.pipe(source('app.browserified.js')) --> what does it mean ??
.pipe(buffer());
var nonBrowserifyLibraries = [];
var output = gulpMerge(
gulp.src(nonBrowserifyLibraries),
browserifiedCode
)
.pipe(concat('app.js'));
//output = output.pipe(uglify());
return output.pipe(gulp.dest('./'));
After running gulp it is creating app.js but when I am running it in browser then I am getting error Uncaught TypeError: fs.readdirSync is not a function
Can any one help me out.
Thanks
EDITED : I am using bulk-require which somewhere has fs.readdirSync(abc) , I am sure it is creating a problem.
Even without gulp when I did browserify app/app.js -o app.js and loaded this app.js in browser still I got the same fs.readdirSync error.
Try the following snippet, specific for only browserify task.
gulp.task('browserify', function () {
return browserify('app/app.js') // main source file
.bundle()
.pipe(source('app.js'))
.pipe(gulp.dest('dist/app.js')); // destination file
});

Gulp 4 & BrowserSync: Style Injection?

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

Prevent browserify from including module's dependencies

I'd like to use my NodeJS module in the browser - so I'm using browserify to process it.
Now, how can I stop browserify from including the module's dependencies in the bundle file? In this case the dependency is lodash and I'll be loading it separately in the index.html.
Here's what I've got so far:
index.html
<script src="lodash.js"></script>
<script src="my-module.js"></script>
index.js
var _ = require('lodash');
_.each([0, 1, 2], function(item) {
console.log(item);
});
gulp.js
var browserify = require('browserify'),
source = require('vinyl-source-stream');
gulp.task('browserify', function() {
return browserify()
.require('./index.js', {
expose: 'my-module'
})
.bundle()
.pipe(source('my-module.js'))
.pipe(gulp.dest('./'));
});
browserify-shim offers the option of setting up globals.
Here are the changes I've made to my code.
package.json
{
"browserify-shim": {
"lodash": "global:_"
},
"browserify": {
"transform": ["browserify-shim"]
}
}
gulp.js
gulp.task('browserify', function() {
return browserify('./index.js')
.require('./index.js', {
expose: 'my-module'
})
.transform('browserify-shim', {
global: true
})
.bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest('./'));
});
There's an option to exclude files:
Usage: browserify [entry files] {OPTIONS}
[...]
--ignore, -i Replace a file with an empty stub. Files can be globs.
--exclude, -u Omit a file from the output bundle. Files can be globs.
https://github.com/substack/node-browserify#usage
And the corresponding exclude function:
b.exclude(file)
Prevent the module name or file at file from showing up in the output bundle.
If your code tries to require() that file it will throw unless you've provided another mechanism for loading it.
So you should try this:
return browserify()
.require('./index.js', {
expose: 'my-module'
})
.exclude('lodash.js')
.bundle();
I figured this out.
const nodeOnlyModule = eval('require')('module-name');
This way you can trick browserify.

Categories

Resources