Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not inject new code #18

Open
aegyed91 opened this issue Jan 8, 2016 · 9 comments
Open

Does not inject new code #18

aegyed91 opened this issue Jan 8, 2016 · 9 comments

Comments

@aegyed91
Copy link

aegyed91 commented Jan 8, 2016

Hello @agentme could you please help me out a bit? I having hard times getting this thing to work.

It seems like updates being emitted early, but i don't think so this is the problem because it never inject the code changed in the previous save.

Browser console:

[HMR] Websocket connection successful.
index.js:514 [HMR] Updated modules ["src/javascripts/main.js"]
index.js:514 [HMR] Updated modules ["src/javascripts/main.js"]

This is how my gulpfile looks:

let options = { debug: true };

if (config.isDev) _.extend(options, watchify.args);

let bundler = browserify(paths.src, options).plugin(hmr);

bundler.transform(babelify);
bundler.transform(hbsfy);
bundler.transform(envify);

if (config.isDev) {
  bundler = watchify(bundler);
  bundler.on('update', () => gulp.start('js'));
}

function bundle() {
  return bundler.bundle()
    .on('error', onError)
    .pipe(source(config.js.bundleName))
    .pipe(buffer())
    .pipe(sourcemaps.init({ loadMaps: true }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(paths.dest))
    // .pipe(bs.stream({ once: true }));
}

gulp.task('js', preTasks, () => bundle());

Terminal:

[BS] Serving files from: public
GET / 200 10.957 ms - 486
GET /stylesheets/main.css 200 4.258 ms - 560724
GET /javascripts/main.js 200 1.663 ms - 1816775
GET /javascripts/main.js.map 200 3.722 ms - 2103596
19:34:59 GMT+0100 (CET) [HMR] User connected, syncing
[19:35:05] Starting 'js'...
19:35:06 GMT+0100 (CET) [HMR] Emitting updates
[19:35:07] Finished 'js' after 1.67 s
[19:35:12] Starting 'js'...
19:35:13 GMT+0100 (CET) [HMR] Emitting updates
[19:35:13] Finished 'js' after 1.22 s

I also use browsersync for server can that be a problem?

gulp.task('browser-sync', () => {
  bs.init({

    // A, if you don't have a backend api use the built in server
    server: {
      baseDir: 'public'
    },

    // B, if you got a backend api proxy the request to it
    // proxy: 'some-vhost-of-existing-backend.api',

    // custom middleware for mock api
    middleware(req, res, next) {
      require('../../api/api')(req, res, next);
    },

    // default port
    port: config.isProd ? 8080 : 3000,

    // disable notify popup
    notify: false,

    // do not open browser on start
    open: false,

    // disable UI completely
    ui: false
  });
@Macil
Copy link
Owner

Macil commented Jan 12, 2016

If you're seeing the "Emitting updates" and "Updated modules" messages, then your build process is likely correct. The issue is probably that you don't have any code calling module.hot. See #16.

@tj
Copy link

tj commented Mar 21, 2016

I'm getting this as well, is there a way to get more verbose logging?

@nicolas-zozol
Copy link

I have also the same problem. As I use websocket, I should not have to add js code, no ?

From the node console :

22:48:11 GMT+0200 (CEST) [HMR] User connected, syncing
updated source
22:48:29 GMT+0200 (CEST) [HMR] Emitting updates
864035 bytes written (0.78 seconds)

From the Dev tool console :


[HMR] Attempting websocket connection to http://localhost:3123
admin.ts:13creating an admin
index.js:425 [HMR] Websocket connection successful.
index.js:514 [HMR] Updated modules ["modules/template.html", "modules/admin.ts", "index.ts"]

@Macil
Copy link
Owner

Macil commented Apr 1, 2016

Are you using module.hot.accept (or a transform that uses it for you, like react-transform-hmr) anywhere in your code? You need to, or else Browserify-HMR won't know how to update your code and you'll run into this issue.

@nicolas-zozol
Copy link

Not at all. Where do we find it ?

@Macil
Copy link
Owner

Macil commented Apr 1, 2016

Browserify-HMR and Webpack HMR update files by executing them again, but you have to first mark which files can accept updates by using module.hot.accept.

A file can accept updates of itself like this:

console.log("foo");
if (module.hot) {
  module.hot.accept();
}

Each time you edit that file, it will execute (and log something again, unless you've removed that statement). Now that's not terribly useful. Usually you want to update functions or classes in-place that are required by other files. Or maybe you want to update already instantiated instances of a class. This takes more effort to set up. I plan to write a bit about this, but I've been delaying that until I polish up and fix a few bugs in Browserify-HMR (like these misleading log statements).

If your project uses React, then go use react-transform-hmr, and all of your files that define React components will automatically be hot-replaceable and you can stop reading here if you want!

If you use the ud library, then it handles using the module.hot APIs to accomplish common tasks for you, and you can make a file with a hot-replaceable function like this:

var ud = require('ud');

// You can edit this function in a live application!
function greeting(name) {
  return "Hello, "+name;
}

module.exports = ud.defn(module, greeting);

or you can make a hot-updateable class like this in ES6:

import {defn} from 'ud';

class Greeter {
  // Changes to this constructor will only affect future instances of Greeter. Changes 
  // to it can't affect instances that have already been constructed!
  constructor(ownName) {
    this._ownName = ownName;
  }
  // Changes to this method will affect all current and future instances of Greeter
  // immediately!
  greet(name) {
    return `Hello ${name}, this is ${this._ownName}`;
  }
}

// defn works on both functions and classes, because they're the same in Javascript
// anyway.
export default defn(module, Greeter);

It's a bit of boilerplate, but the control it gives you is necessary when you have file-scoped state that needs to be persisted between updates (ud's defonce function helps here). I've been brainstorming about automatic code transform tools to make this not necessary, but I haven't yet figured out a technique that would fit all of the needs I've seen in real codebases that ud is able to handle now.

@nicolas-zozol
Copy link

Thanks for your reply. It makes thing much more clear.

@linus-amg
Copy link

Hi @agentme, did you yet came to write a little more about how to update already instantiated instances? I'm referring to your comment: "Or maybe you want to update already instantiated instances of a class. I plan to write a bit about this, but I've been delaying that until I polish up and fix a few bugs in Browserify-HMR"

@mykone
Copy link

mykone commented Nov 2, 2016

Hello @agentme, I am having this issue too. Also, I am using Browserify+Watchify+BrowserSync. I did use the module.hot.accept() in my custom HMR-like class. I am not using ud or React so I am just adding the following code at the end of my ES6 class.

if(module.hot){
   module.hot.accept();
}

I am also getting these outputs in the browser console:

[HMR] Updated modules ["./moduleName.js"]

However, it seems the JS code isn't being re-inject in the tag just like WebPack does.

Any ideas on what's causing this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants
@tj @mykone @Macil @nicolas-zozol @aegyed91 @linus-amg and others