So, We have installed this on our development server got it working however if a second person runs a server it overwrites because; well, it's the same server I might be missing it however multiple instances would be sweet.
Can you explain what you mean by this in more detail?
Are you using the server or proxy option?
This:
campaignGulp.setCampaignBrowserSyncTasks = function (campaign, port) {
var taskName = campaign + ':browserSync';
gulp.task(taskName, function () {
browserSync({
host: '192.168.33.22', //@todo is it needed?
proxy: campaign + '.dev',
port: port
});
});
return taskName;
};
if used more than 1 time opens multiple windows when started.
if called 4 times: It posts 4 times and the browser opens 3 times, really wierd
Every time you call browserSync(), a new instance will be created - that's why the browser is opening multiple times.
You need to structure your tasks so that the one that wraps BrowserSync is only ever called once.
Is there the possibility though for multiple proxies and servers. I want to proxify several folders that are small apps in a bigger project.
I'm likewise encountering this problem. At work, we're highly invested in Java, yet we're trying to transition much of our front-end to take advantage of Node and npm. I want to keep the two systems as independent from one another as possible. Ideally, I want two BrowserSync instances. The first is a proxy to the Java app, and the second is my front-end build system. I want the second to tell the proxy to reload when watching file changes.
I've resolved this by quickly creating browser-sync-instance. I don't intend to publish this npm module, assuming that this functionality will eventually be natively supported by BrowserSync.
@basham Thanks for the link. Might give it a try.
@basham - thanks for your module, I've used it as inspiration for the upcoming feature in BrowserSync.
It's taken a while because I wanted to do this in a non-breaking-change way (which is trickier than it sounds!) & also I think the _vast_ majority of users will still only use a single instance.
So the api will be as it was before for a singleton:
var browserSync = require("browserSync");
browserSync.emitter.on("file:changed", fileChangeFn); // Emitter access still works
browserSync.use(require("some-plugin")); // plugins still work
browserSync({server: true}); // run the instance
But, for multiple instances, you use the .create method.
var browserSync = require("browserSync");
var bs1 = browserSync.create("first server"); // Create a named instance
var bs2 = browserSync.create("proxy"); // Create a second named instance
bs1.use(require("some-plugin")); // Add a plugin to first instance only
bs1.init({
port: 3000,
server: "./app"
});
bs2.init({
port: 3001,
proxy: "mylocal.dev"
});
Finally, you can also retrieve any previously created instances from the main module. (useful if you cannot save the result of .create() in a local variable).
var browserSync = require("browserSync");
browserSync.create("first server"); // Create a named instance
// Somewhere else in your code
browserSync.get("first server").init({
port: 3000,
server: "./app"
});
Hopefully this will satisfy every use-case whilst also allowing the singleton pattern.
Check out the progress here https://github.com/shakyShane/browser-sync/blob/feature/multi-instance/index.js.
Getting multiple sites handled within a single BS instance (daemonized, systemd unit) is very interesting to me, so I did some issue list research. Looks like #172 (issue at hand), #304, #284, #234 all seem to be related in one way or another.
This one, #172, seems to be the most comprehensive ticket towards taking the next step, so I'll post my findings and ideas here for now. But perhaps what I'm talking about needs a separate issue, let me know. Here goes.
I got a single instance BS 1.8.2 running across multiple domains / sites using Apache as a proxy in front of it, which takes care of all rewrites to localhost:3000. It is clear now though that BS does not differentiate between sites, contexts, rooms, namespaces or whatever we want to call it. If the browser connects to the same BS instance from meh.site.com and blah.site.com, two completely different sites, at the moment BS will share CSS and ghost these two completely different into happy oblivion.
Two things that came to mind immediately:
<script>
var _bs = _bs || [];
_bs.push('namespace', 'meh.site.com-feature-x');
// or
_bs.push('namespace', 'meh.site.com-hotfix-y');
</script>
When BS library loads itself, it should initialize itself with this connection info pre-configuration.
If the socket.io level namespacing perhaps already works for separating communications within a single instance, this would be world domination uber power. Wdyt?
EDIT I'm not sure at all that I'm not missing any other big architectural restrictions in BS current gut code, as related to the topic at hand. Enlightenment welcome.
@shakyShane Glad the browser-sync-instance project was able to inspire this feature work. Like the additions to the API.
@shakyShane I'm not able to start this using Gulp. Just pasting in your example above fails, as (I'm guessing) both UIs tries to bind to the same port.
[10:50:20] Using gulpfile ~/repos/frontend-repo/code/gulpfile.js
[10:50:20] Starting 'browser-sync'...
[10:50:20] Finished 'browser-sync' after 21 ms
[BS] [info] Proxying: http://mylocal.dev
[BS] Access URLs:
------------------------------------
Local: http://localhost:3003
External: http://10.2.22.101:3003
------------------------------------
UI: http://localhost:3001
UI External: http://10.2.22.101:3001
------------------------------------
[BS] Access URLs:
------------------------------------
Local: http://localhost:3000
External: http://10.2.22.101:3000
------------------------------------
UI: http://localhost:3001
UI External: http://10.2.22.101:3001
------------------------------------
[BS] Serving files from: ./app
events.js:72
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE
at errnoException (net.js:905:11)
at Server._listen2 (net.js:1043:14)
at listen (net.js:1065:10)
at Server.listen (net.js:1139:5)
at Object.module.exports.startServer [as fn] (/home/testyo/repos/frontend-repo/code/node_modules/browser-sync/node_modules/browser-sync-ui/lib/async.js:99:39)
at /home/testyo/repos/frontend-repo/code/node_modules/browser-sync/node_modules/browser-sync-ui/lib/UI.js:126:14
at iterate (/home/testyo/repos/frontend-repo/code/node_modules/browser-sync/node_modules/async-each-series/index.js:8:5)
at /home/testyo/repos/frontend-repo/code/node_modules/browser-sync/node_modules/async-each-series/index.js:16:16
at /home/testyo/repos/frontend-repo/code/node_modules/browser-sync/node_modules/browser-sync-ui/lib/UI.js:134:13
at Object.module.exports.setUrlOptions [as fn] (/home/testyo/repos/frontend-repo/code/node_modules/browser-sync/node_modules/browser-sync-ui/lib/async.js:62:9)
Process finished with exit code 8
I can't find this in the docs on your website, that's why I ask here instead of making an issue :smile:
Using 2.0.1 release
@SimenB - yeah sorry, this hasn't been added to the docs yet, because of this reason (the race condition with the ports).
You could do this though, and it'll work fine
var browserSync = require("browser-sync");
var bs1 = browserSync.create("proxy1");
var bs2 = browserSync.create("proxy2");
bs1.init({
proxy: "http://mylocal.dev"
}, function () {
bs2.init({
proxy: "http://mylocal2.dev"
});
});
... In this case, the first proxy has already resolved 2 ports, 1 for BrowserSync core + 1 for the UI.
The alternative is to provide all ports ahead of time, if you know them.
var browserSync = require("browser-sync");
var bs1 = browserSync.create("proxy1");
var bs2 = browserSync.create("proxy2");
bs1.init({
proxy: "http://mylocal.dev",
port: 3010,
ui: {
port: 3011
}
});
bs2.init({
proxy: "http://mylocal.dev",
port: 3012,
ui: {
port: 3013
}
});
There we go, that works beautifully. Thanks for the quick response!
Additional question, can I serve a subdirectory at root?
E.g. proxying http://example.com/subdomain at http://localhost:3010 instead of http://localhost:3010/subdomain?
Or can I serve under a subdomain?
@SimenB - that's not currently available I'm afraid - it would involve us having to re-write every single request before it hits your server - doable with middleware maybe? https://github.com/BrowserSync/browser-sync/blob/master/examples/proxy.middleware.js (need latest version for that)
Closing this thread as this is now possible using the technique described https://github.com/BrowserSync/browser-sync/issues/172#issuecomment-74232625
@shakyShane v2 didn't include any incremental provisions for client-side reconfiguration, for the context-separation idea comment or otherwise, right? Could you give me an indication on how you feel about the concept? I could determine the next step forward then.
EDIT or this is a browser-sync-client topic?
Here my happy experience with this feature.
I can have in parallel 1 BrowserSync instance for my 'regular' coding and 1 BrowserSync instance on another port for Protractor so they don't interfere with each other. gulpfile.js snippet:
var browserSync = require('browser-sync');
function browserSyncInit(port, baseDir) {
var browser = browserSync.create();
browser.init({
port: port,
server: {
baseDir: baseDir
},
...
});
return browser;
}
gulp.task('serve', ['styles', 'scripts'], function() {
var browser = browserSyncInit(9000, ['.tmp/app', 'app']);
gulp.watch(['app/*.html'], browser.reload);
gulp.watch(['app/**/*.scss'], ['styles', browser.reload]);
gulp.watch(['app/**/*.ts', 'lib/**/*.ts'], ['scripts', browser.reload]);
});
function runProtractor() {
var browser = browserSyncInit(9001, ['.tmp/app', 'app']);
gulp.src('.tmp/test/e2e/all.js')
.pipe($.protractor.protractor({
configFile: 'protractor.conf.js'
}))
.on('error', function(e) {
// Make sure failed tests cause gulp to exit non-zero
throw e;
})
.on('end', function() {
browser.exit();
});
}
gulp.task('test:e2e', ['build:test:e2e', 'webdriver-update'], runProtractor);
I am facing the same issue. Everything is working perfect on window and mac. But when i run the application on ubuntu 12.4+. gives the following error:
[09:03:54] all files 272.87 kB
[09:03:54] Finished 'scripts' after 4.38 s
[09:03:54] Starting 'inject'...
[09:03:54] gulp-inject 1 files into 404.html.
[09:03:54] gulp-inject 1 files into index.html.
[09:03:54] gulp-inject 77 files into 404.html.
[09:03:54] gulp-inject 77 files into index.html.
[09:03:54] Finished 'inject' after 522 ms
[09:03:54] Starting 'watch'...
[09:03:55] Finished 'watch' after 214 ms
[09:03:55] Starting 'serve'...
[09:03:55] Finished 'serve' after 25 ms
[BS] [BrowserSync SPA] Running...
[BS] Access URLs:
Local: http://localhost:8080/
External: http://192.168.1.4:8080/
UI: http://localhost:3001
UI External: http://192.168.1.4:3001
[BS] Serving files from: .tmp/serve
[BS] Serving files from: app
events.js:72
throw er; // Unhandled 'error' event
^
Error: spawn ENOENT
at errnoException (child_process.js:1011:11)
at Process.ChildProcess._handle.onexit (child_process.js:802:34)
bhagat:/var/www/smart-dms/dms/client_side$
My code snippet is as below :
'use strict';
var gulp = require('gulp');
var browserSync = require('browser-sync');
var browserSyncSpa = require('browser-sync-spa');
var util = require('util');
var middleware = require('./proxy');
module.exports = function(options) {
function browserSyncInit(baseDir, browser) {
browser = browser === undefined ? 'default' : browser;
var routes = null;
if(baseDir === options.src || (util.isArray(baseDir) && baseDir.indexOf(options.src) !== -1)) {
routes = {
'/bower_components': 'bower_components'
};
}
var server = {
baseDir: baseDir,
routes: routes,
port:8080
};
if(middleware.length > 0) {
server.middleware = middleware;
}
browserSync.instance = browserSync.init({
startPath: '/',
server: server,
browser: browser,
port:8080
});
}
browserSync.use(browserSyncSpa({
selector: '[ng-app]'// Only needed for angular apps
}));
gulp.task('serve', ['watch'], function () {
browserSyncInit([options.tmp + '/serve', options.src],'Google Chrome');
});
gulp.task('serve:dist', ['build'], function () {
browserSyncInit(options.dist, 'Google Chrome');
});
gulp.task('serve:e2e', ['inject'], function () {
browserSyncInit([options.tmp + '/serve', options.src], []);
});
gulp.task('serve:e2e-dist', ['build'], function () {
browserSyncInit(options.dist, []);
});
};
-_- if create different browserSync with diff port,it still a 'cross origin' url, front-end still invoke it by jsonp and post method won't work.
This thread gives me the closest to using multiple subdomains with Browsersync, via this comment.
Is there a way that each BS init can do rewrites when one or the other references each other?
For example, in his example above, bs1 used for http://mylocal.dev translates into http://localhost:3010. However, there are several links in bs1 that are the same as bs2 init, but they are not rewritten in bs1 instance to http://localhost:3012. The opposite is also true.
Any solutions to fix this?
How we can restrict browser-sync to run on the same port as the backend is running using react gulp and asp.net core.
Most helpful comment
@SimenB - yeah sorry, this hasn't been added to the docs yet, because of this reason (the race condition with the ports).
You could do this though, and it'll work fine
... In this case, the first proxy has already resolved 2 ports, 1 for BrowserSync core + 1 for the UI.
The alternative is to provide all ports ahead of time, if you know them.