Issue with paths of reloaded module
ArmorDarks opened this issue · 8 comments
Hi @alexisvincent!
Sorry for bothering you again, but we have some troubles. Again.
I'm not sure that it is systemjs-hot-reloader
issue, and maybe it is more related to configuration of JSPM. Though, I'm not sure.
We have following file structure, which you can see here.
Just to be more clear, we have
|- source/scripts <- this is where lives sources of frontend-related code
| |- main.js <- main entry point
| | ...
|- build <- from where server (Browser Sync) serves all files, everything built in that directory
| |- index.html <- where System.import('main.js') invoked
| | ...
|- jspm_packages
|- jspm.config.js
| ...
Well, you can see here a bit tricky situation, when jspm_packages
and main.js
located outside of directory, which actually served. This isn't a problem for production, since on production JSPM just builds single file into build/assets/scripts/main.js
, then index.html
loads it and everyone happy and so on.
But gets trickier in development environment, since we want to load sources directly, without building or copying them.
To do this, we're providing for Browser Sync some additional routes, to make certain directories be available under specific urls
routes:
'/jspm_packages': 'jspm_packages'
'/jspm.config.js': 'jspm.config.js'
This is quite straightforward. Now
<script src="/jspm_packages/system.js"></script>
<script src="/jspm.config.js"></script>
will work, even despite it located outside of served directory. Not a problem.
But next part is quite tricky, and maybe it is where I messing something wrong, so that systemjs-hot-reloader
receives wrong path. I tried different approaches, but all of them ended in quite same situation.
The esiest way for me was to route /assets/scripts
to point to /source/scripts
:
routes:
'/jspm_packages': 'jspm_packages'
'/jspm.config.js': 'jspm.config.js'
'/assets/scripts': 'source/scripts'
Now I can write in my jspm.config.js
specific baseUrl
for browser:
SystemJS.config({
browserConfig: {
baseURL: "/assets/scripts",
"paths": {
"npm:": "/jspm_packages/npm/",
"github:": "/jspm_packages/github/",
"kotsu/": ""
}
},
...
And it will properly import main.js
in html:
<script>
SystemJS.import('systemjs-hot-reloader').then((connect) => {
connect()
SystemJS.import('main.js')
})
</script>
Everything works fine. But if I will edit any js
file and save it, hot-reloading won't kick-in.
Here what shows debugger:
Ass you can see, it appends to baseUrl
full path from root (where chokidar has been launched) to baseUrl
, thus we're receiving wrong path:
http://localhost:3000/assets/scripts/source/scripts/components/Input.js
while expected one is
http://localhost:3000/{{ baseUrl }}/components/Input.js
So far the only solution I was able to figure out is to change baseUrl
to /
, and load main.js
in html by providing following path:
<script>
SystemJS.import('systemjs-hot-reloader').then((connect) => {
connect()
SystemJS.import('source/scripts/main.js')
})
</script>
This isn't bad, but feels somehow wrong and less elegant, since it is preferable to minimize amount of paths declarations.
Maybe there are better ways?
If it isn't systemjs-hot-reloader issue, than I'm sorry for posting it here.
Apologies that I haven't been present. Have major deadlines for Friday. Will be pushing forwards next week.
Just as a side note, this isn't critical issue.
So far we've workarounded it by adding following script to package.json
:
"js:chokidar": "cd ./source/scripts && chokidar-socket-emitter",
So, we just launching chokidar-socket-emitter
from directory, where sources lives. This effectively forces emitter to emit paths without source/scripts
part.
Not super elegant and slightly hacky, but works.
Looking at this, I wonder is it related to the SystemJS Hot Reloader, or Cockidar Socket Emitter itself...
It seems like Socket Emitter path
options should fix this, but it doesn't.
Aha, actually Socket Emitter has hidden in code option relativeTo
, which allows to "align" paths.
So this does the trick:
chokidarEventEmitter({ path: 'source/scripts', relativeTo: 'source/scripts' }, () => {
console.log('running')
})
It will force Emitter to watch only source/scripts
, and at the same time to remove source/scripts
from emitted paths.
Not obvious, but works.
Hi again, does this fix your issue?
For me — yes.
I didn't close the issue only because I wasn't sure is it a right solution in terms of API clearness.
Yeah, path issues are not really the concern of this lib I think. We (and the browser) work from a top level url. If thats going to be customized a bit its the job of the developer (or the build server - i.e. the event emitter) to make sure that all plays well.
If you're happy to close this I'll leave it in your hands :)
Totally agree.
If you're happy to close this I'll leave it in your hands :)
YEY! :D