Conversation
prichodko
left a comment
There was a problem hiding this comment.
Thanks Lu 💪
I've found couple of little things, so just look for the comments. However there are two things outside of the codebase:
- Rename
publicfolder tostatic(and correctly implement handler of*requests), otherwise serving of static files won't work. - Maybe it's out of the scope of your lecture, but it would be pretty cool to show, that you can access cookies on the server and return page already with necessary data for authentication (e.g. no blink).
|
|
||
| class CustomDocument extends Document { | ||
| render() { | ||
| const sheet = new ServerStyleSheet() |
There was a problem hiding this comment.
Although I can't really say, if there is difference or not, but according to official example and styled-components website code for example, styles extraction is defined in getInitialProps method.
There was a problem hiding this comment.
No idea if it makes a difference either but I could change it just in case
| //server.use(compression()) | ||
|
|
||
| server.get('/products/:id/:name', (req, res) => { | ||
| app.render(req, res, '/product', req.params) |
There was a problem hiding this comment.
Please add a return statement here, to indicate the end of the request.
| server.get('*', (req, res) => { | ||
| const parsedUrl = parse(req.url, true) | ||
| const { query, pathname } = parsedUrl | ||
| app.render(req, res, pathname, query) |
There was a problem hiding this comment.
For the handler of all incoming requests you can simply do
// at the top
const app = next({ dev })
const handle = app.getRequestHandler()
// and then
server.get('*', (req, res) => {
return handle(req, res)
})There was a problem hiding this comment.
This is also necessary for the correct handling of static file serving.
There was a problem hiding this comment.
Seems I removed that, I'll add it back
| </Layout> | ||
| ) | ||
| } | ||
| const ProductView = props => { |
There was a problem hiding this comment.
Let's move destructuring straight into arrow function declaration. 😊
|
Another quite a big issue I see right now, is that you are not taking into consideration that @koss-lebedev during his lecture will move codebase to TypeScript. |
dannytce
left a comment
There was a problem hiding this comment.
Overall great job! :) But I agree with Pavel. It would be cool to make it work somehow with Kosta's PR too :)
| @@ -0,0 +1,35 @@ | |||
| // @flow | |||
| @@ -0,0 +1,37 @@ | |||
| /* eslint-env node */ | |||
There was a problem hiding this comment.
We don't need this either. It's already set in .eslintrc
| /* eslint-env node */ | ||
| const express = require('express') | ||
| const next = require('next') | ||
| //const compression = require('compression') |
There was a problem hiding this comment.
Let's get rid off commented code :)
There was a problem hiding this comment.
I was planning on uncommenting it on live demo, but I could type it directly.
| if (err) { | ||
| throw err | ||
| } | ||
| console.log('> Ready on http://localhost:' + PORT) // eslint-disable-line |
There was a problem hiding this comment.
Maybe let's be more strict -> eslint-disable-line no-console? :)
| @@ -1,15 +1,41 @@ | |||
| import fetch from 'isomorphic-fetch' | |||
| // import config from '../config' | |||
There was a problem hiding this comment.
Why it's commented there? :)
| const ProductView = props => { | ||
| const { product } = props | ||
| return ( | ||
| <> |
| <Link to={node.id}> | ||
| <Link | ||
| href={`/product?id=${node.id}`} | ||
| as={`${PRODUCT_LIST}/${node.id}/${kebabCase(node.name)}`} |
There was a problem hiding this comment.
Can we move this into routes.js to preserve previous logic?
There was a problem hiding this comment.
I would have to rework that, as href is different than as, I didn't want to overcomplicate that logic, it might be easier to follow like this in my opinion.
|
|
||
| ProductList.getInitialProps = async props => { | ||
| const products = await getProducts() | ||
| props.store.dispatch(loadProducts(products)) |
There was a problem hiding this comment.
Since you are dispatching loadProduct, you don't need to have them in mapDispatchToProps, don't you?
There was a problem hiding this comment.
I don't, good catch :)
| import cart from './cart/reducer' | ||
| import customer from './customer/reducer' | ||
|
|
||
| const isBrowser = typeof window !== 'undefined' |
There was a problem hiding this comment.
There is is-browser helper, let's use it here :)
| @@ -0,0 +1,11 @@ | |||
| export const getRefreshToken = () => { | |||
| return window.localStorage.getItem('refreshtoken') | |||
There was a problem hiding this comment.
Shouldn't this be extended with isBrowser() && too?
|
@prichodko @dannytce Thanks for the feedback and @prichodko good catch with the static folder I completely forgot to change it, I would mention the sign-in via server but only for the account page as it would hinder caching if done on all routes. Regarding kostas PR, we previously agreed on having this SSR as a separate branch as it would be overwhelming for the students if combined with typescript, but maybe something could be done |
|
Feedback implemented in #18 |
Replaced create-react-app for next.js