Problem with minified js file when using Gulp - javascript

I'm having some problems with gulp with the generated minified files... The following section:
for (const counter of counters) {
//...
}
Is being minified as:
for(const n of n){/**etc...*/}
Which brings problems of variable initialization...
My package.json is using these dependencies:
"devDependencies": {
"del": "^3.0.0",
"gulp": "^4.0.0",
"gulp-concat": "^2.6.1",
"gulp-cssmin": "^0.2.0",
"gulp-htmlmin": "^3.0.0",
"gulp-terser": "^1.4.0",
"gulp-uglify": "^3.0.0",
"merge-stream": "^1.0.1"
}
And the gulpfile.js looks as follow:
'use strict';
var gulp = require('gulp'),
concat = require('gulp-concat'),
cssmin = require('gulp-cssmin'),
htmlmin = require('gulp-htmlmin'),
uglify = require('gulp-uglify'),
merge = require('merge-stream'),
del = require('del'),
bundleconfig = require('./bundleconfig.json'); // this file contains the route for the original js files
const terser = require('gulp-terser');
const regex = {
js: /\.js$/
};
// I've removed css and html minification operations
gulp.task('min:js', async function () {
merge(getBundles(regex.js).map(bundle => {
return gulp.src(bundle.inputFiles, { base: '.' })
.pipe(concat(bundle.outputFileName))
.pipe(terser())
.pipe(gulp.dest('.'));
}))
});
gulp.task('min', gulp.series(['min:js']));
gulp.task('clean', () => {
return del(bundleconfig.map(bundle => bundle.outputFileName));
});
gulp.task('watch', () => {
getBundles(regex.js).forEach(
bundle => gulp.watch(bundle.inputFiles, gulp.series(["min:js"])));
});
const getBundles = (regexPattern) => {
return bundleconfig.filter(bundle => {
return regexPattern.test(bundle.outputFileName);
});
};
gulp.task('default', gulp.series("min"));
I don't know why the minified file is like that, I tried to minify the same file using https://javascript-minifier.com/ and this problem isn't there.

Looks like your code is being mangled by the terser. Set the mangle flag to false and your problem should be solved.
You can refer to how to disable the flag here: https://www.npmjs.com/package/terser

Related

Gulp watch doesn't do anything

I'm trying to use Watch to compile my SASS files, but it doesn't work.
Package.json
"author": "José Ramón Rico Lara",
"license": "ISC",
"devDependencies": {
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-imagemin": "^7.1.0",
"gulp-notify": "^3.2.0",
"gulp-sass": "^4.1.0",
"gulp-webp": "^4.0.1"
}
}
Gulpfile.js
const { series, src, watch, dest, parallel } = require('gulp');
const sass = require('gulp-sass')
const webp = require('gulp-webp');
const paths = {
scss: 'src/scss/**/*.scss',
js: 'src/js/**/*.js'
}
function css() {
return src(paths.scss)
.pipe(sass())
.pipe(dest('./build/css'))
}
function javascript() {
return src(paths.js)
.pipe(concat('bundle.js'))
.pipe(dest('./build/js'))
}
function watchArchivos() {
watch(paths.scss, css); // * = La carpeta actual - ** = Todos los archivos con esa extensión
watch(paths.js, javascript);
}
exports.css = css;
exports.javascript = javascript;
exports.watchArchivos = watchArchivos;
exports.default = series(css, javascript, watchArchivos);
In the console it says, that the code is running and there isn't any issue, but when I change any file it doesn't compile it.
As far as I can tell there are no gulp.tasks... in example
gulp.task('watch', function() {
gulp.watch('public/assets/css/*.css', gulp.series('clean-css', 'pack-css'));
});
Also in the file you've supplied there's just exports, and you're not calling " watchArchivos".
Had a similar problem, the watching task never got executed, the first task in this case (browser) was a browser sync instance, in my case the browser task was asynchronous, so I had to use asyn / await and everything worked fine.
From:
function browser() {
browserSync.init({
server: {
baseDir: PATHS.output,
},
});
}
exports.default = series (browser, watching);
To
async function browser() {
await browserSync.init({
server: {
baseDir: PATHS.output,
},
});
}

regeneratorRuntime is not defined Gulp Babel v7 even after plugin-transform-runtime install

I've got a JS project where I'm trying to use async/await, I've installed the relevant package to transform runtime, but still get this error:
regeneratorRuntime is not defined
What am I missing?
package.json
"dependencies": {
"#babel/core": "^7.14.0",
"#babel/plugin-transform-runtime": "^7.13.15",
"#babel/preset-env": "^7.14.1",
"bootstrap": "4.6.0",
"eslint": "7.21.*",
"gulp": "4.0.2",
"gulp-autoprefixer": "7.0.*",
"gulp-babel": "^8.0.0",
"gulp-concat": "2.6.*",
"gulp-eslint": "6.0.*",
"gulp-minify": "3.1.*",
"gulp-sass": "4.1.*",
"gulp-stylelint": "13.0.*",
"stylelint": "13.11.*"
},
gulpfile.js
const gulp = require('gulp')
const sass = require('gulp-sass')
const babel = require('gulp-babel')
const concat = require('gulp-concat')
const minify = require('gulp-minify')
const eslint = require('gulp-eslint')
const autoprefixer = require('gulp-autoprefixer')
// build the JS
gulp.task('build-js', () =>
gulp.src([
'src/js/plugins/input.js'
])
.pipe(concat('output.js'))
.pipe(babel({
presets: [['#babel/env', { modules: false }]]
}))
.pipe(minify())
.pipe(gulp.dest('src/assets/js/'))
);
I was having the same problem. The solution was to concatenate the output.js file with the file node_modules/regenerator-runtime/runtime.js. Basically you just need to have this file being loaded somewhere in your website.
I didn't find the need for #babel/plugin-transform-runtime, but I am still understanding how all of this works, so let me know if it is necessary.
Here's a possible gulpfile.js:
'use strict';
// Import `src` and `dest` from gulp for use in the task.
const { series, parallel, src, dest } = require("gulp")
// Import Gulp plugins.
// CSS related
const sass = require('gulp-sass')(require('sass')); // compile scss to css
const autoprefixer = require('gulp-autoprefixer'); // add vendor prefixes to css for older browsers
const cleanCSS = require('gulp-clean-css'); // minify css
// JS related
const babel = require("gulp-babel"); // compile JS for older browsers
const uglify = require("gulp-uglify"); // minify JS
const concat = require("gulp-concat"); // concatenate files
const del = require("del"); // delete files
const plumber = require("gulp-plumber"); // Stop at gulp errors
const destDir = './dist';
const paths = {
styles: {
src: './sass/**/*.scss',
dest: `${destDir}/css/`,
bundleName: `main.css`
},
scripts: {
src: './js/**/*.js',
dest: `${destDir}/js/`,
bundleName: `main.js`
}
};
function clean() {
return del([paths.styles.dest, paths.scripts.dest])
}
function delTemp() {
return del([tempDir]);
}
function jsDeps() {
const files = [
"node_modules/regenerator-runtime/runtime.js"
]
return (
src(files)
.pipe(plumber())
// Combine these files into a single main.deps.js file.
.pipe(concat("main.deps.js"))
.pipe(uglify())
// Save the concatenated file to the tmp directory.
.pipe(dest(tempDir))
)
}
function jsBuild() {
// This will grab any file within js/ or its
// subdirectories, then ...
return src(paths.scripts.src)
// Stop the process if an error is thrown.
.pipe(plumber())
// Concatenate all files within src/components and its
// subdirectories into a single file named main.js.
.pipe(concat("main.build.js"))
// Transpile the JS code using Babel's preset-env.
.pipe(
babel({
presets: [
[
"#babel/env",
{
modules: false
}
]
]
})
)
// Minify the self-authored bundle.
.pipe(uglify())
// Save each component as a separate file in dist.
.pipe(dest(tempDir));
}
function jsConcat(done) {
// An array of the two temp (concatenated) files.
const files = [`${tempDir}/main.deps.js`, `${tempDir}/main.build.js`]
return (
src(files)
.pipe(plumber())
// Concatenate the third-party libraries and our
// homegrown components into a single main.js file.
.pipe(concat(paths.scripts.bundleName))
// Save it to the final destination.
.pipe(dest(paths.scripts.dest))
)
}
function sassBuild() {
return src(paths.styles.src)
.pipe(plumber())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer({
cascade: false
}))
.pipe(concat(paths.styles.bundleName))
.pipe(cleanCSS())
.pipe(dest(paths.styles.dest));
}
const build = series(clean, parallel(series(jsDeps, jsBuild, jsConcat), sassBuild), delTemp);
/*
* You can use CommonJS `exports` module notation to declare tasks
*/
exports.clean = clean;
exports.sassBuild = sassBuild;
exports.jsBuild = jsBuild;
exports.build = build;
// Gulp 4 uses exported objects as its tasks. Here we only have a
// single export that represents the default gulp task.
exports.default = build;

Prevent gulp uglify from stripping out es6

I'm using gulp babel to compile es6, but it seems like uglify is stripping out my es6 altogether. I'm not getting any errors in my command line when this runs. Any ideas why this is getting stripped out?
My gulp task looks like this:
gulp.task('scripts', function () {
return gulp.src('src/js/*.js')
.pipe(sourcemaps.init())
.pipe(babel())
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('dist/js'));
});
My javascript:
document.addEventListener('DOMContentLoaded', function (event) {
console.log('ready to es6!');
const foo = 4;
});
The outputted, compiled/uglified javascript:
"use strict";document.addEventListener("DOMContentLoaded",function(e){console.log("ready to es6!")});
//# sourceMappingURL=scripts.js.map
Notice the const foo = 4 is left out. Removing the .pipe(babel()) results in the const getting compiled properly.
If it's helpful, devDependencies:
"devDependencies": {
"#babel/core": "^7.2.2",
"#babel/preset-env": "^7.2.3",
"browser-sync": "^2.26.3",
"gulp": "^3.9.1",
"gulp-babel": "^8.0.0-beta.2",
"gulp-sass": "^4.0.2",
"gulp-sourcemaps": "^2.6.4",
"gulp-uglify": "^3.0.1",
"node-sass": "^4.11.0"
}
UglifyJS (a dependency of gulp-uglify) has a Compress option that by default removes unused vars. Since you never reference foo it is removed from the compressed source.
From UglifyJS2 docs:
Compress options:
unused (default: true) -- drop unreferenced functions and variables (simple direct variable assignments do not count as references unless set to "keep_assign")
Since const foo = 4 is a simple direct variable assignment it doesn't appear in your compressed code. You can either assume you don't need the unused code or adjust your gulp file as such:
gulp.task('scripts', function () {
return gulp.src('src/js/*.js')
.pipe(sourcemaps.init())
.pipe(babel())
.pipe(uglify({
compress: {
unused: false
}
}))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('dist/js'));
});

Javascript 6to5 (now Babel) export module usage

I'm still a beginner, i try to to export and import one class into a main file, the other class in the others class file and use them.
And then gulp ES5 code with 6to5 (now Babel).
// file a.js
import B from 'b.js';
class A {
constructor() {
B.methodB();
}
}
export default A;
// file b.js
class B {
methodB() {
console.log('hi from b');
}
}
export default B;
// file main.js
import A from 'a.js';
new A();
My gulpfile:
var gulp = require('gulp');
var to5 = require('gulp-6to5');
gulp.task('default', function () {
return gulp.src('main.js')
.pipe(to5())
.pipe(gulp.dest('dist'));
});
And this is my dist/main.js file:
"use strict";
var _interopRequire = function (obj) {
return obj && (obj["default"] || obj);
};
var A = _interopRequire(require("a.js"));
new A();
The error in console: ReferenceError: require is not defined
Which of course does not work ... what am I doing wrong or what lack I yet? I do not get it exactly.
I was having the exact same problem before myself... As Qantas mentioned in the comments, Babel (formerly 6to5) will convert syntax, but it won't do module loading or polyfills.
I've found the easiest workflow is using browserify with gulp. This takes care of transpiling, adding polyfills, bundling, minification, and source map generation in one hit. This question has a pretty nice example: Gulp + browserify + 6to5 + source maps.
This version adds minification and polyfills. An example for your case would look like this:
let gulp = require('gulp');
let browserify = require('browserify');
let babelify = require('babelify');
let util = require('gulp-util');
let buffer = require('vinyl-buffer');
let source = require('vinyl-source-stream');
let uglify = require('gulp-uglify');
let sourcemaps = require('gulp-sourcemaps');
gulp.task('build:demo', () => {
browserify('./demo/app.js', { debug: true })
.add(require.resolve('babel-polyfill/dist/polyfill.min.js'))
.transform(babelify.configure({ presets: ['es2015', 'es2016', 'stage-0', 'stage-3'] }))
.bundle()
.on('error', util.log.bind(util, 'Browserify Error'))
.pipe(source('demo.js'))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(uglify({ mangle: false }))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./demo'));
});
gulp.task('default', ['build:demo']);
It's important that uglify has mangle set to false; it really doesn't seem to play nice with the transformed code.
If you don't have all the dependencies installed, you may want to create a package.json file, and ensure that following packages are defined in the dependencies object:
"devDependencies": {
"babel-polyfill": "^6.13.0",
"babel-preset-es2015": "^6.13.0",
"babel-preset-es2016": "^6.11.0",
"babel-preset-stage-0": "^6.5.0",
"babel-preset-stage-3": "^6.11.0",
"babelify": "^7.3.0",
"browserify": "^13.1.0",
"gulp": "^3.9.0",
"gulp-sourcemaps": "^1.6.0",
"gulp-uglify": "^2.0.0",
"gulp-util": "^3.0.0",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0"
}
Most of these won't work if installed with -g, so consider yourself warned :P
Then, just run npm install to install all the dependencies, and gulp to run the default task and transpile all of your code.
Your other files look good, you have the right idea with importing at the beginning of each file and exporting your defaults :) If you want some examples of babelified ES6 in the wild, I have a couple of projects on GitHub that might help.
It's seems you need to import the requirejs fond in your HTML like that:
<script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.15/require.min.js"></script>
And your files need to be something like that:
// file a.js
import B from './b';
class A {
constructor() {
B.methodB = function() {
};
}
}
export default A;
// file b.js
class B {
methodB() {
console.log('hi from b');
}
}
export default B;
// main.js
import A from './a';
new A();
Note that you need to put the module's directory ./a and ./b on the import.
And your gulpfile need to be:
var gulp = require('gulp');
var to5 = require('gulp-6to5');
gulp.task('default', function () {
return gulp.src('src/*.js')
.pipe(to5())
.pipe(gulp.dest('dist'));
});
Note that you need to transform all of your file with src/*.js on the gulp.src

Gulp Filter with SourceMaps

I had a similar question here that has merged into a bit more research on my part and a new way this could work.
Basically I'm trying to have all of my .js and .coffee files within one gulp.src() object and based on the extension, do relevant tasks.
What started off with gulp-if has turned into me using gulp-filter which I prefer honestly. The catch I'm running into right now is getting this all to work with gulp-sourcemaps. The current task seems to override the other -- but I'd ultimately like everything to be concatenated in one file, source-mapped in another and have each file extension run its respective tasks. You'll see the uglify task is commented out; as that's what keeps yelling at me; without a whole bunch to go off of. When I do get the filters to work and I have a CoffeeScript error, I noticed that coffeescriptlint() will do its job, but then my watch command; while still running, doesn't respond to anything.
It seems like I might be going down the path of extracting each sourcemap using something like gulp-extract-sourcemap, but am not sure if that's the right way to go.
Normally I'd separate out the JS and Coffeescript task, but I have so many things co-mingling between the two that bringing them together with a simple filter seemed logical -- especially as I'm trying to figure out the sourcemaps for both.
I feel like this one is pretty close, so any nudges in the right direction would be greatly appreciated. Included current gulpfile.js and package.json if you want to spin it up. Thanks!
Gulpfile.js
// Load plugins
var gulp = require('gulp'),
jshint = require('gulp-jshint'),
coffee = require('gulp-coffee'),
changed = require('gulp-changed'),
coffeelint = require('gulp-coffeelint'),
uglify = require('gulp-uglify'),
sourcemaps = require('gulp-sourcemaps'),
notify = require('gulp-notify'),
concat = require('gulp-concat'),
filesize = require('gulp-size'),
livereload = require('gulp-livereload'),
duration = require('gulp-duration'),
gutil = require('gulp-util'),
gFilter = require('gulp-filter');
gulp.task('scripts', function() {
var jsBuildDir = 'assets/js/build/',
jsFilter = gFilter('**/*.js'),
coffeeFilter = gFilter('**/*.coffee');
return gulp.src([
'assets/js/src/_init.coffee',
'assets/js/src/_init.js'
])
.pipe(coffeeFilter)
.pipe(coffeelint().on('error', gutil.log))
.pipe(coffeelint.reporter())
.pipe(sourcemaps.init())
.pipe(coffee({bare: true}).on('error', gutil.log))
.pipe(sourcemaps.write('../../maps'))
.pipe(coffeeFilter.restore())
.pipe(jsFilter)
.pipe(jshint({
'boss': true,
'sub': true,
'evil': true,
'browser': true,
'globals': {
'module': false,
'require': true
}
}),
jshint.reporter('jshint-stylish'))
.pipe(jsFilter.restore())
.pipe(concat('scripts.min.js'))
//.pipe(uglify())
.pipe(filesize({
title: 'Scripts:'
}))
.pipe(gulp.dest(jsBuildDir))
.pipe(duration('building script files'))
.pipe(notify({ message: 'Coffeescript task complete' }));
});
// Default task
gulp.task('default', ['scripts']);
// Watch
gulp.task('watch', function() {
gulp.watch(['assets/js/src/**/*.js', 'assets/js/src/**/*.coffee'], ['scripts']);
// Create LiveReload server
var server = livereload();
// Watch files in patterns below, reload on change
gulp.watch(['assets/js/build/*']).on('change', function(file) {
server.changed(file.path);
});
});
Package.json
{
"devDependencies": {
"gulp": "^3.8.8",
"gulp-changed": "^1.0.0",
"gulp-coffee": "^2.2.0",
"gulp-coffeelint": "^0.4.0",
"gulp-concat": "^2.4.0",
"gulp-duration": "0.0.0",
"gulp-filter": "^1.0.2",
"gulp-jshint": "^1.8.4",
"gulp-livereload": "^2.1.1",
"gulp-notify": "^1.6.0",
"gulp-size": "^1.1.0",
"gulp-sourcemaps": "^1.2.2",
"gulp-uglify": "^1.0.1",
"gulp-util": "^3.0.1",
"jshint-stylish": "^0.4.0"
}
}
I guess you wrapped the sourcemaps.init() and sourcemaps.write() around the wrong section of your pipe. I put the commands where I assume they belong. See below.
I used gulp-filter quite a few times as well. However, I kept it to a minimum to not overcomplicate things. I found run-sequence very helpful. (Also check out some of my gulpfiles here and here.)
Your scenario I would approach like this:
var runSequence = require('run-sequence');
// ...
gulp.task('scripts', function (done) {
runSequence('lint', 'build', done);
});
gulp.task('lint', function (done) {
runSequence('lint-coffee', 'lint-js', done);
});
gulp.task('lint-coffee', function () {
// Just lint your coffee files here...
});
gulp.task('lint-js', function () {
// Just lint your js files here...
});
gulp.task('build', function () {
return gulp.src([
'assets/js/src/_init.coffee',
'assets/js/src/_init.js'
])
.pipe(coffeeFilter)
.pipe(coffee({bare: true}).on('error', gutil.log))
.pipe(coffeeFilter.restore())
.pipe(sourcemaps.init())
.pipe(concat('scripts.min.js'))
.pipe(uglify())
.pipe(sourcemaps.write('../../maps'))
.pipe(gulp.dest(jsBuildDir));
});

Categories

Resources