Issue bundling javascript with gulp js - javascript

I'm bundling my javascript files using the task runner gulp js, during the development of an application I'm noticing a certain issue.
When I add the new feature(reveal a password) script refuses to work because of the form modal script which can be seen below.
'use strict';
var modal__button = document.getElementById("enquiry-form-trigger");
var close__button = document.getElementById("close");
modal__button.addEventListener("click", function (){
var modal = document.getElementById("modal-form");
modal.classList.add("fadeIn");
modal.style.visibility = "visible";
});
close__button.addEventListener("click", function (){
var modal = document.getElementById("modal-form");
modal.classList.remove("fadeIn");
modal.style.visibility = "hidden";
});
When the above script and this other script below
"use strict"
document.getElementById("password-reveal-modal").addEventListener("click", function (){
var x = document.getElementById("password-modal");
if (x.type === "password") {
x.type = "text";
} else {
x.type = "password";
}
});
The password reveal feature doesn't work, but when I paste it in chrome's dev tools works perfectly.
I'm not sure why it wont work without pasting it into the dev tools, it's baffling me, I'm not sure if its my setup or if its the custom javascript.
This is my gulp file setup in case anyone wants to check it, I don't see an issue but Ive only been using gulp for about 3 or 4 months.
var gulp = require("gulp"),
sass = require("gulp-sass"),
image = require("gulp-image"),
concat = require("gulp-concat"),
browserSync = require('browser-sync').create(),
reload = browserSync.reload,
minifyEjs = require("gulp-minify-ejs"),
stripEJSComments = require('gulp-strip-comments'),
nodemon = require('gulp-nodemon'),
plumber = require("gulp-plumber"),
ejs = require("ejs"),
uglify = require("gulp-uglify");
//Build task
gulp.task("build", ["ejs", "styles", "images", "javascript", "routes", "models", "middleware"], function () {
console.log("Build Success");
});
//start up sequence tasks
gulp.task('init', ["nodemon"], function () {
browserSync.init({
proxy: 'http://localhost:2000', //Index.js port number
port: 2128, // The port browser sync runs on
serveStatic: [ './public/', "./assets/"], // What files browser sync should have access to
reloadOnRestart: true, // Enable auto reload
ghostMode:false, //Stops session mirroring
open: "external", //Opens up on an external address (xxx.xxx.x.xx:3128)
});
});
//Starts the express server
gulp.task('nodemon', function (done) {
var running = false; //Default State
return nodemon({
script: 'index.js', //Index file for the JS project
watch: ["./assets/", "./public/"] //What nodemon has access to
})
.on('start', function () {
if (!running) {
done();
}
running = true;
})
//Minor Delay Of 500ms Upon Restart
.on('restart', function () {
setTimeout(function () {
reload();
}, 500);
});
});
//SCSS Task
gulp.task("styles", function () {
gulp.src("./assets/stylesheet/APP.scss")
.pipe(plumber())
.pipe(sass({
outputStyle: 'compressed'
}))
.pipe(gulp.dest("./public/stylesheet/"))
.pipe(browserSync.stream({ stream: true }));
});
//Compiles the express route/s
gulp.task("routes", function () {
gulp.src([
"./assets/routes/*.js"
])
.pipe(plumber())
.pipe(gulp.dest("./public/routes/"))
.pipe(browserSync.stream({ stream: true }));
});
//Compiles the express route/s
gulp.task("models", function () {
gulp.src("./assets/models/*.js")
.pipe(plumber())
.pipe(gulp.dest("./public/models/"))
.pipe(browserSync.stream({ stream: true }));
});
//Image minification
gulp.task("images", function () {
return gulp.src("./assets/images/*")
.pipe(image())
.pipe(gulp.dest("./public/images"))
.pipe(browserSync.stream({ stream: true }));
});
//Client javascript
gulp.task("javascript", function () {
gulp.src([
"./node_modules/jquery/dist/jquery.js",
"./node_modules/tether/dist/js/tether.js",
"./node_modules/bootstrap/dist/js/bootstrap.js",
"./assets/scripts/**/**/*.js"
])
.pipe(plumber())
.pipe(concat("main.js"))
.pipe(gulp.dest("./public/scripts/"))
.pipe(browserSync.stream({ stream: true }));
});
//Middleware task
gulp.task("middleware", function () {
gulp.src("./assets/middleware/*.js")
.pipe(plumber())
.pipe(concat("index.js"))
.pipe(gulp.dest("./public/middleware/"))
.pipe(browserSync.stream({ stream: true }));
});
//EJS task
gulp.task("ejs", function () {
gulp.src("./assets/views/**/*.ejs")
.pipe(plumber())
.pipe(stripEJSComments())
.pipe(minifyEjs({}))
.pipe(gulp.dest("./public/views"))
.pipe(browserSync.stream({ stream: true }));
});
//Default task array
gulp.task("default", ["init", "build"], function (done) {
gulp.watch("./assets/stylesheet/**/*.scss", ["styles"]);
gulp.watch("./assets/scripts/*", ["javascript"]);
gulp.watch("./assets/routes/*.js", ["routes"]);
gulp.watch("./assets/models/*.js",["models"]);
gulp.watch("./assets/images/*",["images"]);
gulp.watch("./assets/views/**/*.ejs",["ejs"]);
browserSync.reload();
done();
});
The two files which are causing the issue are the only files as I have tested each files and its only these two files weirdly so something is causing it to clash.
If you want me to upload my project to github just let me know and I will upload the latest version to my update branch.
I have exhausted all my knowledge into this problem and I am completely stuck now.
If anyone could help a fellow developer out it would be greatly appreciated.
cheers,
alex

I needed to ensure the DOM had fully loaded before the script could be executed.

Related

Refactored watch task using gulp v4 doesn't work

I'm refactoring my gulpfile now I'm using gulp v4 and am having an issue with gulp watch not running my stylesCompileIncremental function. Any help or pointers would be much appreciated.
My refactoring includes:
Switching to using functions instead of gulp.task
Using series and parallel as per the docs
Exporting public tasks at the bottom of my gulpfile ie exports.stylesWatch = stylesWatch;
Adding callbacks in functions to tell Gulp the function is complete
The code for the affected tasks is as follows (directory paths are stored in package.json file hence pathConfig.ui... values):
// Compile only particular Sass file that has import of changed file
function stylesCompileIncremental(cb) {
sassCompile({
source: getResultedFilesList(changedFilePath),
dest: pathConfig.ui.core.sass.dest,
alsoSearchIn: [pathConfig.ui.lib.resources]
});
cb();
}
// Compile all Sass files and watch for changes
function stylesWatch(cb) {
createImportsGraph();
var watcher = gulp.watch(pathConfig.ui.core.sass.src + '**/*.scss', gulp.parallel(devServReloadStyles));
watcher.on('change', function(event) {
changedFilePath = event;
});
cb();
}
// reload css separated into own function. No callback needed as returning event stream
function reloadCss() {
return gulp.src(generateFilePath)
.pipe($.connect.reload()); // css only reload
}
function devServReloadStyles(cb) {
gulp.series(stylesCompileIncremental, reloadCss);
cb();
}
When I run gulp stylesWatch using my refactored code I get the below output (notice the stylesCompileIncremental task is not run):
So my watch tasking is successfully running but there's something wrong when the devServReloadStyles is run for the stylesCompileIncremental function to not kick in.
The original code before refactoring (when using gulp v3) is below:
// Compile only particular Sass file that has import of changed file
gulp.task('styles:compile:incremental', () => {
return sassCompile({
source: getResultedFilesList(changedFilePath),
dest: pathConfig.ui.core.sass.dest,
alsoSearchIn: [pathConfig.ui.lib.resources]
});
});
// Compile all Sass files and watch for changes
gulp.task('styles:watch', () => {
createImportsGraph();
gulp.watch(
pathConfig.ui.core.sass.src + '**/*.scss',
['devServ:reload:styles']
).on('change', event => changedFilePath = event.path);
});
// Reload the CSS links right after 'styles:compile:incremental' task is returned
gulp.task('devServ:reload:styles', ['styles:compile:incremental'], () => {
return gulp.src(generateFilePath) // css only reload
.pipe($.connect.reload());
});
The original task output when running styles:watch is this:
And this is the sassCompile variable used inside stylesCompileIncremental which I've currently not changed in anyway.
/**
* Configurable Sass compilation
* #param {Object} config
*/
const sassCompile = config => {
const sass = require('gulp-sass');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const postProcessors = [
autoprefixer({
flexbox: 'no-2009'
})
];
return gulp.src(config.source)
.pipe($.sourcemaps.init({
loadMaps: true,
largeFile: true
}))
.pipe(sass({
includePaths: config.alsoSearchIn,
sourceMap: false,
outputStyle: 'compressed',
indentType: 'tab',
indentWidth: '1',
linefeed: 'lf',
precision: 10,
errLogToConsole: true
}))
.on('error', function (error) {
$.util.log('\x07');
$.util.log(error.message);
this.emit('end');
})
.pipe(postcss(postProcessors))
.pipe($.sourcemaps.write('.'))
.pipe(gulp.dest(config.dest));
};
UPDATE
This is due to an issue with my devServReloadStyles function, although I'm still unsure why. If I change my stylesWatch function to use the original devServ:reload:styles task stylesCompileIncremental gets run.
// Compile all Sass files and watch for changes
function stylesWatch(cb) {
createImportsGraph();
var watcher = gulp.watch(pathConfig.ui.core.sass.src + '**/*.scss', gulp.parallel('devServ:reload:styles'));
watcher.on('change', function(event) {
changedFilePath = event;
});
cb();
}
It would still be good to not use the old task and have this as a function though.
Can anybody tell me why my refactored version doesn't work and have any suggestions as to how this should look?
I've fixed this now.
gulp.series and gulp.parallel return functions so there was no need to wrap stylesCompileIncremental and reloadCss inside another function ie. devServReloadStyles.
As per Blaine's comment here.
So my function:
function devServReloadStyles(cb) {
gulp.series(stylesCompileIncremental, reloadCss);
cb();
}
Can just be assigned to a variable:
const devServReloadStyles = gulp.series(stylesCompileIncremental, reloadCss);
And my stylesWatch task is already calling devServReloadStyles:
// Compile all Sass files and watch for changes
function stylesWatch(cb) {
createImportsGraph();
var watcher = gulp.watch(pathConfig.ui.core.sass.src + '**/*.scss', gulp.parallel(devServReloadStyles));
watcher.on('change', function(event) {
changedFilePath = event;
});
cb();
}
So running gulp stylesWatch now runs the stylesCompileIncremental job (notice how devServReloadStyles doesn't show as it's not a function).

How I replace values in HTML attributes via config.json file with Gulp?

Let's say I have a JSON file with the pairs:
{
"Table":{
"fullwidth": "680",
"color": "#33d025",
"margin1": "30",
"margin2": "60",
"padding": "20"
}
}
then, I want to read those values and use them to replace attributes in an html file that looks like this:
<table width="{{Table.fullwidth}}" bgcolor="{{Table.color}}" style="margin: {{Table.margin1}}px {{Table.margin2}}px;">
<tr>
<td style="padding: {{Table.padding}}px;">
<img src="a.jpg">
</td>
</tr>
</table>
So, with the html file in a "temp/" path, after gulping, I obtain a valid html file in "dist/" with the attributes changed looking like this:
<table width="680" bgcolor="#33d025" style="margin: 30px 60px;">
<tr>
<td style="padding: 20px;">
<img src="a.jpg">
</td>
</tr>
</table>
I have already tried gulp-token-replace but after running it once, it won't work again if I save new values in the json file, even when it triggers the watch function, forcing me to restart the "gulp".
Is there a gulp plugin that can do this? or a technique that can replace the gulp-token-replace?
Maybe just javascript, but, can I run something like that from inside a gulp process (running watch to refresh it)?
Gulpfile.js as requested:
// Include gulp
var gulp = require('gulp'),
// Include plugins
fileinclude = require('gulp-file-include'),
rename = require('gulp-rename'),
images = require('gulp-imagemin'),
cache = require('gulp-cache'),
browserSync = require('browser-sync').create(),
reload = browserSync.reload,
runSequence = require('run-sequence'),
del = require('del'),
notify = require('gulp-notify'),
gtr = require('gulp-token-replace')
// Default Task
gulp.task('default', function (cb) {
runSequence('clean', ['AA', 'BB', 'CC', 'watch'], cb);
});
// TASKS
// Clean 'dist'
gulp.task('clean', function () {
return del(['HTMLTemplates/*.html', 'HTMLTemplates/img', 'Temp/*.html']);
});
// Compress images
gulp.task('BB', function () {
gulp.src('templates/img/*.{gif,jpg,png}')
.pipe(cache(images({
optimizationLevel: 4,
progressive: true,
interlaced: true
})))
.pipe(gulp.dest('Templates/img/'));
});
// Reload browser
gulp.task('reload', function () {
browserSync.reload();
});
// Prepare Browser-sync
gulp.task('CC', ['AA'], function () {
browserSync.init({
// browserSync.init(['templates/*/*.html'], {
//proxy: 'your_dev_site.url'
server: {
baseDir: './HTMLTemplates'
}
});
});
// MAIN TASKS
gulp.task('AA', function (cbk) {
runSequence('fileinclude', 'trp', cbk);
});
// Force to run fileinclude first before replacing the tokens
gulp.task('trp', ['fileinclude'], function (done) {
function onFinish(event) {
if (event.task === 'tokenreplace') {
gulp.removeListener('task_stop', onFinish);
done();
}
}
gulp.on('task_stop', onFinish);
gulp.start('tokenreplace');
});
// Include partial files into email template (fileinclude)
gulp.task('fileinclude', function () {
// grab 'template'
return gulp.src('templates/layouts/*.tpl.html')
// include partials
.pipe(fileinclude({
basepath: 'templates/components/'
}))
// remove .tpl.html extension name
.pipe(rename({
extname: ""
}))
// add new extension name
.pipe(rename({
extname: ".html"
}))
// move file to folder
.pipe(gulp.dest('Temp/'))
.pipe(notify({
message: 'Template file includes complete'
}));
});
// Replace tokens in the index.html created by fileinclude
gulp.task('tokenreplace', ['fileinclude'], function (doit) {
var config = require('./templates/components/000 vars/config.json');
return gulp.src('Temp/index.html')
.pipe(gtr({
global: config
}))
.pipe(gulp.dest('HTMLTemplates/'))
// notify to say the task has complete
.pipe(browserSync.stream())
.pipe(notify({
message: 'Vars includes complete'
})), doit();
});
// END of MAIN TASKS
// WATCH
// Watch files for changes in html/css/tpl.html/images
gulp.task('watch', function () {
gulp.watch(['templates/components/**/*.html'], ['AA']);
gulp.watch(['templates/components/**/*.css'], ['AA']);
gulp.watch(['templates/layouts/*.tpl.html'], ['AA']);
gulp.watch(['templates/components/000 vars/*.json'], ['trp']);
gulp.watch(['HTMLTemplates/*.html'], ['reload']);
gulp.watch('templates/img/*', ['BB']);
});
I received the answer directly from the developer of the Gulp Token Replace plugin, so I'm answering my own question for archive purposes.
Replace this:
// Replace tokens in the index.html created by fileinclude
gulp.task('tokenreplace', ['fileinclude'], function (doit) {
var config = require('./templates/components/000 vars/config.json');
return gulp.src('Temp/index.html')
.pipe(gtr({
global: config
}))
with this:
// Replace tokens in the index.html created by fileinclude
gulp.task('tokenreplace', ['fileinclude'], function (doit) {
delete require.cache[require.resolve('./templates/components/000 vars/config.json')]
var config = require('./templates/components/000 vars/config.json');
return gulp.src('Temp/index.html')
.pipe(gtr({
global: config
}))
And now it works like a charm!

Gulp injection missing files

I'm trying to use gulp-inject but something is not syncing up properly. I think it has to do with my cleaning task.
gulp.task("clean", function () {
return gulp.src([
"tmp/client/**/*",
"wwwroot/**/*.css",
"wwwroot/**/*.js"
], { read: false })
.pipe(plumber())
.pipe(clean());
});
This runs before my compile tasks, such as:
gulp.task("dev:tsc", ["clean"], function () {
return tsResult.js
.pipe(sourceMaps.write("."))
.pipe(gulp.dest("wwwroot/js"));
});
Then all my compile steps run before a build task:
function injectTask(assets) {
var layout = gulp.src("Views/Shared/_Layout.cshtml");
var sources = gulp.src(assets, { read: false });
return layout.pipe(inject(sources, {
ignorePath: "wwwroot",
addPrefix: "~",
addRootSlash: false
})).pipe(gulp.dest("Views/Shared"));
}
gulp.task("dev:build", ["dev:tsc", "...other tasks..."], function () {
var vendorSources = vendorConfig.map(function (vendor) {
return ["wwwroot/js", vendor.srcFile].join("/");
});
return injectTask(vendorSources.concat([
"wwwroot/css/*.css",
"wwwroot/js/*.js"
]));
});
Sometimes all my files get injected, sometimes some are missing. Sometimes I get an error about a file missing. I suspect I'm missing some step to correctly declare dependencies on the streams and prevent them from overlapping, I just can't see what it is. The complete gulpfile is here. Any ideas?

Why browsersync does not reload page

The problem is in stream reloading page
Just reload method work correctly
But when I user browserSync.stream() (browserSync.reload({stream: true})) it's not working
It's my browser sync init function
function browserSyncInit(baseDir, browser) {
browser = browser === undefined ? 'default' : browser;
var routes = null;
if(baseDir === conf.paths.src || (util.isArray(baseDir) && baseDir.indexOf(conf.paths.src) !== -1)) {
routes = {
'/bower_components': 'bower_components'
};
}
var server = {
baseDir: baseDir,
routes: routes,
middleware: proxyMiddleware('http://0.0.0.0:8080')
};
var nodemonConfig = {
cwd: path.normalize(__dirname + '/../../'),
script: 'server/server.js',
ext: 'js json',
ignore: ['client/**/*.*'],
env: {'PORT': '8080'}
};
var serverStarted;
nodemon(nodemonConfig)
.on('start', function () {
if (serverStarted) return;
browserSync.init(null, {
startPath: '/',
open: false,
server: server,
browser: browser
});
serverStarted = true;
});
}
Proxy server it's Loopback application (may be problem in this)
It's task for reloading styles and scrips
gulp.task('styles-reload', ['styles'], function() {
return buildStyles()
.pipe(browserSync.stream());
});
gulp.task('scripts-reload', ['scripts'], function() {
return buildScripts()
.pipe(browserSync.stream());
});
Streams are for injecting scripts/css/etc., from a task's Gulp stream, which is why in the documentation, it mentions to place it after the gulp.dest.
If you're looking to manually reload the BrowserSync page, you can do that with .reload in your two functions, otherwise, you'll need to pass through the files into your reload tasks, since it looks like you're calling those tasks from elsewhere.
To add to this, I don't see a reason to separate the two tasks (styles/scripts with their respective -reload tasks). You should just pipe it after the dest, so that you don't have to mess with starting a new stream or merging between tasks.

yeoman sub-generator testing with composeWith

I have a generator-generator app with its own local sub-generator app. The situation is that I want the sub-generator to invoke atleast once with pre-defined argument when I run the main 'app' generator. Everything works fine except the npm test fails.
Main 'app' generator: yo mygen.
Sub generator: yo mygen:foo "lorem ipsum".
Here is the test.js
/*global describe, beforeEach, it*/
'use strict';
var path = require('path'),
yg = require('yeoman-generator');
var helpers = require('yeoman-generator').test;
var assert = require('yeoman-assert');
describe(' running `yo mygen`', function () {
before(function (done) {
var deps = [
[helpers.createDummyGenerator(), 'mygen:foo', 'blah blah blah']
];
helpers.run(path.join(__dirname, '../app'))
.inDir(path.join(__dirname, './temp')) // Clear the directory and set it as the CWD
.withOptions({ mongoose: 'app', 'skip-install': true }) // Mock options passed in
.withPrompts({
'dbName': 'demo',
'useUserAuth': false
})
.withGenerators(deps)
.on('end', done);
//done();
});
it('can be imported without blowing up', function () {
var app = require('../app');
assert(app !== undefined);
});
it('creates all required MVC files', function (done) {
var expected = [
// add files you expect to exist here.
'package.json',
'app.js',
'bower.json',
'routes/index.js',
'public/css/style.css',
'public/js/script.js',
'views/index.html',
'README.md',
'.editorconfig',
'.jshintrc'
];
assert.file(expected);
done();
});
});
describe('í ¼ running `yo mygen:foo`', function () {
before(function (done) {
helpers.run(path.join(__dirname, '../schema'))
.inDir(path.join(__dirname, './temp')) // Clear the directory and set it as the CWD
.withOptions({ mongoose: 'schema' }) // Mock options passed in
.withArguments(['ha ha ha ha hha'])
.on('end', done);
//done();
});
describe('foo generator', function () {
it('foo can be imported without blowing up', function () {
var app = require('../foo');
assert(app !== undefined);
});
it('created new MVC files for foo', function (done) {
var expected = [
// add files you expect to exist here.
'view/t1.js',
'models/t1.js',
'controller/t1.js'
];
assert.file(expected);
done();
})
});
});
And in app/index.js, in order to invoke the sub-generator, i have used:
mygenGenerator.prototype.install = function install(){
this.installDependencies();
this.composeWith("mygen:foo", {args: ["humpty dumpty saton a wall"]});
};
Searched all possible answers on stackoverflow and everywhere else. Can't figure out what to do.
Test Cases for npm test fails:
Remove the composeWith line from index.js and the test passes.
keep the composeWith line, the test goes to infinity, eventually exceed 2000ms quota and failing.

Categories

Resources