A presentation at ReactJS Girls Conference in in London, UK by Monica Powell
ReactJS Girls Conf 2019 Automate Your React Workflow By: Monica Powell @waterproofheart
Hi, I’m Monica! I’m a Full Stack Engineer at Meetup && organizer of the React Ladies Group in NYC I’ve written about git and other tech adventures in publications such as FreeCodeCamp, Hacker Noon and Code Like A Girl. @waterproofheart
Follow Along Slides: http://aboutmonica.com/automationgeneration Code: https://github.com/M0nica/generate-react-components https://github.com/M0nica/generate-kawaii-components @waterproofheart
Overview
What does a typical React app look like? UI components are the building blocks of React apps Multiple components require test, CSS, translation, etc. files locally scoped to each component Example modifed from: https://reactjs.org/docs/ @waterproofheart
Adding components can be repetitive… @waterproofheart
What if you want consistency across components without having to copy + paste + then manually change code between files? @waterproofheart
The answer is mail merge @waterproofheart
The answer is mail merge @waterproofheart
The answer is templates @waterproofheart
Is it worth the time? Source: https://xkcd.com/1205/ @waterproofheart
Scaffolding Scaffolding software is the process of generating startercode based on templates. The starter-code is compromised of boilerplate code that is shared between all code components that share the same conventions. Minimial Viable Component != ready for production. @waterproofheart
Scaffolding Some benefits of scaffolding are: Reduce time to generate new projects or components. less error-prone than copy & pasting & editing encourage consistency and implementation of design patterns @waterproofheart
Scaffolding Can Improve Developer Experience Having an efficient way to consistently implement standards minimizes certain questions about conventions and helps engineers have a more enjoyable onboarding experience when working with a new codebase. @waterproofheart
Scaffolding Can Answer FAQs “ Where can I find the translations for this component? “ Does every component go in “ the same folder? How are components “ named? What style should JavaScript “ components be written in? What’s the current source of truth for our code standards? @waterproofheart
Scaffolding Tools @waterproofheart
React-Boilerplate React-boilerplate reduces overhead for developing a React app optimized for production One-size-fits-all approach can unecessarily increase complexity and dependencies Includes CLI tool to scaffold React components, containers, 3 routes, selectors and sagas 2 @waterproofheart
React-Boilerplate @waterproofheart
Separate Templates Based on Type of Component 1 import React, { Component } from ‘react’; 2 3 export class MyComponent extends Component { 4 render() { 5 return ( 6 <div></div> 7 ); 8 } 9 } Class 1 const MyComponent = (props) => { 2 return ( 3 <div></div> 4 ); 5 } Functional @waterproofheart
Ignite React Ignite is similar to React-boilerplate but for React Native Includes various customizable tools to jump start the creation of React Native applications “Ignite speeds up your app development by over two weeks on average.” @waterproofheart
Should developer use existing React scaffolding tools? The beauty of an effective scaffolding tool is that these tools are designed to be highly-customizable to fit your needs without having to compromise on your standards or best practices. @waterproofheart
Code Generators More lightweight scaffolding solutions than React Boilerplate and React Ignite github.com/diegohaz/generact github.com/jondot/hygen github.com/amwmedia/plop @waterproofheart
PlopJS PlopJS is a microgenerator, and is used under the hood in React-Boilerplate It generates files based on user input via a Command Line Interace (CLI). Minimal setup required plopjs.com @waterproofheart
PlopJS + Handlebars templating language (similar to Mustache) Inquirer.JS is a a collection of common interactive command line user interfaces. @waterproofheart
Let’s generate Kawaii Components https://github.com/miukimiu/react-kawaii @waterproofheart
Structure of Kawaii Components 1 import { Backpack } from ‘react-kawaii’; 2 3 const Example = () => <Backpack size={ 300 } mood=”lovestruck” color=”#EC4067” />; https://github.com/miukimiu/react-kawaii @waterproofheart
Getting started with Plop Now what do we want to do with the user 1 input we collected? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /** * * {{properCase mood}}{{properCase kawaiiComponent}} * Description: This component is a {{mood}} {{kawaiiComponent}}. */ import React from ‘react’; import { {{kawaiiComponent}} } from ‘react-kawaii’ function {{properCase mood}}{{properCase kawaiiComponent}}() { return ( <{{kawaiiComponent}} size={ {{size}} } mood=”{{mood}}” color=”{{color}}” /> ); } {{properCase mood}}{{properCase kawaiiComponent}}.propTypes = {}; export default {{properCase mood}}{{properCase kawaiiComponent}}; @waterproofheart
Getting started with Plop Now what do we want to do with the user 1 input we collected? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /** * * {{properCase mood}}{{properCase kawaiiComponent}} * Description: This component is a {{mood}} {{kawaiiComponent}}. */ import React from ‘react’; import { {{kawaiiComponent}} } from ‘react-kawaii’ function {{properCase mood}}{{properCase kawaiiComponent}}() { return ( <{{kawaiiComponent}} size={ {{size}} } mood=”{{mood}}” color=”{{color}}” /> ); } {{properCase mood}}{{properCase kawaiiComponent}}.propTypes = {}; export default {{properCase mood}}{{properCase kawaiiComponent}}; @waterproofheart
Getting started with Plop Plop is essentially a node module that accesses the plop API through a plop object that is passed in as a parameter. 1 module.exports = function (plop) { 2 // create your generators here 3 plop.setGenerator(‘basics’, { 4 description: ‘this is a skeleton plopfile’, 5 prompts: [], // array of inquirer prompts 6 actions: [] // array of actions 7 }); 8 }; @waterproofheart
Getting started with Plop Plop is essentially a node module that accesses the plop API through a plop object that is passed in as a parameter. 1 module.exports = function (plop) { 2 // create your generators here 3 plop.setGenerator(‘basics’, { 4 description: ‘this is a skeleton plopfile’, 5 prompts: [], // array of inquirer prompts 6 actions: [] // array of actions 7 }); 8 }; @waterproofheart
Which component should we import? Let’s add out first prompt to select which Kawaii component we want to import 1 { 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 type: “list”, name: “kawaiiComponent”, message: “Which Kawaii component would you like to generate?:”, choices: [ “Backpack”, “Browser”, “Cat”, “CreditCard”, “File”, “Ghost”, “IceCream”, “Mug”, “Planet”, “SpeechBubble” ] }, @waterproofheart
Which component should we import? Let’s add out first prompt to select which Kawaii component we want to import 1 { 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 type: “list”, name: “kawaiiComponent”, message: “Which Kawaii component would you like to generate?:”, choices: [ “Backpack”, “Browser”, “Cat”, “CreditCard”, “File”, “Ghost”, “IceCream”, “Mug”, “Planet”, “SpeechBubble” ] }, @waterproofheart
What color should component be? Let’s add out first prompt to select which color we want our component to be 1 2 3 4 5 6 7 8 9 10 11 12 13 14 { type: “list”, name: “color”, message: “What color should the component be:”, choices: [“eggplant”, “mint”, “bubblegum pink”, “purple”, “lime”], filter: colour => ({ “eggplant”: “#2E294E”, “mint”: “#1B998B”, “bubblegum pink”: “#EC4067”, “purple”: “#9A39AB”, “lime”: “#C5D86D” }[colour]) }, @waterproofheart
What color should component be? Let’s add out first prompt to select which color we want our component to be 1 2 3 4 5 6 7 8 9 10 11 12 13 14 { type: “list”, name: “color”, message: “What color should the component be:”, choices: [“eggplant”, “mint”, “bubblegum pink”, “purple”, “lime”], filter: colour => ({ “eggplant”: “#2E294E”, “mint”: “#1B998B”, “bubblegum pink”: “#EC4067”, “purple”: “#9A39AB”, “lime”: “#C5D86D” }[colour]) }, @waterproofheart
What size should our component be? Let’s create a prompt for what size our component should be 1 2 3 4 5 6 7 8 9 10 11 12 13 14 { type: “list”, name: “size”, message: “What size should the component be:”, choices: [“extra small”, “small”, “medium”, “large”, “extra large”], filter: val => ({ “extra small”: 100, “small”: 200, “medium”: 300, “large”: 500, “extra large”: 800 }[val]) } @waterproofheart
What size should our component be? Let’s create a prompt for what size our component should be 1 2 3 4 5 6 7 8 9 10 11 12 13 14 { type: “list”, name: “size”, message: “What size should the component be:”, choices: [“extra small”, “small”, “medium”, “large”, “extra large”], filter: val => ({ “extra small”: 100, “small”: 200, “medium”: 300, “large”: 500, “extra large”: 800 }[val]) } @waterproofheart
What mood should our component have? Let’s add a prompt to select which the mood we want our component to have 1 2 3 4 5 6 7 8 9 10 11 12 13 14 { type: “list”, name: “mood”, message: “Mood:”, choices: [ “sad”, “shocked”, “happy”, “blissful”, “lovestruck”, “excited”, “ko” ] } @waterproofheart
What mood should our component have? Let’s add a prompt to select which the mood we want our component to have 1 2 3 4 5 6 7 8 9 10 11 12 13 14 { type: “list”, name: “mood”, message: “Mood:”, choices: [ “sad”, “shocked”, “happy”, “blissful”, “lovestruck”, “excited”, “ko” ] } @waterproofheart
Getting started with Plop Now what do we want to do with the user input we collected? 1 actions: [ 2 { 3 type: “add”, 4 path: “src/{{properCase mood}}{{properCase kawaiiComponent}}.jsx”, 5 templateFile: “src/plop-templates/kawaii-component-template.hbs” 6 }, 7 { 8 type: “add”, 9 path: “src/{{properCase mood}}{{properCase kawaiiComponent}}.test.jsx”, 10 templateFile: “src/plop-templates/test.hbs” 11 } 12 ] @waterproofheart
Getting started with Plop Now what do we want to do with the user input we collected? 1 actions: [ 2 { 3 type: “add”, 4 path: “src/{{properCase mood}}{{properCase kawaiiComponent}}.jsx”, 5 templateFile: “src/plop-templates/kawaii-component-template.hbs” 6 }, 7 { 8 type: “add”, 9 path: “src/{{properCase mood}}{{properCase kawaiiComponent}}.test.jsx”, 10 templateFile: “src/plop-templates/test.hbs” 11 } 12 ] @waterproofheart
Finished Plop File 1 module.exports = function(plop) { 2 plop.setGenerator(“Generate Kawaii Component”, { 3 description: “Templates from the React Kawaii library “, 4 prompts: [ 5 { 6 type: “list”, 7 name: “kawaiiComponent”, 8 message: “Which Kawaii component would you like to generate?:”, 9 choices: [ 10 “Backpack”, 11 “Browser”, 12 “Cat”, 13 “CreditCard”,… 14 ] 15 }, // truncated for example… 16 ], 17 actions: [ 18 { 19 type: “add”, 20 path: “src/{{properCase mood}}{{properCase kawaiiComponent}}.jsx”, 21 templateFile: “src/plop-templates/kawaii-component-template.hbs” 22 }, 23 { 24 type: “add”, 25 path: “src/{{properCase mood}}{{properCase kawaiiComponent}}.test.jsx”, 26 templateFile: “src/plop-templates/test.hbs” 27 } 28 ] 29 }); 30 }; Now what do we want to do with the user input we collected? @waterproofheart
Finished Plop File 1 module.exports = function(plop) { 2 plop.setGenerator(“Generate Kawaii Component”, { 3 description: “Templates from the React Kawaii library “, 4 prompts: [ 5 { 6 type: “list”, 7 name: “kawaiiComponent”, 8 message: “Which Kawaii component would you like to generate?:”, 9 choices: [ 10 “Backpack”, 11 “Browser”, 12 “Cat”, 13 “CreditCard”,… 14 ] 15 }, // truncated for example… 16 ], 17 actions: [ 18 { 19 type: “add”, 20 path: “src/{{properCase mood}}{{properCase kawaiiComponent}}.jsx”, 21 templateFile: “src/plop-templates/kawaii-component-template.hbs” 22 }, 23 { 24 type: “add”, 25 path: “src/{{properCase mood}}{{properCase kawaiiComponent}}.test.jsx”, 26 templateFile: “src/plop-templates/test.hbs” 27 } 28 ] 29 }); 30 }; Now what do we want to do with the user input we collected? @waterproofheart
Getting started with Plop Now what do we want to do with the user 1 input we collected? @waterproofheart
Getting started with Plop Now what do we want to do with the user 1 input we collected? 1 2 3 4 /** * * LovestruckBackpack * Description: This component is a lovestruck Backpack. 5 */ 6 7 import React from ‘react’; 8 import { Backpack } from ‘react-kawaii’ 9 10 function LovestruckBackpack() { 11 return ( 12 <Backpack size={ 200 } mood=”lovestruck” color=”#EC4067” /> 13 14 );} 15 16 LovestruckBackpack.propTypes = {}; 17 18 export default LovestruckBackpack; @waterproofheart
Getting started with Plop Now what do we want to do with the user 1 input we collected? 1 2 3 4 /** * * LovestruckBackpack * Description: This component is a lovestruck Backpack. 5 */ 6 7 import React from ‘react’; 8 import { Backpack } from ‘react-kawaii’ 9 10 function LovestruckBackpack() { 11 return ( 12 <Backpack size={ 200 } mood=”lovestruck” color=”#EC4067” /> 13 14 );} 15 16 LovestruckBackpack.propTypes = {}; 17 18 export default LovestruckBackpack; @waterproofheart
Challenge Create a CLI tool that you can adapt to at least two different use cases. You can either use two seperate templates or one template with conditional logic. 1
Challenge Some ideas: generate new Gatsby blog posts and pages generator components from a component library that you use regularly Examples: https://github.com/M0nica/generate-reactcomponents 1 https://github.com/M0nica/generate-kawaiicomponents
Thank You! Twitter: @waterproofheart aboutmonica.com || monica.dev If you’re in NYC come to a React Ladies Meetup: meetup.com/React-Ladies/
Do you find yourself copying and pasting the same boilerplate React code in multiple files every time you create a new component? Imagine a world without copy and paste. How much time would that cost you? This talk will walk through how to create a command-line interface (CLI) tool that generates React component files and other ways to automate your workflow.
Here’s what was said about this presentation on social media.
.@waterproofheart — these slides OMG OMG OMG 😱😱😱🙌🙌🙌 pic.twitter.com/amvlxZ7fW1
— Jenn Creighton @ ReactConf (@gurlcode) May 3, 2019
🔴 #ReactjsGirls conf is streaming live!
— ReactJS Girls (@ReactJSgirls) May 3, 2019
Watch here: https://t.co/boColTq0oY
Our speakers:@marcysutton@codegirl_@waterproofheart@erinfoox@marta_frn @emmawedekind@carolstran@manjula_dube@sbinlondon@gurlcode@eveporcello
Thanks @YLDio for organising 🙏
Missed this but hoping to catch up on some of the talks later. Also excited to see @waterproofheart talk (hope I didn't miss it..) ❤️ https://t.co/5kw8rgAPvJ
— Nitya Narasimhan @ NY (@nitya) May 3, 2019
Thank you @ReactJSgirls @YLDio for organizing such an amazing event and having me as a speaker #ReactJSGirls✨⚛️💜 pic.twitter.com/FJqKqetLyw
— Monica.dev @ #ReactConf 👩🏾💻 (@waterproofheart) May 3, 2019
I built a component generator using plop a few days ago. It was so much fun to watch @waterproofheart talk about it today!#ReactjsGirls pic.twitter.com/jgEUg3zqVg
— Anushree Subramani 👑 (@imAnushree) May 3, 2019
How To Automate Your React workflow -- by @waterproofheart at #ReactJSGirls #sketchnotes pic.twitter.com/iGUHChhbYY
— Malwine (@malweene) May 3, 2019
Amazing talk on generators by @waterproofheart at #ReactjsGirls
— Nuno Job (@dscape) May 3, 2019
Really interesting ways of automating , especially when mixed with a solid design system
Code 👇 pic.twitter.com/q5zpTFkr1M
Scaffolding to generate components and apps can be a fantastic way of helping engineers understand standards and best practices (& a big time saver). We have generators for our microservices at @makingmonzo making it so easy to spin up a new one
— localghost 👻 (@type__error) May 3, 2019
@waterproofheart #ReactJSgirls pic.twitter.com/v271amWL3W
Wow, @waterproofheart's intro slide with the robots was so cool! Great talk about scaffolding at #ReactJSGirls!
— Tejas at React Conf ⚛️ (@TejasKumar_) May 3, 2019
Absolutely love @waterproofheart talk on How to Automate Your React workflow @ReactJSgirls conf! https://t.co/zDj2DzCWNZ
— Gift Egwuenu ✨ (@lauragift21) May 3, 2019
@waterproofheart taking about automation. Not always worth it but when it is it's great! #reactjsgirls pic.twitter.com/fqZBigdyG4
— .hocus:focus {🧙♀️} - eli schutze (@elibelly) May 3, 2019
We're back on livestream with our next speaker @waterproofheart from @Meetup speaking on How To Automate Your #Reactjs Workflow 🤩 https://t.co/qBEWztJ7BA
— ReactJS Girls (@ReactJSgirls) May 3, 2019
So @ReactJSgirls has officially started stay tuned for speakers like @codegirl_, @waterproofheart, @emmawedekind and @eveporcello#ReactjsGirls 💃🏽
— Leah Cottham👩🏽💻 (@SearchableLe) May 3, 2019
Keep in the loop with the live stream: https://t.co/hkajvIQY52 👩🏼💻