I'm a Full Stack Engineer at Meetup && organizer of the React Ladies community.
@waterproofheart
Intro |
React App Architecture |
|
What is Scaffolding? |
Scaffolding Options |
DIY Scaffolding |
@waterproofheart
Example modifed from: https://reactjs.org/docs/
@waterproofheart
@waterproofheart
@waterproofheart
@waterproofheart
@waterproofheart
Source: https://xkcd.com/1205/
@waterproofheart
import React, { Component } from 'react';
export class MyComponent extends Component {
render() {
return (
<div></div>
);
}
}
const MyComponent = (props) => {
return (
<div></div>
);
}
Class
Functional
@waterproofheart
@waterproofheart
Where should translations for this component live?
What's the current source of truth for our code standards?
Does every component go in the same folder?
How are components named?
What style should JavaScript components be written in?
@waterproofheart
@waterproofheart
React-boilerplate reduces overhead for developing a React app optimized for production
One-size-fits-all approach can unecessarily increase complexity and dependencies
@waterproofheart
@waterproofheart
@waterproofheart
More lightweight scaffolding solutions than
React Boilerplate and React Ignite
@waterproofheart
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
@waterproofheart
Handlebars templating language
(similar to Mustache)
Inquirer.JS is a a collection of common interactive command line user interfaces.
@waterproofheart
@waterproofheart
@waterproofheart
import { Backpack } from 'react-kawaii';
const Example = () => <Backpack size={ 300 } mood="lovestruck" color="#EC4067" />;
/**
*
* LovestruckBackpack
* Description: This component is a lovestruck Backpack.
*/
import React from 'react';
import { Backpack } from 'react-kawaii'
function LovestruckBackpack() {
return (
<Backpack size={ 200 } mood="lovestruck" color="#EC4067" />
);}
LovestruckBackpack.propTypes = {};
export default LovestruckBackpack;
@waterproofheart
Code
Component
Create a handlebars template
/**
*
* {{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
Plop is essentially a node module that accesses the plop API through a plop object that is passed in as a parameter.
module.exports = function (plop) {
// create your generators here
plop.setGenerator('basics', {
description: 'this is a skeleton plopfile',
prompts: [], // array of inquirer prompts
actions: [] // array of actions
});
};
@waterproofheart
Let's add out first prompt to select which Kawaii component we want to import
{
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
Let's add out first prompt to select which color we want our component to be
{
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
Let's create a prompt for what size our component should be
{
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
Let's add a prompt to select which the mood we want our component to have
{
type: "list",
name: "mood",
message: "Mood:",
choices: [
"sad",
"shocked",
"happy",
"blissful",
"lovestruck",
"excited",
"ko"
]
}
@waterproofheart
Now what do we want to do with the user input we collected?
actions: [
{
type: "add",
path: "src/{{properCase mood}}{{properCase kawaiiComponent}}.jsx",
templateFile: "src/plop-templates/kawaii-component-template.hbs"
},
{
type: "add",
path: "src/{{properCase mood}}{{properCase kawaiiComponent}}.test.jsx",
templateFile: "src/plop-templates/test.hbs"
}
]
@waterproofheart
Now what do we want to do with the user input we collected?
module.exports = function(plop) {
plop.setGenerator("Generate Kawaii Component", {
description: "Templates from the React Kawaii library ",
prompts: [
{
type: "list",
name: "kawaiiComponent",
message: "Which Kawaii component would you like to generate?:",
choices: [
"Backpack",
"Browser",
"Cat",
"CreditCard",...
]
}, // truncated for example...
],
actions: [
{
type: "add",
path: "src/{{properCase mood}}{{properCase kawaiiComponent}}.jsx",
templateFile: "src/plop-templates/kawaii-component-template.hbs"
},
{
type: "add",
path: "src/{{properCase mood}}{{properCase kawaiiComponent}}.test.jsx",
templateFile: "src/plop-templates/test.hbs"
}
]
});
};
@waterproofheart
{
type: "append",
path: "src/index.js",
pattern: /import ".\/index.css"[;]/,
unique: true,
templateFile: "src/plop-templates/import-component-template.hbs"
},
{
type: "append",
path: "src/index.js",
pattern: /<\/h1>/,
unique: true,
templateFile: "src/plop-templates/render-component-template.hbs"
}
@waterproofheart
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
// import generated component here
ReactDOM.render(
<div>
<h1>Demo</h1>
<!-- reference imported component here -->
</div>,
document.getElementById("root")
);
plopfile.js
index.js
@waterproofheart
// src/plop-templates/import-component-template.hbs
import {{properCase mood}}{{properCase kawaiiComponent}} from './{{properCase mood}}{{properCase kawaiiComponent}}';
// src/plop-templates/render-component-template.hbs
<{{properCase mood}}{{properCase kawaiiComponent}} />,
@waterproofheart
/**
*
* LovestruckBackpack
* Description: This component is a lovestruck Backpack.
*/
import React from 'react';
import { Backpack } from 'react-kawaii'
function LovestruckBackpack() {
return (
<Backpack size={ 200 } mood="lovestruck" color="#EC4067" />
);}
LovestruckBackpack.propTypes = {};
export default LovestruckBackpack;
@waterproofheart
@waterproofheart
1. Create handlebar templates
2. Create a plopfile and import plop
3. Define generator:
Some ideas:
Twitter: @waterproofheart
aboutmonica.com || monica.dev