My Gulp was working fine until I installed browser-sync
npm install browser-sync gulp --save-dev
Then I started to get this error:
Error: Cannot find module 'lru-cache'
Which I solved using this: npm link lru-cache answer from https://github.com/npm/npm/issues/1154
However, now when I try to run gulp I get this new error:
~/Projects/starfeeder
❯ npm install browser-sync gulp --save-dev
npm WARN deprecated minimatch#2.0.10: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated node-uuid#1.4.8: Use uuid module instead
fsevents#1.1.2 install
/Users/leongaban/Projects/starfeeder/node_modules/fsevents
node install
My gulpfile if that helps:
"use strict";
const gulp = require('gulp'),
_ = require('lodash'), // https://www.npmjs.com/package/lodash
del = require('del'), // https://www.npmjs.com/package/del
fs = require('fs'), // Node file system
gutil = require('gulp-util'), // https://www.npmjs.com/package/gulp-util
htmlReplace = require('gulp-html-replace'), // https://www.npmjs.com/package/gulp-html-replace
notify = require("gulp-notify"), // https://www.npmjs.com/package/gulp-notify
runSequence = require('run-sequence'), // https://www.npmjs.com/package/run-sequence
sass = require('gulp-ruby-sass'), // https://www.npmjs.com/package/gulp-ruby-sass
sourcemaps = require('gulp-sourcemaps'); // https://www.npmjs.com/package/gulp-sourcemaps
const rootPath = process.cwd();
const paths = {
files: ['src/static/**']
};
const errorlog = err => {
gutil.log(gutil.colors.red.bold.inverse(' ERROR: '+err));
this.emit('end');
};
// Build tasks chain ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
gulp.task('build', function(cb) {
runSequence(
'build:app-css', // Minify and concat app styles
'build:move-files',
'build:index', // Replace scripts in index.html
'build:final', cb); // Remove app.min.js from build folder
});
gulp.task('build:move-files', () => gulp.src(paths.files).pipe(gulp.dest('starfeeder/')) );
// Preprocess SASS into CSS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
gulp.task('build:app-css', () => sass('src/sass/starfeeder.scss', { style: 'compressed' }).on('error', errorlog).pipe(gulp.dest('src/static/css/')) );
// Clear out all files and folders from build folder \\\\\\\\\\\\\\\\\\\\\\\\\\\
gulp.task('build:cleanfolder', cb => { del(['starfeeder/**'], cb); });
// Task to make the index file production ready \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
gulp.task('build:index', () => {
process.stdout.write(gutil.colors.white.inverse(' New asset paths in markup: \n'));
process.stdout.write(gutil.colors.yellow(' static/css/starfeeder.css\n'));
gulp.src('index.html')
.pipe(htmlReplace({
'app-css': 'css/starfeeder.css'
}))
.pipe(gulp.dest('starfeeder/'))
.pipe(notify('Starfeeder build created!'));
});
gulp.task('build:final', cb => {
process.stdout.write(gutil.colors.blue.bold ('###################################################### \n'));
process.stdout.write(gutil.colors.blue.inverse(' Starfeeder build created! \n'));
process.stdout.write(gutil.colors.blue.bold ('###################################################### \n'));
});
// Main Styles /////////////////////////////////////////////////////////////////
gulp.task('app-css', () => {
return sass('src/sass/starfeeder.scss', { style: 'compressed' })
.pipe(sourcemaps.init())
.on('error', errorlog)
.pipe(sourcemaps.write('./maps'))
.pipe(gulp.dest('src/static/css/'))
});
// Development watch /////////////////////////////////////////////////////////// 🤖☕️⏎→
gulp.task('watch', () => {
gulp.watch('src/sass/**/*.scss', ['app-css']).on('change', file => {
let filePath = file.path.split(rootPath);
logFileChanged(filePath[1]);
});
});
gulp.task('default', ['watch']);
I had this same issue with installing through2. The project used shrink wrap and had a package-lock.json which caused the a dependencies to break. Once I removed the lock and re-installed, all was good.
Ok so still not sure why I got those errors, but never installing browserSync again.
I had to npm link all my gulp plugins.
That work, but then it broke during the gulp build process.
Instead of doing npm link to everything, included other node modules I've never heard off. I removed browserSync and deleted my node_modules folder and did yarn(npm) install.
Related
I need to build and deploy a React / NextJS app to a Weblogic J2ee server with a specific context. I have some React experience, but taking my first steps with NextJS.
Currently the build/verification steps are;
Create a vanilla NextJS app
Add a next.config.js with a module.export to change the basepath
module.exports = {
basePath: '/test'
}
Execute npm run dev the application is available on 'http://localhost:3000/test'
Add an export script to the package.json "export": "next build && next export" to support static export
Add the export below to resolve issue 21079
//https://github.com/vercel/next.js/issues/21079
module.exports = {
images: {
loader: "imgix",
path: "",
}
}
Executed npm run export to create a static HTML export. Export is completed successfully to the out folder.
When inspecting the index.html in the out folder, all references to the static content still starts with /_next/static and not with /test/_next/static.
So this can be a misinterpretation of my side, please correct me if i am wrong here.
To be able to test the vanilla app on the J2EE applicationserver it has to be packed into a war file. To accomplish this i added the file warpack/warpack.ts to the project.
const fs = require('fs');
const archiver = require('archiver');
const rimraf = require('rimraf') ;
const distFolder = 'dist' ;
const warFile = distFolder + '/test.war';
const buildFolder = 'out';
const contextRoot = 'test';
// Destroy dist folder
rimraf(distFolder, (error) => {
if (!error) {
// Create dist folder
if (!fs.existsSync(distFolder)){
fs.mkdirSync(distFolder);
}
const output = fs.createWriteStream(warFile);
const archive = archiver('zip', {});
output.on('close', () => {
console.log('war (' + warFile + ') ' + archive.pointer() + ' total bytes');
});
// write archive to output file
archive.pipe(output);
// add build folder to archive
archive.directory(buildFolder,'');
// add weblogic.xml
const weblogicXML = '<?xml version="1.0" encoding="UTF-8"?><weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.2/weblogic-web-app.xsd"><weblogic-version>10.3.6</weblogic-version><context-root>' + contextRoot '</context-root><description>Test NextJS</description></weblogic-web-app>'
archive.append(weblogicXML,{ name: 'WEB-INF/weblogic.xml' });
const manifestMF = 'Manifest-Version: 1.0\nBuild-Tag: 0.0.1-SNAPSHOT\nWeblogic-Application-Version: 0.0.1-SNAPSHOT';
archive.append(manifestMF,{ name: 'META-INF/MANIFEST.MF' });
archive.finalize();
} else {
console.log('Failed to delete "' + distFolder + '" folder.') ;
process.exit(1);
};
});
Installed the required packages for webpack.ts
npm install fs --save-dev
npm install rimraf --save-dev
npm install archiver --save-dev
Added the script "warpack": "next build && next export && node warpack/warpack.ts" to build, export and pack the static app to an war.
After deployment of the war-file the page can be loaded on http://something/test but shows an empty page.
Network development tools indicate that the requests are made to the root of the application server, not to the configured basepath.
GET http://host:8001/static/css/main.09371e9d.chunk.css net::ERR_ABORTED 404 (Not Found)
GET http://host/static/js/2.0850eeb7.chunk.js net::ERR_ABORTED 404 (Not Found)
GET http://host/static/js/main.dc0c945b.chunk.js net::ERR_ABORTED 404 (Not Found)
Too much focus on basePath value instead on correct syntax of next.config.js.
Second module export in next.config.js overwrote first.
Wrong
module.exports = {
basePath: '/test'
}
//https://github.com/vercel/next.js/issues/21079
module.exports = {
images: {
loader: "imgix",
path: "",
}
}
Correct
module.exports = {
basePath: '/test',
assetPrefix: "/test/",
//https://github.com/vercel/next.js/issues/21079
images: {
loader: "imgix",
path: ""
}
}
You can use env check to invoke only for prod environment if you wish to like:
module.exports = {
basePath: "/test"
assetPrefix: process.env.NODE_ENV === "production" ? "/test/" : undefined,
}
I am relatively new to using Gulp for my workflow.
Below is my gulpfile.js. I have tried to debug myself and using some hints from another BrowserStack question, but I cant figure it out.
When I save a .php file it reloads the browser, but errors. When I update a scss file, then it completely sass successfully.
const gulp = require( 'gulp' );
const sourcemaps = require( 'gulp-sourcemaps' );
const sass = require('gulp-sass');
const csso = require('gulp-csso');
const autoprefixer = require('gulp-autoprefixer');
const browserSync = require('browser-sync').create();
sass.compiler = require('node-sass');
// Create browsersyn function
function sync(done) {
browserSync.init({
files: './**/*.php',
// Changegit
proxy: 'http://localhost/jacks-bistro'
});
done();
}
// Create sass and sourcemaps function
function sassy() {
return gulp.src('./assets/*.scss')
.pipe( sourcemaps.init() )
.pipe(sass().on('error', sass.logError))
.pipe( autoprefixer() )
.pipe(csso())
.pipe( sourcemaps.write( './' ) )
.pipe(gulp.dest('./'))
.pipe(browserSync.stream());
};
// Create tasks for functions(probably not needed)
gulp.task( "sass", sassy );
gulp.task( "sync", sync );
// Create watch task
gulp.task( 'watch', function () {
gulp.watch('./assets/*.scss', gulp.series('sass'));
gulp.watch('./**/*.php', gulp.series('sync'));
});
This is the error I am receiving:
[23:07:06] 'sync' errored after 815 μs
[23:07:06] TypeError: args.cb is not a function
at Object.init (/Applications/XAMPP/xamppfiles/htdocs/jacks-bistro/wp-content/themes/jb_ewm/node_modules/browser-sync/dist/public/init.js:21:25)
at sync (/Applications/XAMPP/xamppfiles/htdocs/jacks-bistro/wp-content/themes/jb_ewm/gulpfile.js:12:15)
at sync (/Applications/XAMPP/xamppfiles/htdocs/jacks-bistro/wp-content/themes/jb_ewm/node_modules/undertaker/lib/set-task.js:13:15)
at bound (domain.js:430:14)
at runBound (domain.js:443:12)
at asyncRunner (/Applications/XAMPP/xamppfiles/htdocs/jacks-bistro/wp-content/themes/jb_ewm/node_modules/async-done/index.js:55:18)
at processTicksAndRejections (internal/process/task_queues.js:75:11)
I cannot figure out where the error is. Any help would be greatly appreciated.
From the stack trace, I could infer that the error is originating from done that is being passed to your sync function as an argument. That done isn't a function but is being called like one and that's probably why you are getting args.cb is not a function.
So basically what I'm trying to do is to make the browser refresh whenever there is a change in the files using browserSync, compiles Pug templates, then Parceljs does the bundling. And Gulp is to watch for changes.
The overall objective is a static website/page.
The problem:
If parcel fails building. browserSync exits. Watch stops.
[12:31:41] 'parcel' errored after 3.83 s
[12:31:41] Error in plugin "gulp-parcel"
[12:31:41] The following tasks did not complete: browserSync
[12:31:41] Did you forget to signal async completion?
OS: Windows 10
Thanks!!
Gulpfile.js content:
"use strict";
var gulp = require('gulp');
var parcel = require('gulp-parcel');
var pug = require('gulp-pug');
var browserSync = require('browser-sync').create();
gulp.task('html', function () {
return gulp.src('src/templates/*.pug')
.pipe(pug())
.pipe(gulp.dest('build/html'))
.pipe(browserSync.reload({
stream: true
}));
});
gulp.task('parcel', function () {
return gulp.src('build/html/*.html', {
read: false
})
.pipe(parcel())
.pipe(browserSync.reload({
stream: true
}));
});
gulp.task('browserSync', function () {
browserSync.init({
server: {
baseDir: 'dist'
},
});
});
gulp.task('watch', gulp.parallel('browserSync',gulp.series('html', 'parcel')), function () {
gulp.watch('src/templates/**/*.pug', gulp.series('html', 'parcel'));
});
gulp.task('default', gulp.series('watch'), function(){
console.log('Started default');
});
After investigating a bit, the gulp-parcel plugin had a bug which is still being worked on. Meanwhile, I was able to come up with a workaround.
Upgraded to es6
Implemented 'gulp-run-command' to run Parcel in watch mode
Here is my new solution:
'use strict';
import gulp from 'gulp';
import babel from 'gulp-babel';
import browserSync from 'browser-sync';
import run from 'gulp-run-command';
import log from 'fancy-log';
import errorHandler from 'gulp-error-handle';
const server = browserSync.create();
const paths = {
parcel: {
dist: 'dist/*'
}
};
gulp.task('parcel', run('parcel watch src/templates/index.pug --public-url ./ --no-cache'));
const reload = done => {
server.reload();
done();
};
const serve = done => {
server.init({
server: {
baseDir: 'dist/'
}
});
done();
};
const watch = done => {
gulp.watch(paths.parcel.dist, gulp.series(reload));
done();
};
const dev = gulp.parallel('parcel', serve, watch);
export default dev;
I have the following gulp task that returns a stream. It works fine in gulp 3.9.1, but converting to gulp 4.0, I get:
Did you forget to signal async completion?
const gulp = require('gulp');
const gulpif = require('gulp-if');
const plumber = require('gulp-plumber');
const rename = require('gulp-rename');
const buffer = require('vinyl-buffer');
const es = require('event-stream');
const browserify = require('browserify');
const browserifyInc = require('browserify-incremental');
const babelify = require('babelify');
const browserSync = require('browser-sync').create();
// Incrementally building the js
gulp.task('build-js-inc', () =>
es.merge.apply(null, paths.entry.scripts.map(script => {
const b = browserify(Object.assign({}, browserifyInc.args,
{
entries: script,
extensions: ['.jsx'],
debug: true
}
));
browserifyInc(b, { cacheFile: './browserify-cache.json' });
return b.transform(babelify)
.bundle()
.on('error', handleErrors)
.pipe(source(`./${script.split('/')[script.split('/').length - 1]}`))
.pipe(buffer())
.pipe(plumber())
.pipe(rename(path => {
path.extname = '.bundle.js';
}))
.pipe(gulp.dest('public/js'))
.pipe(gulpif('*sw.bundle.js', gulp.dest('public')))
.pipe(browserSync.reload({ stream: true }));
}))
);
I've tried adding done() to my upstream tasks, but it still errors because I'm thinking it originates here and propogates through my subsequent tasks that rely on this one finishing.
The problem ended up being the module event-stream. Apparently it is no longer being maintained.
#phated:
Support for event-stream is deprecated. Everything is supposed to move to through2, et al. Maybe just fully deprecate this module?
I switched to merge-stream and now my gulpfile works fine.
I have a node / angular project that uses npm for backend dependency management and bower for frontend dependency management. I'd like to use a grunt task to do both install commands. I haven't been able to figure out how to do it.
I made an attempt using exec, but it doesn't actually install anything.
module.exports = function(grunt) {
grunt.registerTask('install', 'install the backend and frontend dependencies', function() {
// adapted from http://www.dzone.com/snippets/execute-unix-command-nodejs
var exec = require('child_process').exec,
sys = require('sys');
function puts(error, stdout, stderr) { console.log(stdout); sys.puts(stdout) }
// assuming this command is run from the root of the repo
exec('bower install', {cwd: './frontend'}, puts);
});
};
When I cd into frontend, open up node, and run this code from the console, this works fine. What am I doing wrong in the grunt task?
(I also tried to use the bower and npm APIs, but couldn't make that work either.)
To install client side components during npm install at the same time than server side libs, you can add in your package.json
"dependencies": {
...
"bower" : ""
},
"scripts": {
...
"postinstall" : "bower install"
}
I prefer to make the difference between install and test/build
You need to tell grunt that you're using an async method (.exec) by calling the this.async() method, getting a callback, and calling that when exec is done.
This should work:
module.exports = function(grunt) {
grunt.registerTask('install', 'install the backend and frontend dependencies', function() {
var exec = require('child_process').exec;
var cb = this.async();
exec('bower install', {cwd: './frontend'}, function(err, stdout, stderr) {
console.log(stdout);
cb();
});
});
};
See Why doesn't my asynchronous task complete?
FYI, here is where i am for now.
You could also have taken the problem another way, i.e. let npm handle the execution of bower, and ultimately let grunt handle npm. See Use bower with heroku.
grunt.registerTask('install', 'install the backend and frontend dependencies', function() {
var async = require('async');
var exec = require('child_process').exec;
var done = this.async();
var runCmd = function(item, callback) {
process.stdout.write('running "' + item + '"...\n');
var cmd = exec(item);
cmd.stdout.on('data', function (data) {
grunt.log.writeln(data);
});
cmd.stderr.on('data', function (data) {
grunt.log.errorlns(data);
});
cmd.on('exit', function (code) {
if (code !== 0) throw new Error(item + ' failed');
grunt.log.writeln('done\n');
callback();
});
};
async.series({
npm: function(callback){
runCmd('npm install', callback);
},
bower: function(callback){
runCmd('bower install', callback);
}
},
function(err, results) {
if (err) done(false);
done();
});
});
Grunt task that does just this job (as per Sindre's solution above):
https://github.com/ahutchings/grunt-install-dependencies
Grunt task that does the bower install command :
https://github.com/yatskevich/grunt-bower-task
also , you can use
https://github.com/stephenplusplus/grunt-bower-install
to auto inject your dependencies into the index.html file