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

Switch to Next.js #178

Merged
merged 37 commits into from
Jun 28, 2021
Merged

Switch to Next.js #178

merged 37 commits into from
Jun 28, 2021

Conversation

mattxwang
Copy link
Contributor

@mattxwang mattxwang commented Jun 18, 2021

This PR does the meat of our transition to Next.js. As a heads up, the files changed/diff is absolutely nasty; I imagine that there will be little bits and pieces that we'll have to address down the line.

Summary

We transition the site to be Next SSG'd.

CRA-to-Next transition

  • swaps out toolchain to use Next
    • installs next, and relevant eslint plugins
    • removes react-scripts, react-router-dom, react-router-hash-link, and @testing-library equivalents
    • changes npm scripts to use next defaults
    • swaps out node-sass for sass (the reference dart implementation)
  • uses Next's file-based routing
    • currently segments into six pages: about, committee, events, index (previously Home), sponsors, and techgala; no paths are broken
    • moves the rest of components (including GM) into components
  • restructures SASS and CSS
    • moves all styles into styles folder, mirroring pages and components structure
    • collates a few styles
    • imports Font Awesome into the next bundle, instead of loading into the index.html entrypoint
  • uses next/image when possible
    • in some cases, we import the image out of the public folder; this automatically sets width and height
    • in some other cases, manually sets width and height (typically for UI elements) or uses layout="fill" and retools CSS to properly deal with it
    • in some cases, maintains <img />. we were unable to fully transition over to <Image /> (see below conversation)
  • for ease-of-transition, removes all tests (jest, enzyme, related things)

Things that will need to be addressed later

  • this PR explicitly doesn't address .module SASS, but we should do that in a follow-up
  • there should be something we can do about fonts that doesn't involve loading it in the <Head> - let's look into that! possibly see @BryanPan342's comment below
  • SEO, using <Head> properly, etc; since this isn't a regression, let's table adding this to each page in a separate PR
  • more ergonomic image inputs - maybe through an index.js that collates together images, thanks @dtjanaka for the suggestion!
  • remove postcss@8 as a dev dependency, but still resolve this error: missing postcss dependency on build vercel/next.js#24882
  • refactor the GM component to derive all of its information from state; then, make a new wrapper page that passes in the relevant information from data files, manual configuration, etc.
  • document the new CI/CD pipeline, document Next quirks (ex next/image)
  • resolve issues with next/image

Misc. code quality changes

  • removes the <Button> component entirely, and changes the button selector to instead use the .button class.
    • this is because the component itself didn't do anything (it just passed on props to a <button>) and also arbitrarily restricted the semantic element
  • changes CSS for the officers section of the about page to use flexbox instead of nested selectors + absolute/inline-based positioning
  • changes the officers section text to say "Leadership" <- this is easily changeable
  • fixes bug where .page-content p bleeds into the Committees page events arbitrarily
  • fixes incorrect use of ul and li in <Navbar>
  • slashes a non-trivial amount of completely unused CSS
  • de-dupes CommitteeSectionIntro's double-images for committee motifs

Issues that still need to be addressed:

  • switching over to next/image to resolve build failures
  • properly using next/image to resolve layout issues - see TODO comments
  • font awesome icons are not sized properly
  • strip out the Button component, as it's not useful and causes issues with Link
  • fix the Navbar button (general_
  • fix the Navbar membership portal button on mobile
  • this error: missing postcss dependency on build vercel/next.js#24882 - stopgap is to have postcss@8 as a devdep; moved to "deal with later"
  • resolve netlify build error (very simple, just change output folder)
  • deal with the GM component -> this should probably be a component, and then have a dummy page wrap it for every new GM. deals with longevity very well - moved to "deal with later"
  • fix about page first image diamond (now not centered properly)
  • fix image borders not appearing properly on next/image components
  • fix committee page nav images not being properly sized
  • the favicon is bugged

This PR also does some favours for us: it closes #162, (reasonably) closes #131 (for now). It also unblocks #110 and #116!

@mattxwang mattxwang marked this pull request as draft June 18, 2021 19:42
@BryanPan342
Copy link

@mattxwang lmk if u need help with the next.js migration!

Even tho next is awesome, sometimes the bugs are opaque AF and takes a bit of digging to fix!

@mattxwang
Copy link
Contributor Author

@mattxwang lmk if u need help with the next.js migration!

Even tho next is awesome, sometimes the bugs are opaque AF and takes a bit of digging to fix!

Thanks, appreciate it! I might pick your brain once I resolve all the low hanging fruit. Gotta say, the image conversion has been the largest pain point thus far, though it's also a huge code smell with our website in general!

@BryanPan342
Copy link

For fonts, usually we import them into our variables or global scss file!

https://github.com/UCLA-Creative-Labs/sunshine/blob/master/styles/_variables.module.scss

Copy link

@BryanPan342 BryanPan342 left a comment

Choose a reason for hiding this comment

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

Why are u using document? What part of the html/body tag do you really need to target?

pages/_document.js Outdated Show resolved Hide resolved
Copy link
Contributor

@advaithg advaithg left a comment

Choose a reason for hiding this comment

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

I fixed the issues with the weird sizing of Next Images by making the attributes of the Image element layout: "fill" with objectFit:"contain" and wrapping them in a div which had the size we needed along with position:relative

This made sense cause the images on the website mostly had a fixed height but varying width, and Next didn't let me do that - so I had to do that in an outer div. I couldn't find a way to tell Next to "use default width"

Alignment was done using the objectPosition attribute

@BryanPan342
Copy link

Never got back to this; I'm curious, does this delay the font load time? Since then we'll have to hit the CSS file first (fetch + parse), and then load the font itself (fetch + parse)?

it does a little bit (I only really notice it when I'm really laggy), but I mean, it will load with the rest of your styling so I don't see a problem with it TBH

@BryanPan342
Copy link

BryanPan342 commented Jun 21, 2021

@BryanPan342, I'm curious do y'all host CL stuff on Vercel or Netlify? Running into some issues with using next/image on Netlify (you can peep the deploy preview or check out the discussion vercel/next.js#18356 or vercel/next.js#19065 for some context). No worries at all on timing though, you're doing a huge help for us already!

we host everything on netlify! I haven't run into many problems with next/image BUT to be honest, I prefer using just the regular image tag! I find next/image abstracts a little too much for me personally.


have you tried removing the next.config file? I found that that file usually gives me the most trouble


this netlify post seems to confirm a lot of your suspicions.. yeah honestly would recommend just using <image /> and also I'm not sure if you need the next.config file.. i honestly don't know what craCompact is but I deleted your next.config file and it still deploys

@mattxwang
Copy link
Contributor Author

we host everything on netlify! I haven't run into many problems with next/image BUT to be honest, I prefer using just the regular image tag! I find next/image abstracts a little too much for me personally.

Hm okay thanks for the thought - I think we'll switch back to <img> for now (since it moves gracefully), and try our hand at <Image /> some other time (I also saw that there's some movement with the Essential Next.js plugin).

For some SVG's, converted to PNG
For others, reverted back to img instead of using /next/image

reverts acm logo on navbar to img

reverts committee spread to img
also comments out next image import

runs linter

reverts sidebar in committees page to img

reverts committee logos on committee page to img

fixed bbq picture on about page

converts svgs in sponsors page to pngs

revert bbq picture to img

fixes linter error
(combination of 3 commits - messages below)

added borders to committee page images
also added margin before intro section for gap after committee logo
issue currently - 'padding' between image and it's surrounding div causing the border to be slightly off

fixed border issue for committees images
also added comment explaining rationale behind gnarly css

ran linter
@mattxwang mattxwang marked this pull request as ready for review June 25, 2021 05:42
@advaithg advaithg requested a review from a team June 26, 2021 00:46
Copy link
Contributor

@dtjanaka dtjanaka left a comment

Choose a reason for hiding this comment

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

nice

@@ -0,0 +1,177 @@
// import React from 'react';
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this file completely commented out?

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 GM needs to be refactored into an actual component in a dummy page, will probably be another issue!
@mattxwang should have more info

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, just to follow up - since the page isn't live, didn't want to introduce more complexity into the change. Eventually, we should adjust this too.

A quick thought - I think the page for a GM (ex gm-w21) should wrap the existing GM component, and simply pass in props to the component. That way, the GM component itself doesn't need to rely on external data sources, which may be a better separation of concerns.

Copy link
Member

Choose a reason for hiding this comment

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

All the above comments make sense.

Since we're now relying on file system routing, it's harder to have dummy pages that are not live. Matt's suggestion makes a lot of sense, having the actual pages acting just as wrapper for components (to which you can pass all the relevant data as props).

import React from 'react';

function ProjectCard(props) {
const {image, title, winner, summary, names, url, category} = props.project;
return (
<div className="intro-row">
<div className="show-mobile">
<img src={image} alt={`showcase image for ${title}`}/>
<Image src={image} alt={`showcase image for ${title}`} height={280} width={370} />
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe a dumb question, but it seems like height and width are now required props for images; what are the implications for responsiveness?

Copy link
Contributor

Choose a reason for hiding this comment

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

The images automatically readjust themselves based on the size of the page, iirc. The height and width props are for the general case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I think moving forward @advaithg is going to be the SME for next/image - you may want to discuss how the component works (ex specified with/height versus layout="fill", what's happening under the hood) with the team some time.

@@ -0,0 +1,69 @@
import blizzard from '../public/images/sponsors/blizzard.png';
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe consider making an index.js file for the images so u can just do import {blizzard, citadel, deloitee, etc.} from '../public/images/sponsors/';

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great idea, let's add it to the backlog 😄

Copy link
Member

@evanzhong evanzhong left a comment

Choose a reason for hiding this comment

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

Amazing work @advaithg and @mattxwang!

I mainly looked at the diffs in this review. Most of the relevant items are left in comments in specific files. General things I noticed

  • +1 to the comment in the PR writeup, there's a lot of low hanging fruit with using .modules; a discussion we should have later after this PR ships.
  • There's some extraneous commented out JSX left in files under TODOs comments. My personal preference is not to have commented out code in production. If we can always refer back to it in the commit history if needed down the line. I left some comments about this, but didn't comment on every instance I saw.
  • We use both regular html <img> tags and next/image. This could get confusing in future development as devs might not know which is appropriate. I know next/image was a particular pain point so we can talk about addressing this in a future issue.

Only thing blocking for me is removal of commented out code, other than that it looks good to go!

README.md Show resolved Hide resolved
<div
style={{backgroundImage: 'url('+ process.env.PUBLIC_URL + item + ')'}}>
</div>
<Image src={item} width={IMAGE_WIDTH} height={IMAGE_WIDTH}/>
Copy link
Member

Choose a reason for hiding this comment

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

I remember there being some discussion about using regular <img> tags instead of next/image.

This also seems to be a background image that we're replacing, would appreciate some more context behind this change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, so my reasoning here is that the background image approach itself is a hack - each div really semantically should be an image, and without this change (in general) the Carousel would be inaccessible.

I did merge that above change with also transitioning it to <Image />, which may have jumped the gun. Didn't see any issues with this on prod, but always down to switch back!

Copy link
Member

Choose a reason for hiding this comment

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

Makes sense, re: accessibility.

If no problems seen on prod with next/image I think it's actually a great change. The carousel is a prime place for lazy loading since it's located below the fold and is image dense

components/CommitteeSpread.js Outdated Show resolved Hide resolved
import React from 'react';

function CommitteeEventCard(props) {
const hasImage = props.image.src;
return (
<div className="info-card-container">
<div className="image-wrapper">
Copy link
Member

Choose a reason for hiding this comment

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

Assuming that this div.image-wrapper is necessary to control the width and height of the next/image used below

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe so, I think this is from Advaith's side!

components/Committees/CommitteeSection.js Outdated Show resolved Hide resolved
Comment on lines +1 to +8
// import Image from 'next/image';
import Link from 'next/link';
import React from 'react';
// import gmData from '../../config/gmData';

//to allow GM page to be visible on the navbar and accessible
//uncomment the above import line "import gmData from '../../config/gmData';" to get quarter from the gmData page
//uncomment the two lines saying "/* <Link href="/gm"><li>{gmData.date.quarter} gm</li></Link> */"
Copy link
Member

Choose a reason for hiding this comment

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

As this is written right now, this is kind of a hack, but it's just a result of how we designed the Navbar component

I'm curious what y'alls thoughts are on making this more friendly to page inactivation. We could easily store the ul information in a json object and have the Navbar be constructed from it. I think this would also benefit us by making the code DRYer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'm not the largest fan of this either, especially since this requires people to update comments (uncommon) when implementation details change, like they did here.

The JSON implementation is a good idea; our friends at Creative Labs do something similar, see https://github.com/UCLA-Creative-Labs/sunshine/blob/master/components/Navbar.tsx#L9

pages/events.js Show resolved Hide resolved
pages/index.js Outdated Show resolved Hide resolved
styles/components/CommitteeSpread.scss Outdated Show resolved Hide resolved
Comment on lines +56 to +66
// this is kind of gnarly, but the !important override is needed to overwrite the CSS built into /next/image
// the div is to change display from inline-block to block so there's no weird spacing between border and image
// the img is to overwrite the default image shadow from committees.scss to prevent double borders
// img should be removable once fully converting to /next/image - the one in committees.scss needs to stay for the non next imgs for now
div {
display: block !important;
}

img {
box-shadow: none !important;
}
Copy link
Member

Choose a reason for hiding this comment

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

Interesting stuff, perhaps this is what Bryan mentioned about next/image being too abstracted for his liking.

In the future, if this persists we may want to consider creating our own wrapper component for next/image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup yup, honestly strange that they force so many style tag changes (causes some specificity shenanigans). Open to any suggestions on how to approach this.

@mattxwang
Copy link
Contributor Author

Addressed most of Evan's comments, and updated the PR description with the relevant to-dos!

Copy link
Member

@evanzhong evanzhong left a comment

Choose a reason for hiding this comment

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

lgtm for this set of changes!

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.

Scroll location on page change Flattening/restructuring the component directory
5 participants