{"action":"created","issue":{"url":"https://api.github.com/repos/systemjs/systemjs/issues/1222","repository_url":"https://api.github.com/repos/systemjs/systemjs","labels_url":"https://api.github.com/repos/systemjs/systemjs/issues/1222/labels{/name}","comments_url":"https://api.github.com/repos/systemjs/systemjs/issues/1222/comments","events_url":"https://api.github.com/repos/systemjs/systemjs/issues/1222/events","html_url":"https://github.com/systemjs/systemjs/issues/1222","id":149447527,"number":1222,"title":"Proposal: Integrate HMR primitives into SystemJS Core","user":{"login":"alexisvincent","id":1898669,"avatar_url":"https://avatars.githubusercontent.com/u/1898669?v=3","gravatar_id":"","url":"https://api.github.com/users/alexisvincent","html_url":"https://github.com/alexisvincent","followers_url":"https://api.github.com/users/alexisvincent/followers","following_url":"https://api.github.com/users/alexisvincent/following{/other_user}","gists_url":"https://api.github.com/users/alexisvincent/gists{/gist_id}","starred_url":"https://api.github.com/users/alexisvincent/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexisvincent/subscriptions","organizations_url":"https://api.github.com/users/alexisvincent/orgs","repos_url":"https://api.github.com/users/alexisvincent/repos","events_url":"https://api.github.com/users/alexisvincent/events{/privacy}","received_events_url":"https://api.github.com/users/alexisvincent/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/systemjs/systemjs/labels/discussion","name":"discussion","color":"fef2c0"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":11,"created_at":"2016-04-19T12:31:32Z","updated_at":"2016-05-02T15:30:28Z","closed_at":null,"body":"I would like to propose that we integrate HMR primitives into SystemJS Core. I think this would add to the  tooling capacity of the project and allow for interesting integrations. While [capaj/systemjs-hot-reloader](https://github.com/capaj/systemjs-hot-reloader) is great at an application level, it forces you to use its own events API which is problematic for anyone trying to create tooling around SystemJS & HMR. And while you can implement your own HMR logic void of an events system, HMR is a straight forward enough problem (at least where SystemJS is concerned) that this logic could be appropriately included into the core project.\r\n\r\nI think the lack of supporting tooling built around SystemJS is one of the core reasons SystemJS feels 'hard' for new users and I think proper HMR support would go a long way to increase developer interest in the project.\r\n\r\n@gaearon has released an alpha for [React Hot Loader 3](https://github.com/gaearon/react-hot-boilerplate/pull/61#issuecomment-211627184) that will play brilliantly with SystemJS, allowing us to reload components without loosing state or destroying the DOM. Since JSPM 0.17 now uses Babel 6, @gaearon's react-hot-loader/babel transform would serve the vast majority of people. Otherwise it shouldn't be hard to implement a SystemJS plugin to do this. \r\n\r\nMy proposal for SystemJS HMR would be to quite simply expose a\r\n```js\r\nSystem.reload(\"./someModule.js\")\r\n```\r\nInternally it could function almost exactly like [capaj/systemjs-hot-reloader](https://github.com/capaj/systemjs-hot-reloader), recursively deleting modules up the dependency tree and then reimporting them. While this is a simple extension I think it would act as an enabler for further tooling.\r\n\r\nAt this point it might be worth thinking about a potential plugin unload hook. That would fire on a\r\n```js\r\nSystem.delete(\"./someModule\")\r\n```\r\nLet's say for instance that a JS unload hook might call ```__unload()``` if such a function is exported from the module. This would cater both for https://github.com/capaj/systemjs-hot-reloader#unload as well as a general use case if a module is forcefully deleted.\r\n\r\nAdded loader unload hooks would also solve issues like https://github.com/systemjs/plugin-css/issues/81 and some extension of this idea might solve https://github.com/capaj/systemjs-hot-reloader/issues/37. Providing us with true CSS/SCSS reloading.\r\n\r\nWith regards to hydrating state after a reload I can see two ways to do this. The first would be the way [capaj/systemjs-hot-reloader](https://github.com/capaj/systemjs-hot-reloader) currently does it, which is to export a ```__reload(module)``` function and have that fired after the module has rerun on reload.\r\n\r\nThis works well until you want to incorporate reload logic into your standard module initialisation code and perhaps export a variable that might exist on the previous module instance. My suggestion would be to pass in the old instance of the module as a 'local/global' variable directly available to the module. This would allow for more complex handling of reload logic when required. Cleaning up reload behaviour for production (if required) could be easily handled via dead code removal as is standard in the industry (via JSPM's ``` bundle --production ``` flag?).\r\n\r\nImplementing something similar to the above proposal would change the focus of [capaj/systemjs-hot-reloader](https://github.com/capaj/systemjs-hot-reloader) and other tooling rather into one of handling file change events. This would also make it trivial for developers to build their own bundling logic if they so required.\r\n\r\nSome extra food for thought:\r\nA `System.reload(\"./someModule.js\")` function could additionally take in ***source code*** as a second argument.\r\n```js\r\nSystem.reload(\"./someModule.js\", source)\r\n```\r\nThis would mean that a file-watcher/socket system could pass the new code to the client directly. For a satisfyingly fast development loop.\r\n\r\n@guybedford Let me know what you think.\r\nAlso, @tyscorp this might interest you."},"comment":{"url":"https://api.github.com/repos/systemjs/systemjs/issues/comments/216268225","html_url":"https://github.com/systemjs/systemjs/issues/1222#issuecomment-216268225","issue_url":"https://api.github.com/repos/systemjs/systemjs/issues/1222","id":216268225,"user":{"login":"alexisvincent","id":1898669,"avatar_url":"https://avatars.githubusercontent.com/u/1898669?v=3","gravatar_id":"","url":"https://api.github.com/users/alexisvincent","html_url":"https://github.com/alexisvincent","followers_url":"https://api.github.com/users/alexisvincent/followers","following_url":"https://api.github.com/users/alexisvincent/following{/other_user}","gists_url":"https://api.github.com/users/alexisvincent/gists{/gist_id}","starred_url":"https://api.github.com/users/alexisvincent/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexisvincent/subscriptions","organizations_url":"https://api.github.com/users/alexisvincent/orgs","repos_url":"https://api.github.com/users/alexisvincent/repos","events_url":"https://api.github.com/users/alexisvincent/events{/privacy}","received_events_url":"https://api.github.com/users/alexisvincent/received_events","type":"User","site_admin":false},"created_at":"2016-05-02T15:30:28Z","updated_at":"2016-05-02T15:30:28Z","body":"@guybedford Cool, I would suggest a clean ```System.reload('moduleName', 'moduleValue')```. This can be the sum total of the api (keeping it light). Then later if you would like to introduce it to the api the unload part can be moved to the responsibility of ```System.delete```."}}