Automate React Workflow

A presentation at ReactJS Girls Conference in May 2019 in London, UK by Monica Powell

Slide 1

Slide 1

ReactJS Girls Conf 2019 Automate Your React Workflow By: Monica Powell @waterproofheart

Slide 2

Slide 2

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

Slide 3

Slide 3

Follow Along Slides: http://aboutmonica.com/automationgeneration Code: https://github.com/M0nica/generate-react-components https://github.com/M0nica/generate-kawaii-components @waterproofheart

Slide 4

Slide 4

Overview

  1. Introduction
  2. What is Scaffolding?
  3. Scaffolding Options
  4. React App Architecture
  5. DIY Scaffolding @waterproofheart

Slide 5

Slide 5

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

Slide 6

Slide 6

Adding components can be repetitive… @waterproofheart

Slide 7

Slide 7

What if you want consistency across components without having to copy + paste + then manually change code between files? @waterproofheart

Slide 8

Slide 8

The answer is mail merge @waterproofheart

Slide 9

Slide 9

The answer is mail merge @waterproofheart

Slide 10

Slide 10

The answer is templates @waterproofheart

Slide 11

Slide 11

Is it worth the time? Source: https://xkcd.com/1205/ @waterproofheart

Slide 12

Slide 12

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

Slide 13

Slide 13

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

Slide 14

Slide 14

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

Slide 15

Slide 15

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

Slide 16

Slide 16

Scaffolding Tools @waterproofheart

Slide 17

Slide 17

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

Slide 18

Slide 18

React-Boilerplate @waterproofheart

Slide 19

Slide 19

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

Slide 20

Slide 20

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

Slide 21

Slide 21

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

Slide 22

Slide 22

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

Slide 23

Slide 23

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

Slide 24

Slide 24

PlopJS + Handlebars templating language (similar to Mustache) Inquirer.JS is a a collection of common interactive command line user interfaces. @waterproofheart

Slide 25

Slide 25

Let’s generate Kawaii Components https://github.com/miukimiu/react-kawaii @waterproofheart

Slide 26

Slide 26

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

Slide 27

Slide 27

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

Slide 28

Slide 28

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

Slide 29

Slide 29

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

Slide 30

Slide 30

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

Slide 31

Slide 31

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

Slide 32

Slide 32

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

Slide 33

Slide 33

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

Slide 34

Slide 34

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

Slide 35

Slide 35

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

Slide 36

Slide 36

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

Slide 37

Slide 37

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

Slide 38

Slide 38

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

Slide 39

Slide 39

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

Slide 40

Slide 40

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

Slide 41

Slide 41

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

Slide 42

Slide 42

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

Slide 43

Slide 43

Getting started with Plop Now what do we want to do with the user 1 input we collected? @waterproofheart

Slide 44

Slide 44

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

Slide 45

Slide 45

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

Slide 46

Slide 46

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

Slide 47

Slide 47

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

Slide 48

Slide 48

Thank You! Twitter: @waterproofheart aboutmonica.com || monica.dev If you’re in NYC come to a React Ladies Meetup: meetup.com/React-Ladies/