Accio React App
My professional-self has been writing a whole lot of React components lately. I’ve mixed feelings about React (mostly do to it’s parentage), but I’m very much enjoying the work and am happy to be writing functional code.
When I started my most recent React project I decided to not use Webpack and instead opted to use Parcel (shout out to @hjertnes for the intro!). My plan was for this to be a post about Parcel and how to use it, but in the course of sussing out what I was going to cover, I ended up writing a little script…
The script is a beautifully procedural bit of bash
that instantiates a basic react starting point.
I’ve used Webpack before and found it to be a) overly complicated, b) a gargantuan time-suck.
I’ve also toyed with react-create-app and always been displeased. It works well, but is a bit limiting out of the box, and it’s eject
method is…terrifying?
Accio React App is my answer to react-create-app. It provides the minimal bits needed to start a React project (including react-router, sass and babel) and a basic project scaffolding. It isn’t much, but I’ve already found it to be a helpful little thing.
Here is the script in full, it can also be found on my pastebin and as a gist hosted on GitHub.
#!/bin/bash
# ACCIO REACT APP!
# A quick and dirty way to start a simple React project
# NOTE! This script assumes you are using Yarn
# Author: Eli (https://eli.li)
# License: unlicense (https://unlicense.org/)
read -p 'What is the name of your new project? ' PROJECTNAME
echo 'Creating new project, ' $PROJECTNAME
mkdir $PROJECTNAME
cd $PROJECTNAME
echo 'Now yarn is gonna do *A LOT* of stuff all at once, including initiating a new project, and pulling in a number of dependencies. This may take a few minutes.'
yarn init -y
yarn add react
yarn add react-dom
yarn add react-router-dom
yarn add node-sass
yarn add --dev parcel-bundler
yarn add --dev babel-preset-env
yarn add --dev babel-preset-react
echo 'Next is a slight modification to package.json, adding a `start` and a `build` script'
SCRIPT=',"scripts": {"start": "parcel index.html", "build": "parcel build index.html --out-dir dist" }'
printf '%s\n' H 17i "$SCRIPT" . wq | ed -s package.json
echo 'Making `.babelrc`!'
touch '.babelrc'
echo '{"presets": ["env", "react"]}' >> .babelrc
echo 'Making `.gitignore`!'
touch '.gitignore'
echo '/node_modules' >> .gitignore
echo '/dist' >> .gitignore
echo '/.cache' >> .gitignore
echo '.DS_Store' >> .gitignore
echo 'For our next trick!? Time to make the project scaffolding.'
mkdir 'src'
mkdir 'src/components'
mkdir 'src/scss'
mkdir 'src/static'
touch 'src/index.js'
touch 'src/components/HelloWorld.js'
touch 'src/scss/main.scss'
touch 'index.html'
touch 'README.md'
echo '<!doctype html>' >> index.html
echo '<html lang="en">' >> index.html
echo '<head>' >> index.html
echo '<meta charset="UTF-8">' >> index.html
echo '<meta name="viewport"' >> index.html
echo 'content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">' >> index.html
echo '<meta http-equiv="X-UA-Compatible" content="ie=edge">' >> index.html
echo '<title>'$PROJECTNAME'</title>' >> index.html
echo '<link rel="stylesheet" href="./src/scss/main.scss">' >> index.html
echo '</head>' >> index.html
echo '<body>' >> index.html
echo '<div id="root"></div>' >> index.html
echo '<script src="./src/index.js"></script>' >> index.html
echo '</body>' >> index.html
echo '</html>' >> index.html
echo 'import React from "react";' >> src/index.js
echo 'import ReactDOM from "react-dom";' >> src/index.js
echo 'import {BrowserRouter as Router, Route} from "react-router-dom"' >> src/index.js
echo 'import HelloWorld from "./components/HelloWorld"' >> src/index.js
echo ' ' >> src/index.js
echo 'let Root = document.getElementById("root");' >> src/index.js
echo ' ' >> src/index.js
echo 'ReactDOM.render(' >> src/index.js
echo '<Router>' >> src/index.js
echo '<main>' >> src/index.js
echo '<Route exact strict path="/" component={HelloWorld}/>' >> src/index.js
echo '</main>' >> src/index.js
echo '</Router>,' >> src/index.js
echo 'Root' >> src/index.js
echo ')' >> src/index.js
echo 'import React from "react"' >> src/components/HelloWorld.js
echo ' ' >> src/components/HelloWorld.js
echo 'export default class HelloWorld extends React.Component {' >> src/components/HelloWorld.js
echo 'constructor(props) {' >> src/components/HelloWorld.js
echo 'super(props);' >> src/components/HelloWorld.js
echo '}' >> src/components/HelloWorld.js
echo ' ' >> src/components/HelloWorld.js
echo 'render() {' >> src/components/HelloWorld.js
echo 'return (' >> src/components/HelloWorld.js
echo '<div>' >> src/components/HelloWorld.js
echo '<h1>Hello World!</h1>' >> src/components/HelloWorld.js
echo '</div>' >> src/components/HelloWorld.js
echo ')' >> src/components/HelloWorld.js
echo '}' >> src/components/HelloWorld.js
echo '}' >> src/components/HelloWorld.js
echo 'body {padding: 3em; color: pink}' >> src/scss/main.scss
echo '#' $PROJECTNAME >> README.md
echo ' ' >> README.md
echo '(ノ◕ヮ◕)ノ*:・゚✧' >> README.md
echo 'Built w/a very little bit of magic!' >> README.md
echo ' ' >> README.md
echo ' ' >> README.md
echo 'Run: w/either:' >> README.md
echo '```' >> README.md
echo '$ yarn start' >> README.md
echo '```' >> README.md
echo 'OR, if using NPM' >> README.md
echo '```' >> README.md
echo '$ npm start' >> README.md
echo '```' >> README.md
yarn start