Skip to content

Update React development stack #72

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

Merged
merged 10 commits into from
Nov 10, 2020
Merged

Update React development stack #72

merged 10 commits into from
Nov 10, 2020

Conversation

watsonbox
Copy link
Owner

@watsonbox watsonbox commented Nov 9, 2020

The goal here is to update the project to a more modern React stack, brining several benefits:

  • Using create-react-app is an established standard development stack which should make contributing easier
  • Build step separates production and development environments (file structure, tests, performance)
  • More robust development toolchain including live reload, auto test runs, linting etc
  • Much improved testing framework (JEST)
  • Up to date versions of React, Font Awesome, JSZip and FileSaver.js
  • Sass for styling
  • Clear path to full ES6 / TypeScript

Out of Scope

I've deliberately omitted some things in this step, in order to keep the scope under control:

- JSZip
- FileSaver.js
- jQuery for legacy code support
- Fontawesome
- Sass
- Bootstrap and Bootstrap React

Keeping old version of Bootstrap for now (upgrade to come later)
- Yarn for dependency management
- react-fontawesome for Font Awesome 5 icon components
- TypeScript (more to come)
- SASS support
- JSZip upgrade

Note: I've kept certain things like Bootstrap 3 and jQuery in order to make changes incrementally.
@watsonbox watsonbox self-assigned this Nov 9, 2020
@watsonbox watsonbox changed the title Update React Stack Update React stack Nov 9, 2020
@watsonbox watsonbox changed the title Update React stack Update React development stack Nov 9, 2020
- Auth redirect flow
- Playlist loading (snapshot)
- Single playlist export
- Export all playlists
Copy link

@tesnouf-drivy tesnouf-drivy left a comment

Choose a reason for hiding this comment

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

Some minors comments/suggestions:

Some code could be more ES6+ friendly and React Components are a little bit legacy (Class Component instead of functional) and constructors are missing

I didn't focus on the logical side but this little project is neat !

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { authorize } from "helpers"

class Login extends React.Component {

Choose a reason for hiding this comment

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

Despite not being deprecated, the nowadays way to go for Components are Functional components especially if you have no state. It's simpler and easier to write/test

Copy link
Owner Author

Choose a reason for hiding this comment

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

Okay noted, I may simplify these then 👍

import { apiCall } from "helpers"

// Handles exporting a single playlist as a CSV file
var PlaylistExporter = {

Choose a reason for hiding this comment

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

all your var should be replaced by let or const

Copy link
Owner Author

Choose a reason for hiding this comment

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

Yep I think I'll clean up all the legacy code file by file once this is merged 👍

Comment on lines +74 to +77
tracks.forEach(function(row, index){
let dataString = row.map(function (cell) { return '"' + String(cell).replace(/"/g, '""') + '"'; }).join(",");
csvContent += dataString + "\n";
});

Choose a reason for hiding this comment

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

When iterating on a loop to build something, you could use the reduce function

const csvContent = tracks.reduce( (acc, row) => {
return `${acc}${row.map(cell => '"' + String(cell).replace(/"/g, '""') + '"'; }).join(","))}\n`
      }, '');

Comment on lines +11 to +18
state = {
playlists: [],
playlistCount: 0,
likedSongsLimit: 0,
likedSongsCount: 0,
nextURL: null,
prevURL: null
}

Choose a reason for hiding this comment

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

should be defined in your constructor:
https://reactjs.org/docs/react-component.html#constructor

Copy link
Owner Author

Choose a reason for hiding this comment

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

I read that if the constructor isn't required for anything else, this is cleaner e.g.:

https://dev.to/ascorbic/class-fields-are-coming-heres-what-that-means-for-react--3a87

window.location.href = window.location.href.split('#')[0] + '?rate_limit_message=true'
} else {
// Otherwise report the error so user can raise an issue
alert(jqXHR.responseText);

Choose a reason for hiding this comment

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

I guess it's a critical case...

Copy link
Owner Author

Choose a reason for hiding this comment

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

Meh, again I think this should be improved at some point.

</nav>
)
} else {
return <div>&nbsp;</div>

Choose a reason for hiding this comment

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

it's a little bit odd to return an empty div
Could return null do the job ? or at least return <div></div> ?

@@ -0,0 +1,139 @@
import React from "react"
import $ from "jquery" // TODO: Remove jQuery dependency

Choose a reason for hiding this comment

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

your comment say it all ;)

Comment on lines +111 to +117
<th style={{width: "30px"}}></th>
<th>Name</th>
<th style={{width: "150px"}}>Owner</th>
<th style={{width: "100px"}}>Tracks</th>
<th style={{width: "120px"}}>Public?</th>
<th style={{width: "120px"}}>Collaborative?</th>
<th style={{width: "100px"}} className="text-right">

Choose a reason for hiding this comment

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

you should define your width using css classes.
Directly defining the style object is required when using variable / computing the value.
Aside of separating the visual from your logic, doing so won't break your Jest snapshots if you decide to change a column width

Copy link
Owner Author

Choose a reason for hiding this comment

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

Very good point about the Jest snapshots! Indeed, something else to add to the cleanup list 👍

@watsonbox
Copy link
Owner Author

Thanks a lot for the comments @tesnouf-drivy 🙏

@pavelkomarov
Copy link
Contributor

My PR gets rid of all jquery. Not sure how my React is compared to this PR; it is the first and only thing I've ever done in React. Honestly don't love React. Super verbose and annoying.

@watsonbox watsonbox mentioned this pull request Nov 10, 2020
@watsonbox watsonbox marked this pull request as ready for review November 10, 2020 09:04
@watsonbox watsonbox merged commit 85ff3e4 into master Nov 10, 2020
watsonbox added a commit that referenced this pull request Nov 10, 2020
* Remove old project structure

* Initialize project using Create React App

npx create-react-app exportify --template typescript

(https://create-react-app.dev/docs/adding-typescript/)

* Add dependencies

- JSZip
- FileSaver.js
- jQuery for legacy code support
- Fontawesome
- Sass
- Bootstrap and Bootstrap React

Keeping old version of Bootstrap for now (upgrade to come later)

* Migrate Exportify to create-react-app stack

- Yarn for dependency management
- react-fontawesome for Font Awesome 5 icon components
- TypeScript (more to come)
- SASS support
- JSZip upgrade

Note: I've kept certain things like Bootstrap 3 and jQuery in order to make changes incrementally.

* Add test suite

- Auth redirect flow
- Playlist loading (snapshot)
- Single playlist export
- Export all playlists

* Add Bugsnag for error monitoring

* Replace bind(this) with arrow functions

* Use literals template for string concatenation

* Update README.md for create-react-app  development stack

* Don't use Bugsnag in development environment
watsonbox added a commit that referenced this pull request Nov 10, 2020
watsonbox added a commit that referenced this pull request Nov 11, 2020
* Remove old project structure

* Initialize project using Create React App

npx create-react-app exportify --template typescript

(https://create-react-app.dev/docs/adding-typescript/)

* Add dependencies

- JSZip
- FileSaver.js
- jQuery for legacy code support
- Fontawesome
- Sass
- Bootstrap and Bootstrap React

Keeping old version of Bootstrap for now (upgrade to come later)

* Migrate Exportify to create-react-app stack

- Yarn for dependency management
- react-fontawesome for Font Awesome 5 icon components
- TypeScript (more to come)
- SASS support
- JSZip upgrade

Note: I've kept certain things like Bootstrap 3 and jQuery in order to make changes incrementally.

* Add test suite

- Auth redirect flow
- Playlist loading (snapshot)
- Single playlist export
- Export all playlists

* Add Bugsnag for error monitoring

* Replace bind(this) with arrow functions

* Use literals template for string concatenation

* Update README.md for create-react-app  development stack

* Don't use Bugsnag in development environment
@watsonbox watsonbox deleted the v2 branch November 19, 2020 11:36
@watsonbox watsonbox mentioned this pull request Nov 22, 2020
watsonbox added a commit that referenced this pull request Aug 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants