vigetlabs / blendid

A delicious blend of gulp tasks combined into a configurable asset pipeline and static site builder
MIT License
4.97k stars 682 forks source link

browserSync proxy and HMR ... is it possible? #295

Closed besimhu closed 7 years ago

besimhu commented 8 years ago

Let me start off by saying thanks for all of the hard work that has been poured into these build tools.

Over the weekend I had been working on a project and while it works wonderful on localhost. Eventually I'd love to switch over to a proxy setup with browserSync. I primarily utilize this method for local WP or Craft development.

I've looked throughout browserSync.js and noticed there were proxy calls. And while I was able to pass in a proxy address in, everything setup wise works. It's just that HMR will not trigger.

My guess is that is has something to do with the public path. I've also been researching online and come across discussions that webpack-hot-module doesn't support proxy setups.

https://github.com/webpack/webpack-dev-middleware/issues/67 http://code.fitness/post/2016/02/webpack-public-path-and-hot-reload.html

I ended up changing the proxyConfig to var proxyConfig = "l.local-url" || null; to work. And in the config

"browserSync": {
  "server": false
}

Any help would be helpful.

mmikkel commented 8 years ago

For me, HMR with BrowserSync proxying is actually working pretty much out of the box – the only thing that tripped me up initially was that I've set the root.dest property in config.json to a sub folder ("./public/assets", in my case), which means that BrowserSync will use the wrong path for HMR because in the vanilla setup the public path is equal to the config.tasks.js.dest path.

Here's what I did to make it work:

First, I added a new property to the browserSync task in config.json, called path, and set it to the sub folder where my code is compiling:

"browserSync": {
    "proxy": "example.dev",
    "path": "assets"
},

Then, I added the browserSync.path property to the public path in /tasks/browserSync.js:

server.middleware = [
    require('webpack-dev-middleware')(compiler, {
      stats: 'errors-only',
      publicPath: pathToUrl('/', config.tasks.browserSync.path, webpackConfig.output.publicPath)
    }),
    require('webpack-hot-middleware')(compiler)
  ]

That's it; works like a charm.

dillonbailey commented 7 years ago

@mmikkel @besimhu I similarly went through this exact process once I got into developing the templates in Wordpress.

Essentially my folder structure ended up with:

-wp-content
--themes
---<our-theme>
----gulp starter is in here with the standard theme files

Borrowing from @mmikkel above I ended up with:

{
  "root": {
    "src": "./src",
    "dest": "./assets"
  },

  "tasks": {
    "browserSync": {
      "proxy": "http://<our-theme>.dev",
      "path": "wp-content/themes/<our-theme>/assets"
    },

Which sort of got me thinking and wondering if there shouldn't be a npm run proxy that watches CMS files (in this case php) and builds assets to a different destination than the static site to save clogging up the assets folder with the *.html files we're not currently focusing on?

Typically in these cases I find most people will just start to kick out their JS and CSS with a copy task and call it a day, but if we want BrowserSync and Webpack still firing on all cylinders I think it makes sense to have a npm run cms-start and npm run start doing separate things?

What do you guys think?

1stevengrant commented 7 years ago

@mmikkel where did you define pathToUrl in your solution?

greypants commented 7 years ago

@dillonbailey you can pass a files option to the browserSync config to specify additional files to watch and reload on (CMS files). I usually point it at the templates folder for whatever platform i'm on (Rails, Craft, Django, etc).

https://browsersync.io/docs/options#option-files

besimhu commented 7 years ago

@mmikkel @dillonbailey just wanted to throw out a very late thank you. I had forgotten to check on this until recently. I ended up switching to a browserify approach. But yes, I too ended up going a similar approach later.

The path option makes sense. Here's an example of how I have it working with blendit:

// task-config.js
browserSync: {
  path: 'wp-content/themes/theme-name/assets',
  server: false,
  proxy: 'proxy-url.dev',
  open: true,
  notify: false,
  reloadOnRestart: true,
  files: [
    './**/*.php',
    '!node_modules/'
  ]
},

... and in gulpfile.js/tasks/browserSync.js replace line 40 with

publicPath: pathToUrl('/', TASK_CONFIG.browserSync.path, webpackConfig.output.publicPath)

All my files are built in the /assets/ folder with the exception of styles. Which is sent to the theme root.

"stylesheets": {
  "src": "stylesheets",
  "dest": "./../"
},
dillonbailey commented 7 years ago

@besimhu with the latest blendid I don't think the adjustment to gulpfile.js/tasks/browserSync.js is necessary but I haven't tested with the latest.

Glad you got it working!

besimhu commented 7 years ago

@dillonbailey I wasn't able to get it working without the adjustment ... unless of course I handled something differently.