Slide 1

Slide 1 text

Let's make sure everybody is on board 1. https://github.com/noelrappin/rails_conf_north_by 2. bundle install 3. yarn install 4. rails server -> http://localhost:3000/schedule 5. The toggle buttons should not work 6. http://bit.ly/workshop_snippets Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 2

Slide 2 text

Rails 6, Webpacker, and Stimulus Noel Rappin (@noelrap) http://www.tablexi.com http://techdoneright.io http://www.noelrappin.com Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 3

Slide 3 text

We are going to • Walk-through adding a stimulus feature • talk about webpack and webpacker • see where we are on time • work together to add more stimulus code Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 4

Slide 4 text

Some ground rules: Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 5

Slide 5 text

Feel free to ask questions Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 6

Slide 6 text

Pair... if you are comfortable doing so Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 7

Slide 7 text

Everybody knows that the best way to learn is under intense, life- threatening pressure! Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 8

Slide 8 text

We have a Rails app Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 9

Slide 9 text

We want to improve the user experience Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 10

Slide 10 text

But we don't need a single page app Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 11

Slide 11 text

There are a lot of Questions Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 12

Slide 12 text

Logistics: How to convert our code into something nice that we can send to the browser Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 13

Slide 13 text

Webpack(er) Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 14

Slide 14 text

Structure: What's a good structure for non- SPA JavaScript interactions Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 15

Slide 15 text

Stimulus Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 16

Slide 16 text

"A Modest JavaScript Framework for the HTML you already have" Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 17

Slide 17 text

Stimulus has four basic concepts Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 18

Slide 18 text

Controllers Actions Targets Data Maps Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 19

Slide 19 text

Controllers Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 20

Slide 20 text

A controller is where Stimulus code is executed Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 21

Slide 21 text

A controller is associated with an HTML Element Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 22

Slide 22 text

The controller is active across that element and its children Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 23

Slide 23 text

Let's create a controller! Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 24

Slide 24 text

All the stuff to enter in this section is in http://bit.ly/ workshop_snippets Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 25

Slide 25 text

app/views/schedule/ show.html.erb:29-30 " data-controller="toggle"> Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 26

Slide 26 text

The code for the controller exists in app/javascript/ controllers/ toggle_controller.js Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 27

Slide 27 text

import { Controller } from "stimulus" export default class extends Controller { connect() { console.log("The Controller is Connected") } } Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 28

Slide 28 text

Reload the page Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 29

Slide 29 text

You'll see in the log [Webpacker] Compiling… Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 30

Slide 30 text

And the message in the console Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 31

Slide 31 text

An element can have multiple controllers Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 32

Slide 32 text

A controller can be instantiated multiple times Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 33

Slide 33 text

Action Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 34

Slide 34 text

Actions are associated with an HTML element Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 35

Slide 35 text

app/views/schedule/ show.html.erb:34
Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 36

Slide 36 text

app/javascript/controllers/ toggle_controller.rb toggle() { console.log("click") } Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 37

Slide 37 text

An action associates an arbitrary event to a controller method event->controller#method Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 38

Slide 38 text

When the event happens, Stimulus dispatches to the controller method Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 39

Slide 39 text

The HTML element must be within the controller being referenced Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 40

Slide 40 text

Target Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 41

Slide 41 text

A Target is an HTML element of interest to a controller Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 42

Slide 42 text

Targets are associated with an HTML element Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 43

Slide 43 text

app/views/schedule/ show.html.erb:39 Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 44

Slide 44 text

And then are registered with the controller: static targets = ["thingToHide"] Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 45

Slide 45 text

Targets make it easy to look up elements of interest You get: • this.thingToHideTarget • this.thingToHideTargets • this.hasThingToHideTarget Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 46

Slide 46 text

Let's update our action Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 47

Slide 47 text

toggle() { this.thingToHideTarget.classList.toggle("is-hidden") } Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 48

Slide 48 text

Data Map Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 49

Slide 49 text

A Data Map allows you to associate data with a controller Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 50

Slide 50 text

app/views/schedule/ show.html.haml " data-controller="toggle" data-toggle-hidden="false"> Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 51

Slide 51 text

Data maps belong to the controller data-controllername-key • get(key) • has(key) • set(key, stringValue) • delete(key) Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 52

Slide 52 text

If we add another target: Hide Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 53

Slide 53 text

We can glue it all together Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 54

Slide 54 text

import { Controller } from "stimulus" export default class extends Controller { static targets = ["text", "thingToHide"] hidden() { return this.data.get("hidden") === "true" } flip() { this.data.set("hidden", this.hidden() ? "false" : "true") } toggle() { this.flip() this.thingToHideTarget.classList.toggle("is-hidden", this.isHidden()) this.textTarget.innerText = this.isHidden() ? "Show" : "Hide" } } Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 55

Slide 55 text

Stimulus Cheatsheet Item Attribute Value Naming Controller data-controller controller-name Action data-action event->controller- name#methodName Target data-target controller- name.targetName Data Map data-controller-name- attribute value as string Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 56

Slide 56 text

How does this all work? Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 57

Slide 57 text

At compile, webpack loads all controllers import { Application } from "stimulus" import { definitionsFromContext } from "stimulus/webpack-helpers" const application = Application.start() const context = require.context("controllers", true, /_controller\.js$/) application.load(definitionsFromContext(context)) Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 58

Slide 58 text

On page load, Stimulus detects the data-controller attributes and instantiates new controller instances. Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 59

Slide 59 text

Stimulus also finds all the actions and sets up event listeners Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 60

Slide 60 text

When the event is triggered, the stimulus listener sends control to the method. Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 61

Slide 61 text

In the method, Stimulus generates the data and target properties Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 62

Slide 62 text

Why Stimulus? Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 63

Slide 63 text

Low Overhead Easy to follow Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 64

Slide 64 text

Removes a lot of boilerplate event listeners Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 65

Slide 65 text

Makes it easy to write small modular effects Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 66

Slide 66 text

Great at handling dynamic changes to the page. Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 67

Slide 67 text

Why not Stimulus? Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 68

Slide 68 text

No support for router/ SPA Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 69

Slide 69 text

Not super-helpful if there's a lot of state, or controlled access to state. Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 70

Slide 70 text

Let's talk about: Webpack and Webpacker Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 71

Slide 71 text

When executing our code: Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 72

Slide 72 text

Our code knew how to find other modules via include Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 73

Slide 73 text

The browser got all of our individual files in one pack Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 74

Slide 74 text

Our changes were automatically compiled on page reload. Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 75

Slide 75 text

Webpack Webpacker Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 76

Slide 76 text

Webpack's mission in life: Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 77

Slide 77 text

"At its core, webpack is a static module bundler for modern JavaScript applications. Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 78

Slide 78 text

Entry Output Loaders / Plugins Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 79

Slide 79 text

Entry: A file. Often JavaScript. Usually referencing other files in use. Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 80

Slide 80 text

Webpack uses entry points to build a "dependency graph" Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 81

Slide 81 text

Output: where the bundle ends up Often the code is turned into a single file. Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 82

Slide 82 text

Loaders: transform files add them the graph Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 83

Slide 83 text

For Example: TypeScript compiler CSS Loader File loader Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 84

Slide 84 text

Webpacker's mission in life Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 85

Slide 85 text

"Webpack is really complicated" Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 86

Slide 86 text

Webpacker provides Useful defaults Makes some behavior easier to override Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 87

Slide 87 text

Webpacker is the default for new Rails 6 apps Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 88

Slide 88 text

rails webpacker:install Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 89

Slide 89 text

It has default configs for • Angular • Coffeescript • Elm • Erb Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 90

Slide 90 text

It has default configs for • React • Stimulus • TypeScript • Vue Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 91

Slide 91 text

Important files: Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 92

Slide 92 text

package.json /node_modules Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 93

Slide 93 text

config/webpacker.yml config/webpack/ Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 94

Slide 94 text

babel.config.js postcss.config.js Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 95

Slide 95 text

What are the defaults? Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 96

Slide 96 text

Any file in application/ javascript/packs is considered an entry point for a pack Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 97

Slide 97 text

Using javascript_pack_tag or stylesheet_pack_tag adds the pack to a page Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 98

Slide 98 text

Program note: If you have both JS and CSS in the same pack, import them both in the same .js file, and use both javascript_pack_tag and stylesheet_pack_tag to load them Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 99

Slide 99 text

Rails automatically compiles when you hit a page in development Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 100

Slide 100 text

Or you can use webpack-dev-server Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 101

Slide 101 text

Which compiles on change Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 102

Slide 102 text

And live reloads Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 103

Slide 103 text

Hands-On Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 104

Slide 104 text

Let's build a different date filter Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 105

Slide 105 text

If no dates have been clicked, all dates show If any dates have been clicked, only clicked dates show Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 106

Slide 106 text

What do we need? Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 107

Slide 107 text

• Controller • Action for each date • Action for show all • Targets for each date body • Data for current state Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 108

Slide 108 text

put the controller in the HTML Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 109

Slide 109 text

Add the targets and starting data Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 110

Slide 110 text

Add the action Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 111

Slide 111 text

Add the show all action Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 112

Slide 112 text

Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 113

Slide 113 text

Takeaways Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 114

Slide 114 text

Webpack and Webpacker are there to help you write your code the way you want... Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 115

Slide 115 text

And deliver it to the browser as needed Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 116

Slide 116 text

Stimulus is great for small JS interactions that aren't SPA worthy Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap

Slide 117

Slide 117 text

Noel Rappin (@noelrap) http://pragprog.com/book/nrtest3 (20% off with RailsConf2019_Rappin) http://stickynote.game http://techdoneright.io/46 Noel Rappin | Rails 6, Webpacker, and Stimulus | RailsConf 2019 | @noelrap