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

Rewrite as a Svelte/Express app #56

Merged
merged 34 commits into from
Mar 19, 2017
Merged

Rewrite as a Svelte/Express app #56

merged 34 commits into from
Mar 19, 2017

Conversation

Rich-Harris
Copy link
Member

@Rich-Harris Rich-Harris commented Mar 14, 2017

https://sveltetechnology-ukcvrplota.now.sh

Svelte is mature enough that it makes sense to use it rewrite https://svelte.technology. Apart from testing out the development workflow, this has some tangible benefits:

  • the code is a lot more organised (much easier to include components in multiple pages, for example)
  • the site feels faster, because of client-side routing

Still very work-in-progress, lots of outstanding tasks:

  • Reimplement the REPL
  • Highlight current guide section on scroll
  • Preload data for other routes, for instant navigation
  • Loading indicators for the extreme cases when that's necessary
  • Syntax highlighting in guide (we can probably do this at build time, rather than loading CodeMirror on the client just for that)
  • 'Open in REPL' links in the guide
  • Service worker
  • Whatever webpagetest.org recommends
  • Update URL in REPL when using a built-in example (including version)
  • Load built-in examples asynchronously
  • Add fallback fonts everywhere
  • Curl sometimes doesn't load. WTF?
  • Remove unused code from previous site (src, gobblefile etc)

plus whatever I forgot.

A few notes on developer experience:

  • The way CSS is generated (creating a component that imports all other components, bundling it with generate: 'ssr' then calling app.renderCss()) is a bit clunky. It means you have to maintain that App.html file as you add new routes, and you have to send all the CSS for the entire app (though maybe that's not a bad thing — dynamically adding CSS is often a CSP violation, and the CSS is tiny).
  • Because the CSS isn't generated dynamically, editing a component means that the unique hash gets out of date, and server-rendered CSS isn't applied to client-rendered components. Would be nice if there was a good way to generate the CSS dynamically while developing (but still serve the baked version in production) — otherwise you have to keep stopping and starting the npm run dev task
  • HMR would be nice!
  • Client-side routing could be a bit more declarative — though the trick is to do that without losing the ability to do things like this, which is hard to do if you go ultra-declarative with your routing setup. (Maybe that particular bit of logic belongs in the component itself, I don't know.)
  • There's probably some stuff that's unnecessarily duplicated between server-side and client-side routing. For now I like having them separate, but it could eventually seem like a chore, or (worse) bug-prone.

As we gather more of this sort of data on building these kinds of apps, maybe it'll become clearer what can be packaged up somehow in a way that improves the developer experience, in the way that Next.js improved the experience of building universal React apps.

@Rich-Harris
Copy link
Member Author

I've deployed this even though there are tasks outstanding, as it's an improvement on the previous site, and it will hopefully mean feedback/bug reports.

@Conduitry
Copy link
Member

I was actually just taking a look at this locally. One thing I saw (besides the missing roadtrip dependency, which I see you fixed) was a weird routing bug on Firefox. Start from a particular anchor on the guide page, then click to the REPL or blog, then press back - the last back doesn't work, I'm staying on whatever the non-guide page was. This works fine on Chrome and works fine if you don't start from an anchor on the guide page.

@Rich-Harris
Copy link
Member Author

Huh, that is weird. What version of FF are you using? It seems to be okay for me on FF52 on OS X. Do you see any errors in the console when that happens?

blocked = true;

fn();
setTimeout( unblock, ms );

Choose a reason for hiding this comment

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

I wonder whether this could lead to a memory leak if the timeouts aren't cleared.

Copy link
Member Author

Choose a reason for hiding this comment

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

shouldn't do, why would it? The timeout is never meant to be cleared before it executes, and you obviously don't need to clear a timeout after it's been executed

padding: 2em 1em;
/*background-color: #333;
color: #f4f4f4;*/
background-color: white;

Choose a reason for hiding this comment

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

Usually you use hex values for colours.

Copy link
Member Author

Choose a reason for hiding this comment

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


.learn-svelte {
background-color: rgb(170,30,30);
color: white;

Choose a reason for hiding this comment

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

Usually you use hex values for colours.

@media (min-width: 480px) {
.left, .right {
max-width: 32em;
margin: 0 auto;

Choose a reason for hiding this comment

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

You need to make it a block element (or take care to not add those classes to inline elements as that won't have an effect).

bottom: 0;
padding: 0.5em;
background-color: rgb(255,220,220);
border-top: 1px solid rgb(200,0,0);

Choose a reason for hiding this comment

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

You usually use hex values for colours.

// the component is actually in the DOM
setTimeout( () => {
this.editor.refresh();
});

Choose a reason for hiding this comment

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

What happens with setTimeout if you omit the second argument?

Copy link
Member Author

Choose a reason for hiding this comment

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

It defaults to 0

toTeardown = component;
component = null;

setTimeout( () => { // necessary because `data` is not yet updated. TODO would be nice to fix this

Choose a reason for hiding this comment

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

Missing second argument?

<div class='controls'>
<button class='{{showGenerated ? "" : "active"}}' on:click='set({ showGenerated: false })'>input</button>
<button class='{{showGenerated ? "active" : ""}}' on:click='set({ showGenerated: true })'>output</button>
<button class='{{saving ? "active" : ""}}' on:click='save()'>{{saving ? 'saving' : 'save'}}</button>

Choose a reason for hiding this comment

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

Semantically those <button>s are of type „submit”.

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 associate submit with forms, rather than event triggers. You could maybe argue the 'save' button is, but the others aren't, they're effectively tabs. With submit you have to prevent the event default — is there any real advantage to submit? If it's an a11y thing, maybe there's an aria attribute that would be more appropriate?

margin: 0 0.5em 0 0;
border-radius: 0.2em;
color: rgb(170,30,30);
border: 1px solid rgb(170,30,30);

Choose a reason for hiding this comment

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

Usually you use hex values for colours.


.controls button.active {
background-color: rgb(170,30,30);
color: white;

Choose a reason for hiding this comment

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

Usually you use hex values for colours.

@Conduitry
Copy link
Member

I'm on Firefox 52 on Windows. I am getting a TypeError: t.state is null error when I go back from the non-guide page to the guide with the fragment. I'm also seeing that same error when I click on anchor links from within the guide page, but I guess that doesn't actually cause problems at that moment because the browser just follows it like a regular anchor hyperlink.

@Rich-Harris
Copy link
Member Author

Huh, thought I'd fixed that in Rich-Harris/roadtrip@27778fa. Is this happening on the deployed site, or locally? Could it be that your dependencies are out of date?

@Conduitry
Copy link
Member

This is on the live deployed site. But taking a look at the minified code in https://svelte.technology/bundle.js I don't see that change.

@Rich-Harris
Copy link
Member Author

Curiouser and curiouser. I've redeployed, and it looks like bundle.js does now have that check, so hopefully that's the end of it...

@Conduitry
Copy link
Member

All right, I'm no longer getting that console error - but the navigation still isn't working. When I go back from /repl to /guide#some-anchor I'm assuming the new check is now returning early from the popstate handler, but there is still something that has to happen on that popstate. (Should this conversation move over to roadtrip? 😃)

@Rich-Harris
Copy link
Member Author

Ok, now I'm more freaked out that it is working for me! Now that you mention it does seem like something is missing from that code. Perils of trying to fix bugs at the end of the day.

Should this conversation move over to roadtrip?

Probably! And if you know of any alternative routers that use regular <a> tags instead of framework-specific stuff, and handle scroll history etc, then I'm all ears — I don't really want to be in the router business, I just couldn't find anything that either a) did nothing and had no opinions or b) did everything and had all the opinions

Rich-Harris/roadtrip#9

@Conduitry
Copy link
Member

The div.error with the error messages in the CodeMirror component in the REPL are not displaying correctly. They're present in the DOM when they should be, but not visible on the page.

@Conduitry
Copy link
Member

Everything under the src directory can be removed with this rewrite, correct?

@Rich-Harris
Copy link
Member Author

Everything under the src directory can be removed with this rewrite, correct?

Yep, am just keeping it around so it's easier to copy and paste stuff if I need to... have updated the task list at the top of the page so we don't forget

@Conduitry
Copy link
Member

Conduitry commented Mar 16, 2017

So lol oops - just the other day I opened a PR against https://github.com/flagello/awesome-sveltejs to have the link to the REPL there be to https://svelte.technology/repl/?version=1&gist=c80ee9ec68fefa93617dfc40400851f5 instead of a particular version because that would grab the latest 1.x.x version and would redirect/rewrite the version param in the url - but that feature no longer seems to be working! Was that an intended feature before? Actually, the REPL isn't working at all right now? Nothing suspicious in the console, but svelte.js isn't being loaded from unpkg.

Edit for real this time - https://svelte.technology/repl works fine but https://svelte.technology/repl/ does not.

@Rich-Harris
Copy link
Member Author

Ah, right — that makes sense. We probably just need to add an entry here

@Conduitry
Copy link
Member

Some LESS snuck into the CSS here.

@Rich-Harris
Copy link
Member Author

Merging this, will open separate issues for the remaining tasks

@Rich-Harris Rich-Harris merged commit e171295 into master Mar 19, 2017
@Rich-Harris Rich-Harris deleted the svelte-app branch March 19, 2017 19:14
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.

3 participants