Closed roblav96 closed 8 years ago
Looks like it's coming from when I execute
cordova prepare
Here's the file:
testApp/plugins/cordova-plugin-browsersync/lib/projectHook.js
var path = require( 'path' );
var glob = require( 'glob' );
var Patcher = require( './utils/Patcher' );
var browserSyncServer = require( './utils/browserSyncServer' );
function parseOptions( opts ) {
var result = {};
opts.forEach( function ( opt ) {
var parts = opt.split( /=/ );
result[ parts[ 0 ].replace( /^-+/, '' ) ] = parts[ 1 ] || true;
} );
return result;
}
module.exports = function ( context ) {
var options = parseOptions( context.opts.options );
if ( typeof options[ 'live-reload' ] === 'undefined' ) {
return;
}
// TODO - Add back ignored option
// TODO - Enable live reload servers
var platforms = [ 'android', 'ios' ];
var patcher = new Patcher( context.opts.projectRoot, platforms );
var bs = browserSyncServer( function ( defaults ) {
defaults.files.push( {
match: [ 'www/**/*.*' ],
fn: function ( event, file ) {
if ( event === 'change' ) {
context.cordova.raw.prepare().then( function () {
patcher.addCSP();
bs.reload();
} );
}
}
} );
defaults.server = {
baseDir: platforms.map( patcher.getWWWFolder.bind( patcher ) ),
routes: {}
}
platforms.forEach( function ( platform ) {
var www = patcher.getWWWFolder( platform );
defaults.server.routes[ '/' + www ] = path.join( context.opts.projectRoot, www );
} );
return defaults;
}, function ( err, servers ) {
patcher.patch( {
servers: servers
} );
} );
}
I'm gonna keep trying to figure this out. Any help would be amazing!
Here's some more info:
Executing "before_prepare" hook for all plugins.
Generating config.xml from defaults for platform "android"
Wrote out Android application name to "HelloCordova"
This app does not have launcher icons defined
Wrote out Android package name to "io.cordova.hellocordova"
Generating config.xml from defaults for platform "ios"
Wrote out iOS Bundle Identifier to "io.cordova.hellocordova"
Wrote out iOS Bundle Version to "0.0.1"
iOS Product Name has not changed (still "HelloCordova")
Executing "after_prepare" hook for all plugins.
Error: TypeError: opts.forEach is not a function
at parseOptions (/Users/admin/Downloads/testApp/plugins/cordova-plugin-browsersync/lib/pluginHook.js:9:7)
at module.exports (/Users/admin/Downloads/testApp/plugins/cordova-plugin-browsersync/lib/pluginHook.js:17:16)
at runScriptViaModuleLoader (/usr/local/lib/node_modules/cordova/node_modules/cordova-lib/src/hooks/HooksRunner.js:151:18)
at runScript (/usr/local/lib/node_modules/cordova/node_modules/cordova-lib/src/hooks/HooksRunner.js:129:16)
at /usr/local/lib/node_modules/cordova/node_modules/cordova-lib/src/hooks/HooksRunner.js:114:20
at _fulfilled (/usr/local/lib/node_modules/cordova/node_modules/q/q.js:787:54)
at self.promiseDispatch.done (/usr/local/lib/node_modules/cordova/node_modules/q/q.js:816:30)
at Promise.promise.promiseDispatch (/usr/local/lib/node_modules/cordova/node_modules/q/q.js:749:13)
at /usr/local/lib/node_modules/cordova/node_modules/q/q.js:810:14
at flush (/usr/local/lib/node_modules/cordova/node_modules/q/q.js:108:17)
Commenting out these lines got it working:
// var options = parseOptions( context.opts.options );
// if ( typeof options[ 'live-reload' ] === 'undefined' ) {
// return;
// }
Still broken though after the second reload.
Error: listen EADDRINUSE :::3004
at Object.exports._errnoException (util.js:874:11)
at exports._exceptionWithHostPort (util.js:897:20)
at Server._listen2 (net.js:1234:14)
at listen (net.js:1270:10)
at Server.listen (net.js:1366:5)
at module.exports.plugin (/Users/admin/Downloads/syncz/node_modules/browser-sync/lib/server/index.js:24:25)
at Object.module.exports.startServer [as fn] (/Users/admin/Downloads/syncz/node_modules/browser-sync/lib/async.js:236:52)
at /Users/admin/Downloads/syncz/node_modules/browser-sync/lib/browser-sync.js:149:14
at iterate (/Users/admin/Downloads/syncz/node_modules/browser-sync/node_modules/async-each-series/index.js:8:5)
at /Users/admin/Downloads/syncz/node_modules/browser-sync/node_modules/async-each-series/index.js:16:16
Seems like the entire browsersync server creates another instance when a file is changed.
Will look at it now...
Can you help me understand your project setup? Are you adding this as a plugin, or as a hook ?
I'm adding this as a plugin. I'm following your video step by step.
I'm going to try and play around with adding as a hook.
Might another option be setting all this up manually?
Are there any global dependentcies I need installed?
Would you like to use teamviewer sometime? I'm in Boston, MA USA
Sure, we could do that sometime today. I am in PST. Weird that the plugin does not work. It should "just work". I will look in to see if there is an error in this code.
I'm free whenever you are.
I'll be in this chat room, channel "cordova". you don't need to auth or anything http://webchat.freenode.net/
my unsername is rob__
I edited your hook file like so and skipped the whole parsing function, which I never understood why it was there.
var port = parseInt(context.opts.options.argv)
console.log( 'port >', port )
require( 'dns' ).lookup( require( 'os' ).hostname(), function ( err, address, fam ) {
console.log( 'address >', address )
var tcpPortUsed = require( 'tcp-port-used' );
tcpPortUsed.check( port, address ).then( function ( inUse ) {
console.log( 'inUse >', inUse )
if ( inUse == false ) {
var platforms = [ 'android', 'ios' ];
var patcher = new Patcher( context.opts.projectRoot, platforms );
var bs = browserSyncServer( function ( defaults ) {
defaults.files.push( {
match: [ 'www/**/*.*' ],
fn: function ( event, file ) {
if ( event === 'change' ) {
context.cordova.raw.prepare().then( function () {
patcher.addCSP();
bs.reload();
} );
}
}
} );
defaults.server = {
baseDir: platforms.map( patcher.getWWWFolder.bind( patcher ) ),
routes: {}
}
platforms.forEach( function ( platform ) {
var www = patcher.getWWWFolder( platform );
defaults.server.routes[ '/' + www ] = path.join( context.opts.projectRoot, www );
} );
return defaults;
}, function ( err, servers ) {
patcher.patch( {
servers: servers
} );
} );
}
} )
} )
Then i just do:
cordova run android -d -- 3000
The problem was that every time it would trigger a refresh, a whole new browsersync instance would be created on top of the same port so it would error out and crash. Now I just pass in the port I'd like to use as a parameter so now I can use this on as many devices as I'd like.
I fixed this issue here - https://github.com/nparashuram/cordova-plugin-browsersync/commit/4b8f98a5a87e0e8707198b4f92f5cdffec1bec23
Looks like the way I was getting options from the command line was messed up - i thought context.opts.options should work, but look like there is another argv option there. This is needed so that the plugin is activated only when you call it with -- --live-reload
(Note the double dashes). The plugin should not be called any other time since it changes the <content src="index.html">
in every platform's config.xml
to point to the browsersync server.
We also need to pass options to let a user ignore watching certain files. Also, note that changing any file calls prepare, which invokes this plugin - that is the reason you get the error about Error: listen EADDRINUSE :::3004
when you disabled it. This is the same problem with your code, when you call prepare as a part of the after-prepare hook. You need a way to not call the same hook from when the files are changed.
With the fix above, you should be good. Please let me know if that works.
Btw, I hangout in the Cordova slack channel here - http://cordova.slack.com/. I am axemclion
. So feel free to ping me if this is still an issue.
Interesting. I'll have to try this out as soon as I get home. Thank you!!!
@roblav96 Closing this issue as there is no more activity on this required. Please re-open if this issue is still not resolved.
Ok thanks man!
Following your video directly and I can't do
It says:
Any ideas?