-
Notifications
You must be signed in to change notification settings - Fork 263
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
JavaScript refactoring #303
JavaScript refactoring #303
Conversation
…ove reliance on Google Closure and support WebPack integration
Hey @matatirosolutions! I finally got a moment to look at this. Nice work! The changes are still (necessarily) HUGE, which makes them tough to review. However, because you made no changes to the test suite, I think is the most important thing. I did notice a few file permissions changes. Unless those are on purpose, could you revert them? @tobias-93 What are your thoughts on this? I think we should just test it manually a bit, then merge it in. If the automated tests + some manually testing doesn't find an issue, then that's the best we can do. We really need to move forward with how the JS is written in the lib. |
@matatirosolutions Good work! I think we can really use this going forward. For the code: I'm not a JS genius so I'll rely on the tests and do some manual testing myself in order to verify it as @weaverryan suggested. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like what I am seeing.
.travis.yml
Outdated
@@ -22,7 +22,7 @@ before_install: | |||
|
|||
install: | |||
- composer update $COMPOSER_FLAGS --prefer-dist | |||
- npm install google-closure-library | |||
- cd Resources && npm install google-closure-library && cd ../ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure to understand why this is needed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changing of directories? I was trying to keep it such that all node_module dependencies were in the Resources directory rather than some at the root of the project, and others in the Resource directory.
Resources/doc/usage.rst
Outdated
@@ -1,7 +1,7 @@ | |||
Usage | |||
===== | |||
|
|||
Add these two lines in your layout: | |||
In applications not using WebPack add these two lines in your layout: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we write "Webpack" (see: https://en.wikipedia.org/wiki/Webpack).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would seem to be the wikipedia view, yet https://webpack.js.org/ seems to favour all lowercase, so I've gone with that - hope that's ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok for all lowercase then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still not conform to the discussed capitalisation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry @tobias-93 fixed now!
Resources/doc/usage.rst
Outdated
.. code-block:: javascript | ||
|
||
const routes = require('../../web/js/fos_js_routes.json'); | ||
import {Router, Routing} from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.js'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you mixing ES and Node imports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe that I am - in this example I load the routes which have been generated as .json from fos:js-routing:dump, then import the actual Router and Routing objects for use - but perhaps I don't understand your comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant either you use require()
or import ... from
.
Resources/doc/usage.rst
Outdated
import {Router, Routing} from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.js'; | ||
|
||
Router.setData(routes); | ||
Routing.generate('rep_log_list'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why we need two different objects here but I'll keep reading :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BC, however based on a comment by @stof this has now been refactored and removed
Note: I dont think the singleton pattern is correctly implemented here (with a global (module-scoped) instance returned by a method in a class of this module). I would go for a static property on the class instead. |
Resources/doc/usage.rst
Outdated
.. note:: | ||
|
||
If you are not using Twig, then it is no problem. What you need is to add | ||
.. note:: If you are not using Twig, then it is no problem. What you need is to add |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this change looks wrong to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How so? All I did was remove two line-breaks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and this is precisely the issue, as having some content on the same line than the directive or as an indented block following it has a totally different meaning in the rST syntax.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok - I must be being miss-lead by the editor I'm using - the only difference I see is that without the line-breaks the text of the note is closer to the heading of the note (and therefore to my eye looks neater ;-). I've reverted the change in a soon-to-be pushed commit.
@@ -386,7 +387,7 @@ function testGetRoutes() { | |||
blog: 'test' | |||
}); | |||
|
|||
assertObjectEquals(expected, router.getRoutes()); | |||
assertObjectEquals(expected.toObject(), router.getRoutes()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it just the object passed as argument to new goog.structs.Map
then ? If yes, it may be simpler to remove the goog Map wrapper instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My reasoning for doing it this way was to minimise the changes to the tests as far as possible.
Your other comments below have also simplified the install/config process to the point that it adds no additional effort and the test suite itself still relies on the Google library.
Resources/package.json
Outdated
], | ||
"files": [ | ||
"js/router.js", | ||
"public/js/router.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we include both files ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're correct, shouldn't be including the first. Now updated.
* Configures the current Router instance with the provided data. | ||
* @param {Object} data | ||
*/ | ||
static setData(data) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to also add a non-static method to simplify the usage in a CommonJS environment (and then, the static method kept for BC can call the non-static method internally to avoid duplication)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea! now implemented.
Resources/gulpfile.js
Outdated
const wrap = require('gulp-wrap'); | ||
|
||
gulp.task('js', () => { | ||
gulp.src('js/router.js') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should have a return
statement, so that Gulp is notified about the result too (to know when it end, and whether it succeeded)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in a soon-to-be pushed commit.
Resources/gulpfile.js
Outdated
}); | ||
|
||
gulp.task('default', () => { | ||
gulp.start(['js']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing return here too.
And btw, I don't think we need 2 different tasks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Return added in a soon-to-be pushed commit.
Having two tasks isn't strictly necessary and I'm reasonably new to using Gulp so am happy to remove the second if you would prefer? My reading suggests that the 'standard' is to have a 'default' task which essentially acts as a 'controller' calling the other tasks which actually do the doing (so in a future version for example a 'css' task could be added)
CONTRIBUTING.md
Outdated
|
||
```bash | ||
$ cd Resources | ||
$ npm install google-closure-library |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please it as a dev dependency, so that no extra manual installation is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, done in a soon-to-be pushed commit.
CONTRIBUTING.md
Outdated
$ npm install google-closure-library | ||
``` | ||
|
||
Run the JS test suite with: | ||
|
||
```bash | ||
$ phantomjs Resources/js/run_jsunit.js Resources/js/router_test.html | ||
$ phantomjs js/run_jsunit.js js/router_test.html |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest adding this command as the test
script in package.json, so that the standard npm test
command can be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, done in a soon-to-be pushed commit. Documentation also updated.
Ping @matatirosolutions! |
@weaverryan yeah - combination of somewhat overwhelmed by the feedback and not entirely sure how to move forward from this position, and swamped with clients who all suddenly want stuff done 'before the New Year'. Aim to get this sorted next week as I'm also working on an SF4 project which needs this merged! |
Ping me here or on Symfony slack if you want to chat about any points. This is indeed a non/trivial task, but important! |
@matatirosolutions No worries, if you have any questions don't hesitate to ask. I've created a Gitter chatroom at https://gitter.im/FOSJsRoutingBundle/Lobby, in case you want to discuss something (and I encourage everyone here to join :)). |
@weaverryan and @tobias-93 I've reverted the permissions changes on the JS files - these were the files brought in from the work which Bruno Sampaio did and I hadn't noticed that the permissions were different - thanks for spotting this! @tobias-93 the reason that there are now two router.js files and not a symlink is that the version in the /js folder is written in ES6, and then cross-compiled (using gulp/babel) into the version in the /public folder which is ES5 compatible (and therefore backwards compatible with previous versions and older browsers) so we do now need the two separate files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matatirosolutions Thanks, good work! I noticed, however, that the Resources/ts/router.d.ts
file still has changed permissions. Could you change that?
Furthermore: I'd like you to update the docs so it refers to the Resources/Public/js/router.min.js
instead of Resources/Public/js/router.js
as that changes the behaviour of the bundle.
Resources/package.json
Outdated
@@ -0,0 +1,47 @@ | |||
{ | |||
"name": "fos-router", | |||
"version": "1.6.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be updated to reflect the version number in the rest of the bundle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm... that was correct at the time of forking - the world of FOSJsRouting is moving quickly at present :-)
I've updated it to 2.2 - see if I can get the other feedback on this PR addressed before it's too late to be that version!
<script language="javascript" type="text/javascript" src="../../node_modules/google-closure-library/closure/goog/base.js"></script> | ||
<script language="javascript" type="text/javascript" src="router.js"></script> | ||
<script language="javascript" type="text/javascript" src="../node_modules/google-closure-library/closure/goog/base.js"></script> | ||
<script language="javascript" type="text/javascript" src="../public/js/router.js"></script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the tests use the ES6 version? That way, you're always testing the non-compiled version, so compilation is not needed before you can run the tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attempting to do that was where Bruno's original PR came unstuck (see #257) because in order to do that requires rewriting the test suite as well as the code. Understandably people didn't think that was a good idea, and that PR has been stalled for over a year.
After a discussions with @weaverryan and @stof at SymfonyCon, what I'm attempting to do here is to merge in the updated JS (to support webpack usage in SF4) without changing the test suite so that we can have a (high) degree of confidence that the new JS remains BC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All right, then I will accept this. However, the test script should invoke the compile step before running the test, to prevent one from testing without compiling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docs should also be updated to reflect this (building before testing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure thing. Running npm run test
will now perform a build first. Docs updated to explain that this will happen.
Resources/doc/usage.rst
Outdated
@@ -1,7 +1,7 @@ | |||
Usage | |||
===== | |||
|
|||
Add these two lines in your layout: | |||
In applications not using WebPack add these two lines in your layout: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still not conform to the discussed capitalisation
Thanks @willdurand, @weaverryan, @stof and @tobias-93 for your reviews. I believe that I've now addressed all of the concerns and implemented all the changes requested. Please let me know if there's anything further required to merge this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last thing: I think we should adapt the Travis configuration to conform to the docs. Could you change the commands to npm install
and npm test
?
CONTRIBUTING.md
Outdated
``` | ||
|
||
Because the current test suite runs agains the built javascript a build is automatically |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: agains instead of against
I see that the PHP 5.3 test fails due to Node being too old. You could add a line to the travis config to skip the build on the old environment, as the tests themselves run fine. |
…prevent unexpected dependencies in projects
In implementing this in an SF 4 project over the last two days I found that the use of the .babelrc file was resulting in the implementing project having to include the dependencies specified there in. To prevent that I've removed the .babelrc file and explicitly set the babel parameters in the gulp file. |
@stof what needs to happen to move this forward - as far as I am aware I've addressed all of your concerns - are you able to take a look and confirm please? |
What do I need to do to get this PR merged? As far as I'm aware I've addressed all concerns raised and it would be great if we could move forward with this! |
Yea... I have the same question. @tobias-93: you approved this. Can you merge it? |
@weaverryan Yes, I approved this. I wanted to give @stof time to review this, because he had comments. However, I think he had his chance to do so. I'm now merging this. |
Makes sense. And woohoo!!!! :) |
@steveWinter I want to update the docs of using this bundle with Encore. What’s your setup look like? Are you always dumping the routes in dev and loading the JSON? Or something else? |
@weaverryan I'm essentially doing things as per the update I made to the bundle docs. And yes, I'm dumping the routes to json (though into /assets/js rather than the path in the docs) then in my 'layout.js' (as it was referred to in your SFCon workshop) I'm doing as per the link above. On my build server I'm running the dump command before encore to ensure the built files have the latest set of routes. |
Thanks @steveWinter :). I'm wondering if the bundle could/should (with some config) dump that JSON file automatically whenever the routing cache is rebuilt... that would avoid needing to re-dump it when you add new stuff. Not sure how possible that is... |
@weaverryan I like the idea - if there are events dispatched as part of the route-cache building process, then it would be pretty simple but I know very little about the internals of Symfony routing, so have no idea how possible that might be. I'd be happy to look at implementing this, if you can point me at the right person to talk to about the routing cache process. |
I don't think we can hook into the routing dumping easily. |
Bah, I was afraid of that :). Maybe something to think about in core |
@weaverryan, @steveWinter : Actually, here is what I'm actually using with Webpack Encore to not have dumping routes each time on
|
In PR #257 @bensampaio refactored the JavaScript to remove the reliance on the Google Closure library and to support using this bundle with WebPack (as identified in #264).
That pull request has stalled because the JavaScript tests were also moved from the deprecated jsUnit to the more modern Jasmine as part of the same PR.
I discussed this with @stof during #SymfonyCon2017Hackday because I wanted to see this move forward to allow for easier integration with WebPack.
This PR attempts to do that by bringing the excellent work Bruno did in refactoring the JS in without refactoring the tests as part of the same process. Essentially I have brought together the work Bruno did on updated JS and an updated JS build process, with the old tests.
It was necessary to make three minor changes to the test suite which I wish to explain to set minds at ease:
goog.require('goog.structs.Map');
in the test suite because it is used by one of the tests which was relying on this having been required by the originalrouter.js
testGetRoutes()
had to be modified to useexpected.toObject()
because it was previously running against the uncompiled code which returned agoog.structs.Map
where-as we are now returning a standard object instead.router_test.html
was modified to load the compiled library, rather than the 'source' library. This was needed because the test suite expects (amongst other things) for there to be a global fos object. The updated JS code is also written in ES6 which is then transpiled as part of the build process to support backwards compatibility.The documentation around contributing has also been updated to reflect the new build process.