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

Server side conversions #716

Merged
merged 24 commits into from
Apr 5, 2018
Merged

Server side conversions #716

merged 24 commits into from
Apr 5, 2018

Conversation

lexoyo
Copy link
Member

@lexoyo lexoyo commented Mar 30, 2018

When Silex saves / opens / publishes a website, it parses the website's DOM to find URLs and make them absolute (when opening) or relative (when saving) or relative to the published version

This PR takes all these operations on the server side, taking advantage of nodejs parsing libraries, and making it possible to parse the DOM without loading any external images or scripts or styles or iframes, and in a cross browser consistent way

This is way cleaner (no more regexp to find the URLs for example), more efficient on the client side, less efficient on the server side, and it fixes long time bugs like #624

Backward compatibility is dropped for this release because I did not manage to port it from client side to server side, but this version is 100% compatible with the one currently on master. So now when you try to open an older website, Silex sends you to https://old.silex.me/ which has the version currently on master. There you can open your website and save it with the version which still has BC on the client side. Then come back to editor.silex.me and you will be able to open it. A BC system is already ready on this PR but it is waiting for the next version to be used.

@lexoyo lexoyo temporarily deployed to silex-editor March 30, 2018 18:31 Inactive
* used for backward compat
* also the static files are taken from //{{host}}/static/Y-Z
*/
const LATEST_VERSION = require(Path.resolve(__dirname, '../../package.json')).version.split('.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, if you start the server with NPM, it sets an env variable for you : process.env.npm_package_version

// then download all assets
// FIXME: should use unifile's batch method to avoid conflicts or the "too many clients" error in FTP
//return Promise.all([
return sequential([
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As previously discussed you should do that. But maybe you want to clean that in another PR

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes as you told me it is better to test if a file exist and by writing and checking the error

But I would rather do that in an other PR because this current solution is the result of many problems with unifile batch and I am not comfortable changing it now

Copy link
Contributor

@JbIPS JbIPS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mainly you need to address the package.json problem

assets
.filter(file => !!file)
.map(file => {
if(file.path === 'css/') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops old code sorry

// publication tasks
router.post('/tasks/:task', bodyParser.json(), (req, res, next) => {
// init the session (shouldn't it be done by express??
req.session.sessionID = req.session.sessionID || uuid.v4();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it should. Did you encounter a case where the session was not set?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I did
I'll remove it and see what happens since we updated express

const express = require('express');
const fs = require('fs');
const { JSDOM } = require('jsdom');
const bodyParser = require('body-parser');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As seen in CE2, you don't need body-parser since express 4.16.0

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concerning JSON: CE adds routes that collide with Silex new routes, e.g. /website/github/get/master/ will be caught by CE as a service called "website/github". So I need to put Silex router before CE router, and so the body needs to be explicit

Concerning text: here I need the body parsed as text, and I can't figure out how to access the body parser from express to use bodyParser.text(

Also in the docs, this is still written to require('body-parser') so I lost too much time with this for now
https://expressjs.com/en/4x/api.html#req.body

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finally I removed it from CE2 since it doesn't need a parser (right?)
and I added it here #718

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the documentation is outdated on this point but the changelog clearly mentioned the new way to parse bodies https://expressjs.com/en/changelog/4x.html

const cloudExplorerRouter = new CloudExplorerRouter(rootUrl);
app.use(new WebsiteRouter(port, rootUrl, cloudExplorerRouter.unifile));
app.use(new PublishRouter(port, rootUrl, cloudExplorerRouter.unifile));
app.use(new SslRouter(app));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's arguable, but IMO this file should act as a controller and perform the environment checks (like SSL and such) before using the router.
In that case, the router wouldn't have to worry about the env and the configuration variables should be injected in its constructor.

This will greatly simplify testing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍
I'll try to refactor
If you could write this in a separate issue that would be great - not a problem otherwise, I'll try

package.json Outdated
@@ -38,34 +40,33 @@
"start:electron": "SILEX_ELECTRON=true electron ."
},
"dependencies": {
"body-parser": "1.13.3",
"bluebird": "*",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's what you want. Even with a package-lock this file should be human readable (the lock clearly isn't).

Basically, we talked about express version and it's now very difficult to know which one is used here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i agree but one of the dependencies has a dependency that breaks the production server but works on localhost. I have no idea which and it is really hard to test since I need to deploy every time (and break the server on preprod.silex.me)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I decided to give it one more chance, I fixed all versions to the latest available and it seems to work on preprod.silex.me

👍

// });
const oReq = new XMLHttpRequest();
oReq.onload = function(event) {
if(oReq.status === 200) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happened to your indentation? (╯°□°)╯︵ ┻━┻

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@lexoyo
Copy link
Member Author

lexoyo commented Mar 30, 2018

Thanks, great review, I'll fix all this

@lexoyo lexoyo temporarily deployed to silex-editor March 31, 2018 13:22 Inactive
@lexoyo lexoyo temporarily deployed to silex-editor April 1, 2018 14:44 Inactive
@lexoyo
Copy link
Member Author

lexoyo commented Apr 3, 2018

Do you think that everything is fine now?

  • package.json with fixed versions
  • removed body-parser
  • fixed the other things

Only the refactoring and the test of existing files remain

@JbIPS
Copy link
Contributor

JbIPS commented Apr 4, 2018

Yep, it's good to go!

@lexoyo
Copy link
Member Author

lexoyo commented Apr 5, 2018

Let's do it!

@lexoyo lexoyo merged commit 9cfc2a6 into master Apr 5, 2018
@lexoyo lexoyo removed the in progress label Apr 5, 2018
@lexoyo
Copy link
Member Author

lexoyo commented Apr 5, 2018

Deployment in progress
Silex is down

@lexoyo
Copy link
Member Author

lexoyo commented Apr 5, 2018

Silex is back up
This is now live, I'll have a look at the server performance statistics soon

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

Successfully merging this pull request may close these issues.

2 participants