Closed zeptonaut closed 1 year ago
Before I go ahead and style anything, I'd like to actually get the infrastructure set up that allows me to build a decent frontend for the app.
What technology you use to write the frontend depends on a number of factors:
Given that this is an interview and I want to get something working on a tight schedule, I'm going to stick with what I know: React. React offers off-the-shelf everything because it's so widely used.
Before we can add React, though, we need to add some sort of Javascript package management software (probably yarn) and some sort of build server (this seems like a good opportunity to try out Parcel because webpack is a huge pain in the butt to set up).
Adding yarn is as simple as:
yarn init
And then we can add Parcel with:
yarn add --dev parcel
Lastly, it looks like the app.js
and index.html
file are in the static/
folder, which is a little unconventional for React apps. I just moved them both into a src/
folder.
Finally, you can start the Parcel dev server with:
yarn parcel src/index.html
This shows the app running at localhost:1234, but unfortunately requests to the backend don't work. The fix to this is simple though: you just have to rewrite the requests that would normally go to the /search
endpoint and tell them to instead go to the locahost:5000/search. You can do this by creating the following .proxyrc
file and restarting Parcel:
{
"/search": {
"target": "http://localhost:5000/",
"pathRewrite": {
"^/search": "/search"
}
}
}
(This is very similar to something I've done to get development servers working with Webpack before.)
After doing this, you can go to localhost:1234
and everything works, including hot reload of the Javascript which will be nice for development. This should also make it much easier to get other parts of the Javascript ecosystem playing nicely with the app.
Conveniently, the app also continues to work at localhost:5000, which is critical because the go app will be the web server in production, not Parcel.
Added .babelrc
with the following:
{
"presets": [
["@babel/preset-react", {"runtime": "automatic"}]
]
}
This was required to get JSX working.
Also had to run:
yarn add react react-dom
yarn add -D parcel-bundler @babel/core @babel/preset-env @babel/preset-react
To get React all the necessary React reqs added to the project.
After doing this, the dead-simple React component that I added is rendering on the page.
Hm, it looks like something I did borked the proxy that allows us to have both the Parcel and Go web servers up and running.
As a reminder, the .proxyrc
file looks like:
{
"/search": {
"target": "http://localhost:5000/",
"pathRewrite": {
"^/search": "/search"
}
}
}
and the expectation is that when we make a call to localhost:1234/search?q=wood
, then Parcel will under the hood redirect that to localhost:5000/search?q=wood
.
We can clearly see in the Network tab of devtools that it isn't happening though:
It looks like the .proxyrc
file that I wrote is basically being ignored. I tried adding http-proxy-middleware
to the list of dev dependencies (as suggested might be necessary here), but that didn't seem to have any effect. I found some other documentation online that suggested that it was important that the .proxyrc
file be in the project root, but that seems to be the case.
Hm - genuinely baffled about what's going on here with the .proxyrc
file.
Here's what I know:
localhost:5000/search?q=wood
returns the actual go server results containing "wood"..proxyrc
file that looks like:
{
"/api": {
"target": "http://localhost:5000/",
"pathRewrite": {
"^/api": ""
}
}
}
and then go to http://localhost:1234/api/search?q=wood
, I'd expect to see the same page as going to http://localhost:5000/search?q=wood
. That doesn't seem to work though.
.proxyrc
should live in the project root vs. src/
(I'd certainly expect project root) is a little vague, but neither seems to work..proxyrc
file altogether if it's malformed, which isn't helpful. I tried turning on verbose logging with yarn start --log-level=verbose
, but then the entire Parcel server perplexingly doesn't want to startUnfortunately, I don't think there's too much to do at this point but go back to the last git commit and go forward from there.
Blah. Here we go again.
I went back to the last git commit with:
git reset --hard head
git clean -dff
Then I recreated the package.json and added Parcel with:
yarn init
yarn add --dev parcel
I then created the .proxyrc
file that looked like:
{
"/search": {
"target": "http://localhost:5000/"
}
}
Starting the Parcel server with:
yarn parcel static/index.js
and.... everything works. The only explanation I have at this point is that some stale cache of an old .proxyrc
was preventing this from working, despite having nuked anything that vaguely looked like a cache directory.
Blah again. Working forwards, I figured out what the problem was. I was following the directions at https://github.com/dastasoft/parcel-react-boilerplate in order to get React + Parcel up and running. However, one of the commands that repo asks you to run is:
yarn add -D parcel-bundler @babel/core @babel/preset-env @babel/preset-react
Note parcel-bundler
is in there, even though I've already installed Parcel.
Apparently parcel-bundler
is much older than parcel
, doesn't support .proxyrc
, and takes precedence over parcel
when both are installed. Therefore, it looked like all of my Parcel commands were working, but they were all using an older version of Parcel that didn't know how to process .proxyrc
files (something like 1.1.x instead of 2.8.x).
To fix this, I just removed parcel-bundler
from the repo and it got things working again.
I wanted to add DaisyUI (an open-source Tailwind UI package) in order to quickly and easily make the UI look nice. It has easy, nice formatting for stuff like tables.
I first mistakenly named the tailwind config file wrong .tailwind.config.js
instead of tailwind.config.js
- but after I named that file correctly and filled it with:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./src/**/*.{html,js,ts,jsx,tsx}',
],
theme: {
extend: {},
},
plugins: [require("daisyui")],
}
and then added a .postcssrc.json
of:
{
"plugins": {
"tailwindcss": {}
}
}
DaisyUI is working nicely. I can test it by changing App.js
to be:
const App = () => <button className="btn">Hello World!</button>
export default App;
which now uses the DaisyUI button class. And it indeed looks like a DaisyUI button:
Obviously, still not pretty, but it means that all of the pieces are in place to start making a reasonable looking interface.
Address the following issues: