BrowserSync / browser-sync

Keep multiple browsers & devices in sync when building websites. https://browsersync.io
https://discord.gg/2d2xUThp
Apache License 2.0
12.17k stars 756 forks source link

Feature Request: server mode for assets, proxy for HTML #514

Closed fvsch closed 9 years ago

fvsch commented 9 years ago

Unless I've missed on option, the server and proxy modes are mutually exclusive. Would it be possible to use the server mode, but with the proxy mode as a fallback?

Say I have a website that can only be tested on a development or staging server that I don't control. I happen to have the CSS and JS sources (possibly in many files and several formats, with build scripts or tools). A rather good workflow would be:

  1. Checkout the front-end assets in a local working directory.
  2. Tell BrowserScript to watch and serve those assets, and fallback to a proxy domain for everything it can't find locally (dynamically generated HTML from a CMS/server-side app + database, user files, etc.).
  3. Get instant feedback when changing CSS, and ability to reload and get my changes when changing JS code.

Of course I couldn't do 100% of my work as a front-end dev like this, but for a lot of stuff when I don't need to touch templates that would be great.

Specific use cases I have where this would be useful:

Hence the need for distant HTML, and local CSS/JS, both through BrowserSync.

shakyShane commented 9 years ago

Sure, just use the serve-static middleware along with the proxy and you'll be good to go.

var browserSync = require("browser-sync");

browserSync({
    proxy: "staging.yoursite.com",
    open:  false,
    files: "path/to/assets/**",
    middleware: require("serve-static")("path/to/assets")
});

Of course, this will only work by directly mapping your assets directory to what is being requested by the browser - so it's fragile, but do able.

Since 2.4.0 I've also added the rewriteRules option that allows you to modify the HTML response of the proxy, so you can do cool stuff like this: http://quick.as/w6ri32qe

fvsch commented 9 years ago

Thanks for the information. I updated to 2.4.0, installed serve-static, and made it work with a config file like so:

module.exports = {
    proxy: 'staging.website.localnetwork',
    files: 'assets-copy/**',
    middleware: require('serve-static')('./assets-copy'),
    rewriteRules: [{
        match: new RegExp('/assets/css/styles.css'),
        fn: function() {
            return ('/css/styles.css')
        }
    }]
}

In this case I have the sources on my machine, and the paths are similar, but I still duplicated the assets folder to make sure the rewriting and static-serving were working.

fvsch commented 9 years ago

Of course, this will only work by directly mapping your assets directory to what is being requested by the browser.

In my previous comment I used rewriteRules because I couldn't make this simple case work after many tests. Turns out I was passing the wrong path to serve-static.

serve-static receives the full path of the request, in my case that was /assets/css/styles.css (same domain absolute URL, from <link href="/assets/css/styles.css">). When I configured it to look in assets-copy as above, it would fail, because assets-copy/assets/css/styles.css didn't exist. So my rewriteRule above only rewrites the URL static-serve receives, manually stripping the /assets part from the URL. Phew. Took me long enough to figure that out. ^^

So, in the case where the URLs for static files do match your local path, it gets simpler:

Folder structure:
    project-root/
        bs-config.js
        web/
            assets/

URLs for assets:
    '/assets/something/something'
module.exports = {
    proxy: 'staging.website.localnetwork',
    files: 'web/assets/**',
    middleware: require('serve-static')('web'),
}
shakyShane commented 9 years ago

@fvsch - nice work!

Glad I good help, I see this being a useful workflow.

fvsch commented 9 years ago

So I wrote a long explanatory gist on this workflow: https://gist.github.com/fvsch/cf7a7decf639c8372b8c

shakyShane commented 9 years ago

Very nice - we must great a recipe for this.