quilt_rails 1.12.1 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +31 -590
  3. data/lib/generators/quilt/USAGE +7 -0
  4. data/lib/generators/quilt/demo_app/USAGE +5 -0
  5. data/lib/generators/quilt/demo_app/demo_app_generator.rb +69 -0
  6. data/lib/generators/quilt/demo_app/templates/app-ui/components/NotFound/NotFound.tsx +28 -0
  7. data/lib/generators/quilt/demo_app/templates/app-ui/components/NotFound/illustrations/404.svg +1 -0
  8. data/lib/generators/quilt/demo_app/templates/app-ui/components/NotFound/illustrations/index.ts +1 -0
  9. data/lib/generators/quilt/demo_app/templates/app-ui/components/NotFound/index.ts +1 -0
  10. data/lib/generators/quilt/demo_app/templates/app-ui/components/index.ts +1 -0
  11. data/lib/generators/quilt/demo_app/templates/app-ui/features/Home/Home.tsx +23 -0
  12. data/lib/generators/quilt/demo_app/templates/app-ui/features/Home/illustrations/empty-state.svg +57 -0
  13. data/lib/generators/quilt/demo_app/templates/app-ui/features/Home/illustrations/index.ts +1 -0
  14. data/lib/generators/quilt/demo_app/templates/app-ui/features/Home/index.tsx +7 -0
  15. data/lib/generators/quilt/demo_app/templates/app-ui/features/Home/translations/en.json +5 -0
  16. data/lib/generators/quilt/demo_app/templates/app-ui/features/index.ts +1 -0
  17. data/lib/generators/quilt/demo_app/templates/app-ui/foundation/App.tsx +21 -0
  18. data/lib/generators/quilt/demo_app/templates/app-ui/foundation/I18n.tsx +21 -0
  19. data/lib/generators/quilt/demo_app/templates/app-ui/foundation/Polaris.tsx +24 -0
  20. data/lib/generators/quilt/demo_app/templates/app-ui/foundation/Routes.tsx +13 -0
  21. data/lib/generators/quilt/demo_app/templates/app-ui/index.ts +1 -0
  22. data/lib/generators/quilt/demo_app/templates/path_import.ts +2 -0
  23. data/lib/generators/quilt/demo_app/templates/polaris_sass_plugin.ts +10 -0
  24. data/lib/generators/quilt/install_demo_app_generator.rb +11 -0
  25. data/lib/generators/quilt/install_generator.rb +4 -46
  26. data/lib/generators/quilt/rails_setup/USAGE +5 -0
  27. data/lib/generators/quilt/rails_setup/rails_setup_generator.rb +31 -0
  28. data/lib/generators/quilt/rails_setup/templates/Procfile +2 -0
  29. data/lib/generators/quilt/{templates → rails_setup/templates}/routes.rb +0 -0
  30. data/lib/generators/quilt/react_app/USAGE +5 -0
  31. data/lib/generators/quilt/react_app/react_app_generator.rb +25 -0
  32. data/lib/generators/quilt/{templates → react_app/templates}/App.tsx +0 -0
  33. data/lib/generators/quilt/react_setup/USAGE +5 -0
  34. data/lib/generators/quilt/react_setup/react_setup_generator.rb +23 -0
  35. data/lib/generators/quilt/{templates → react_setup/templates}/tsconfig.json +5 -2
  36. data/lib/quilt_rails/performance/reportable.rb +9 -2
  37. data/lib/quilt_rails/react_renderable.rb +1 -2
  38. data/lib/quilt_rails/version.rb +1 -1
  39. metadata +33 -8
  40. data/lib/generators/sewing_kit/USAGE +0 -5
  41. data/lib/generators/sewing_kit/install_generator.rb +0 -21
  42. data/lib/generators/sewing_kit/templates/sewing-kit.config.ts +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7dd3a1819df8890a210390afc49273715e052de27f62484e194a5aa577d4783b
4
- data.tar.gz: e09486d3a9274e9ae539dfba6b533f0c1caff6a217706d990d4dd3286c9a1425
3
+ metadata.gz: e1023b00b5f569a1eaf37a6bd8c9a0ab52e3b9f69a1df57683b712e469204218
4
+ data.tar.gz: e7d6bf86ee4ce07af8e791be14bd09dc936dbededc19abf3e7a73c7797e0759f
5
5
  SHA512:
6
- metadata.gz: 6ced5760673f5410ddfb4eefdd3ab87a2708e0de26eaddce0a27e51a9a596a28b0936e18eb410ac87f175209fc039a8a46b4b106a31139b99ea331de942f7b49
7
- data.tar.gz: 1376c88df0991345ca4c05dc18e89cbcbf5f358c3c237f34eb6fc307646c38834ed19d1e35d7ee413a01672c072f50eb4715f416bf2d9deffc97fee795033610
6
+ metadata.gz: '0849412552c1c0044a747fa90691be5db225bba9daa9572571b84b00413eaf684bf307694c4ae2a92e25b22eb4901966facb033aed3a6ef1bd201d2f9c73153d'
7
+ data.tar.gz: b3da789c23e449b048ac9b728c642b3f9c2bcbd8c10430ac12fcc2ee3ad4f5298db9b796412f171735cfe73da8d10679eb7f49a7175bc99136588fd7696312a2
data/README.md CHANGED
@@ -8,55 +8,22 @@ A turn-key solution for integrating Quilt client-side libraries into your Rails
8
8
  - [Quick start](#quick-start)
9
9
  - [Generate Rails boilerplate](#generate-rails-boilerplate)
10
10
  - [Add Ruby dependencies](#add-ruby-dependencies)
11
- - [Generate Quilt boilerplate](#generate-quilt-boilerplate)
11
+ - [Generate app boilerplate](#generate-app-boilerplate)
12
12
  - [Try it out](#try-it-out)
13
13
  - [Manual Install](#manual-installation)
14
- - [Generate Rails boilerplate](#generate-rails-boilerplate)
15
- - [Install Dependencies](#install-dependencies)
16
- - [Setup the Rails app](#setup-the-rails-app)
17
- - [Add JavaScript](#add-javascript)
18
- - [Run the server](#run-the-server)
19
14
  - [Application Layout](#application-layout)
20
15
  - [Advanced Use](#advanced-use)
21
16
  - [Testing](#testing)
22
17
  - [Interacting with the request and response in React code](#interacting-with-the-request-and-response-in-react-code)
23
18
  - [Dealing with isomorphic state](#dealing-with-isomorphic-state)
24
- - [Customizing the node server](#customizing-the-node-server)
19
+ - [Customizing the Node server](#customizing-the-node-server)
25
20
  - [Fixing rejected CSRF tokens for new user sessions](#fixing-rejected-csrf-tokens-for-new-user-sessions)
26
21
  - [Performance tracking a React app](#performance-tracking-a-react-app)
27
- - [Install dependencies](#install-dependencies)
28
- - [Setup an endpoint for performance reports](setup-an-endpoint-for-performance-reports)
29
- - [Add annotations](#add-annotations)
30
- - [Send the report](#send-the-report)
31
- - [Verify in development](#verify-in-development)
32
- - [Configure StatsD for production](#configure-statsd-for-production)
33
22
  - [API](#api)
34
- - [ReactRenderable](#reactrenderable)
35
- - [Performance](#performance)
36
- - [Engine](#engine)
37
- - [Generators](#generators)
38
23
 
39
24
  ## Server-side-rendering
40
25
 
41
- ### Alpha functionality - do not use in high-traffic production applications
42
-
43
- **Warning:** quilt_rails's server-side-rendering module `ReactRenderable` does not work at scale. Improvements to its architecture are being investigated. In its current state, it can be used for:
44
-
45
- - Workshop applications
46
- - Proof of concept applications
47
- - Low traffic applications
48
-
49
- For a description of the current architecture's problems, see [this Github comment](https://github.com/Shopify/quilt/issues/1059#issuecomment-539195340).
50
-
51
- The ["decide on a scalable quilt_rails architecture" issue](https://github.com/Shopify/quilt/issues/1100) will track discussion of future architectures.
52
-
53
- To scale up existing quilt_rails applications, skip server-side queries in your components. e.g.:
54
-
55
- ```ts
56
- useQuery(MyQuery, {
57
- skip: typeof document === 'undefined',
58
- });
59
- ```
26
+ 🗒 This guide is focused on internal Shopify developers with access [@shopify/sewing-kit](https://github.com/Shopify/sewing-kit). A similar setup can be achieved using the [manual installation](./docs/manual-installation.md) , and following the [react-server webpack plugin](../../packages/react-server/README.md#webpack-plugin) guide. Apps not running on Shopify infrastructure should [disable server-side GraphQL queries](./docs/FAQ.md) to avoid scalability issue.
60
27
 
61
28
  ### Quick start
62
29
 
@@ -64,9 +31,7 @@ Using the magic of generators, we can spin up a basic app with a few console com
64
31
 
65
32
  #### Generate Rails boilerplate
66
33
 
67
- `dev init`
68
-
69
- When prompted, choose `rails`. This will generate a basic Rails application scaffold.
34
+ Use [`rails new . --skip-javascript`](https://guides.rubyonrails.org/command_line.html#rails-new) to scaffold out a Rails application.to do the same.
70
35
 
71
36
  #### Add Ruby dependencies
72
37
 
@@ -74,190 +39,29 @@ When prompted, choose `rails`. This will generate a basic Rails application scaf
74
39
 
75
40
  This will install our ruby dependencies and update the project's gemfile.
76
41
 
77
- #### Generate Quilt boilerplate
78
-
79
- `rails generate quilt:install`
80
-
81
- This will install the Node dependencies, provide a basic React app (in TypeScript) and mounts the Quilt engine inside of `config/routes.rb`.
82
-
83
- #### Try it out
84
-
85
- ```sh
86
- dev up
87
- dev server
88
- ```
89
-
90
- Will run the application, starting up both servers and compiling assets.
91
-
92
- ### Manual installation
93
-
94
- An application can also be setup manually using the following steps.
42
+ #### Generate app boilerplate
95
43
 
96
- [Generate Rails boilerplate](#generate-rails-boilerplate)
44
+ `rails generate sewing_kit:install`
97
45
 
98
- #### Install dependencies
99
-
100
- ```sh
101
- # Add ruby dependencies
102
- bundle add sewing_kit quilt_rails
46
+ This will generate a package.json file with common sewing-kit script tasks, default lint, format configuration; a sewing-kit configuration file, and other project default configurations.
103
47
 
104
- # Add core Node dependencies
105
- yarn add @shopify/sewing-kit @shopify/react-server
48
+ `rails generate quilt::install_demo_app`
106
49
 
107
- # Add React
108
- yarn add react react-dom
50
+ Both command will install Node dependencies, mount the Quilt engine in `config/routes.rb`, set up basic linting and format configurations, and provide a demo React app (in TypeScript) that uses all of quilt toolings and is a more complete example of a typical application.
109
51
 
110
- # Add Typescript
111
- yarn add typescript @types/react @types/react-dom
112
- ```
52
+ If you prefer to setup all of the React app yourself, `rails generate quilt:install` does the same as above but with a bare bone React app.
113
53
 
114
- ##### Define typescript config
115
-
116
- ```json
117
- // tsconfig.json
118
- {
119
- "extends": "@shopify/typescript-configs/application.json",
120
- "compilerOptions": {
121
- "baseUrl": ".",
122
- "rootDir": "."
123
- },
124
- "include": ["app/ui"]
125
- }
126
- ```
54
+ #### Try it out
127
55
 
128
56
  ```sh
129
- yarn
130
- dev up
57
+ bin/rails server
131
58
  ```
132
59
 
133
- #### Setup the Rails app
134
-
135
- There are 2 ways to consume this package.
136
-
137
- ##### Option 1: Mount the Engine
138
-
139
- Add the engine to `routes.rb`.
140
-
141
- ```ruby
142
- # config/routes.rb
143
- Rails.application.routes.draw do
144
- # ...
145
- mount Quilt::Engine, at: '/'
146
- end
147
- ```
148
-
149
- If only a sub-section of routes should respond with the React App, it can be configured using the `at` parameter.
150
-
151
- ```ruby
152
- # config/routes.rb
153
- Rails.application.routes.draw do
154
- # ...
155
- mount Quilt::Engine, at: '/path/to/react'
156
- end
157
- ```
158
-
159
- ##### Option 2: Add a React controller and routes
160
-
161
- Create a `ReactController` to handle react requests.
162
-
163
- ```ruby
164
- class ReactController < ApplicationController
165
- include Quilt::ReactRenderable
166
-
167
- def index
168
- render_react
169
- end
170
- end
171
- ```
172
-
173
- Add routes to default to the `ReactController`.
174
-
175
- ```ruby
176
- get '/*path', to: 'react#index'
177
- root 'react#index'
178
- ```
179
-
180
- #### Add JavaScript
181
-
182
- `sewing_kit` looks for the top level component of your React app in `app/ui/index`. The component exported from this component (and any imported JS/CSS) will be built into a `main` bundle, and used to render the initial server-rendered markup.
183
-
184
- We will add a basic entrypoint using React with some HTML.
185
-
186
- ```tsx
187
- // app/ui/index.tsx
188
-
189
- import React from 'react';
190
-
191
- function App() {
192
- return <h1>My application ❤️</h1>;
193
- }
194
-
195
- export default App;
196
- ```
197
-
198
- #### Run the server
199
-
200
- `dev server`
201
-
202
60
  Will run the application, starting up both servers and compiling assets.
203
61
 
204
- ### Application layout
205
-
206
- #### Minimal
207
-
208
- The basic layout for an app using `quilt_rails` and friends will have a `ui` folder nested inside the normal Rails `app` folder, containing at _least_ an index.js file exporting a React component.
209
-
210
- ```
211
- ├── Gemfile (must contain "gem 'sewing_kit" and "gem 'quilt_rails'")
212
- ├── package.json (must specify '@shopify/sewing-kit' and `@shopify/react-server` as 'dependencies')
213
-
214
- └── app
215
- └── ui
216
- │ └─- index.{js|ts} (exports a React component)
217
- └── controllers
218
- └─- react_controller.rb (see above)
219
- ```
220
-
221
- #### Rails and React
222
-
223
- A more complex application will want a more complex layout. The following shows scalable locations for:
224
-
225
- - Global SCSS settings
226
- - App sections (roughly analogous to Rails routes)
227
- - Components
228
- - Co-located CSS modules
229
- - Co-located unit tests
230
- - Test setup files
62
+ ### Manual installation
231
63
 
232
- ```
233
- └── app
234
- └── ui
235
- ├─- index.{js|ts} (exports a React component)
236
- ├── styles (optional)
237
- └── shared.scss (common functions/mixins you want available in every scss file. Requires configuring `plugin.sass`'s `autoInclude` option in `sewing-kit.config.js`)
238
-
239
- └── tests (optional)
240
- │ └── each-test.{js|ts}
241
- │ └── setup.{js|ts}
242
- └── features (optional)
243
- ├── App
244
- │ ├── index.{js|ts}
245
- │ ├── App.{js|ts}x
246
- │ └── tests
247
- │ └── App.test.{js|ts}x
248
-
249
- ├-─ MyComponent
250
- │ ├-─ index.{js|ts}
251
- │ ├-─ MyComponent.{js|ts}x
252
- │ ├── MyComponent.scss (optional; component-scoped CSS styles, mixins, etc)
253
- │ └── tests
254
- │ └── MyComponent.test.{js|ts}x
255
-
256
- └── sections (optional; container views that compose presentation components into UI blocks)
257
- └── Home
258
- ├-─ index.{js|ts}
259
- └── Home.{js|ts}
260
- ```
64
+ Follow [this guide](./docs/manual-installation.md) on how to do manual setup without the generator.
261
65
 
262
66
  ### Advanced use
263
67
 
@@ -343,6 +147,8 @@ class ReactController < ApplicationController
343
147
  end
344
148
  ```
345
149
 
150
+ 🗒️ if you don't have a controller. Follow the [instruction](./docs/manual-installation#add-a-react-controller-and-routes) to setup `quilt_rails` in a controller instead of using the engine.
151
+
346
152
  Headers can be accessed during server-side-rendering with the `useRequestHeader` hook from `@shopify/react-network`.
347
153
 
348
154
  ```tsx
@@ -375,30 +181,9 @@ class ReactController < ApplicationController
375
181
  end
376
182
  ```
377
183
 
378
- The React server will serialize the provided quilt data using `quilt-data` as the ID. You can then get this serialized data on the client with `getSerialized` from `@shopify/react-html`.
379
-
380
- ```tsx
381
- // app/ui/index.tsx
382
-
383
- import React from 'react';
384
- import {getSerialized} from '@shopify/react-html';
385
-
386
- const IS_CLIENT = typeof window !== 'undefined';
387
-
388
- function App() {
389
- // get the serialized data from the request that was sent through Rails ReactController
390
- const quiltData = IS_CLIENT ? getSerialized<Record<string, any>>('quilt-data') : null;
391
-
392
- // Logs {"some_id":123}
393
- console.log(quiltData);
394
-
395
- return <h1>Data: {quiltData}</h1>;
396
- }
397
-
398
- export default App;
399
- ```
184
+ 🗒️ if you don't have a controller. Follow the [instruction](./docs/manual-installation#add-a-react-controller-and-routes) to setup `quilt_rails` in a controller instead of using the engine.
400
185
 
401
- If using the webpack plugin, this will be done automatically and the data will be passed into your application as the `data` prop.
186
+ If using `react-server` without a customized server & client file, this will be automatically passed into your application as the `data` prop. If `react-server` is not being used or a customized server / client file was provided, check out [`react-server/webpack-plugin`](../../packages/react-server/src/webpack-plugin/webpack-plugin.ts) on how to pass the data to React.
402
187
 
403
188
  ```tsx
404
189
  // app/ui/index.tsx
@@ -437,11 +222,11 @@ export default App;
437
222
 
438
223
  With SSR enabled React apps, state must be serialized on the server and deserialized on the client to keep it consistent. When using `@shopify/react-server`, the best tool for this job is [`@shopify/react-html`](https://github.com/Shopify/quilt/tree/master/packages/react-html)'s [`useSerialized`](https://github.com/Shopify/quilt/tree/master/packages/react-html#in-your-application-code) hook.
439
224
 
440
- `useSerialized` can be used to implement [universal-providers](https://github.com/Shopify/quilt/tree/master/packages/react-universal-provider#what-is-a-universal-provider-), allowing application code to manage what is persisted between the server and client without adding any custom code to client or server entrypoints. We offer some for common use cases such as [CSRF](https://github.com/Shopify/quilt/tree/master/packages/react-csrf-universal-provider), [GraphQL](https://github.com/Shopify/quilt/tree/master/packages/react-graphql-universal-provider), [I18n](https://github.com/Shopify/quilt/tree/master/packages/react-i18n-universal-provider), and the [Shopify App Bridge](https://github.com/Shopify/quilt/tree/master/packages/react-app-bridge-universal-provider).
225
+ `useSerialized` can be used to implement [universal-providers](https://github.com/Shopify/quilt/tree/master/packages/react-universal-provider#what-is-a-universal-provider-), allowing application code to manage what is persisted between the server and client without adding any custom code to client or server entrypoints. We offer some for common use cases such as [GraphQL](https://github.com/Shopify/quilt/tree/master/packages/react-graphql-universal-provider), and [I18n](https://github.com/Shopify/quilt/tree/master/packages/react-i18n-universal-provider).
441
226
 
442
- #### Customizing the node server
227
+ #### Customizing the Node server
443
228
 
444
- By default, sewing-kit bundles in [`@shopify/react-server-webpack-plugin`](../../packages/react-server-webpack-plugin/README.md) for `quilt_rails` applications to get apps up and running fast without needing to manually write any node server code.
229
+ By default, sewing-kit bundles in [`@shopify/react-server/webpack-plugin`](../../packages/react-server/README.md#webpack-plugin) for `quilt_rails` applications to get apps up and running fast without needing to manually write any Node server code.
445
230
 
446
231
  If what it provides is not sufficient, a completely custom server can be defined by adding a `server.js` or `server.ts` file to the `app/ui` folder. The simplest way to customize the server is to export the object created by [`@shopify/react-server`](../../packages/react-server/README.md#node-usage)'s `createServer` call in `server.ts` file.
447
232
 
@@ -459,6 +244,10 @@ When a React component sends HTTP requests back to a Rails endpoint (e.g., `/gra
459
244
 
460
245
  If your API **does not** require session data, the easiest way to deal with this is to use `protect_from_forgery with: :null_session`. This will work for APIs that either have no authentication requirements, or use header based authentication.
461
246
 
247
+ While `Can't verify CSRF token authenticity` error will persist, `protect_from_forgery with: :null_session` will keep CSRF protection while ensuring the session is nullified when a token is not sent in to be more secure.
248
+
249
+ You can also add `self.log_warning_on_csrf_failure = false` to the controller to suppress this error all together.
250
+
462
251
  ##### Example
463
252
 
464
253
  ```rb
@@ -478,7 +267,7 @@ end
478
267
  If your API **does** require session data, you can follow these steps:
479
268
 
480
269
  - Add an `x-shopify-react-xhr` header to all GraphQL requests with a value of 1 (this is done automatically if you are using `@shopify/react-graphql-universal-provider`)
481
- - Add a `protect_from_forgery with: Quilt::HeaderCsrfStrategy` override to your controllers
270
+ - Add a `protect_from_forgery with: Quilt::HeaderCsrfStrategy` override to your API controllers
482
271
 
483
272
  ##### Example
484
273
 
@@ -498,361 +287,13 @@ end
498
287
 
499
288
  ## Performance tracking a React app
500
289
 
501
- Using [`Quilt::Performance::Reportable`](#performanceReportable) and [@shopify/react-performance](https://www.npmjs.com/package/@shopify/react-performance) it's easy to add performance tracking to apps using[`sewing_kit`](https://github.com/Shopify/sewing-kit/tree/master/gems/sewing_kit#sewing_kit-) for client-side-rendering or `quilt_rails` for server-side-rendering.
502
-
503
- ### Install dependencies
504
-
505
- 1. Install the gem (if your app is not already using `quilt_rails`).
506
-
507
- ```bash
508
- bundle add quilt_rails
509
- ```
510
-
511
- 2. Install `@shopify/react-performance`, the library we will use to annotate our React application and send performance reports to our server.
512
-
513
- ```bash
514
- yarn add @shopify/react-performance
515
- ```
516
-
517
- ### Setup an endpoint for performance reports
518
-
519
- If your application is not using `Quilt::Engine`, you will need to manually configure the server-side portion of performance tracking. If it _is_ using the engine, the following will be done automatically.
520
-
521
- 1. Add a `PerformanceController` and the corresponding routes to your Rails app.
522
-
523
- ```ruby
524
- # app/controllers/performance_report_controller.rb
525
-
526
- class PerformanceReportController < ActionController::Base
527
- include Quilt::Performance::Reportable
528
- protect_from_forgery with: :null_session
529
-
530
- def create
531
- process_report
532
-
533
- render(json: { result: 'success' }, status: 200)
534
- rescue ActionController::ParameterMissing => error
535
- render(json: { error: error.message }, status: 422)
536
- end
537
- end
538
- ```
539
-
540
- 2. Add a route pointing at the controller.
541
-
542
- ```ruby
543
- # config/routes.rb
544
-
545
- post '/performance_report', to: 'performance_report#create'
546
-
547
- # rest of routes
548
- ```
549
-
550
- ### Add annotations
551
-
552
- Add a [`usePerformanceMark`](https://github.com/Shopify/quilt/tree/master/packages/react-performance#useperformancemark) call to each of your route-level components.
553
-
554
- ```tsx
555
- // app/ui/features/Home/Home.tsx
556
- import {usePerformanceMark} from '@shopify/react-performance';
557
-
558
- export function Home() {
559
- // tell the library the page has finished rendering completely
560
- usePerformanceMark('complete', 'Home');
561
-
562
- return <>{/* your Home page JSX goes here*/}</>;
563
- }
564
- ```
565
-
566
- ### Send the report
567
-
568
- Add a [`usePerformanceReport`](https://github.com/Shopify/quilt/tree/master/packages/react-performance#usePerformanceReport) call to your top-level `<App />` component.
569
-
570
- ```tsx
571
- // app/ui/foundation/App/App.tsx
572
- import {usePerformanceReport} from '@shopify/react-performance';
573
-
574
- export function App() {
575
- // send the report to the server
576
- usePerformanceReport('/performance_report');
577
-
578
- return <>{/* your app JSX goes here*/}</>;
579
- }
580
- ```
581
-
582
- For more details on how to use the APIs from `@shopify/react-performance` check out its [documentation](https://github.com/Shopify/quilt/tree/master/packages/react-performance).
583
-
584
- ### Verify in development
585
-
586
- By default `quilt_rails` will not send metrics in development mode. To verify your app is setup correctly you can check in your network tab when visiting your application and see that POST requests are sent to `/performance_report`, and recieve a `200 OK` response.
587
-
588
- If you want more insight into what distributions _would_ be sent in production, you can use the `on_distribution` callback provided by the library to setup logging.
589
-
590
- ```ruby
591
- # app/controllers/performance_report_controller.rb
592
-
593
- class PerformanceReportController < ActionController::Base
594
- include Quilt::Performance::Reportable
595
- protect_from_forgery with: :null_session
596
-
597
- def create
598
- # customize process_report's behaviour with a block
599
- process_report do |client|
600
- client.on_distribution do |name, value, tags|
601
- # We log out the details of each distribution that would be sent in production.
602
- Rails.logger.debug("Distribution: #{name}, #{value}, #{tags}")
603
- end
604
- end
605
-
606
- render json: { result: 'success' }, status: 200
607
- rescue ActionController::ParameterMissing => error
608
- render json: { error: error.message, status: 422 }
609
- end
610
- end
611
- ```
612
-
613
- Now you can check your Rails console output and verify that metrics are reported as expected.
614
-
615
- ### Configure StatsD for production
616
-
617
- > Attention Shopifolk! If using `dev` your `StatsD` endpoint will already be configured for you in production. You should not need to do the following. ✨
618
-
619
- To tell `Quilt::Performance::Reportable` where to send it's distributions, setup the environment variables detailed [documentation](https://github.com/Shopify/statsd-instrument#configuration).
290
+ To setup performance tracking with your React app with `quilt_rails`.
291
+ Follow details guide [here](./docs/performance-tracking.md).
620
292
 
621
293
  ## API
622
294
 
623
- ### ReactRenderable
624
-
625
- The `ReactRenderable` mixin is intended to be used in Rails controllers, and provides only the `render_react` method. This method handles proxying to a running `@shopify/react-server`.
626
-
627
- ```ruby
628
- class ReactController < ApplicationController
629
- include Quilt::ReactRenderable
630
-
631
- def index
632
- render_react
633
- end
634
- end
635
- ```
636
-
637
- ### Performance
638
-
639
- #### Reportable
640
-
641
- The `Quilt::Performance::Reportable` mixin is intended to be used in Rails controllers, and provides only the `process_report` method. This method handles parsing an incoming report from [@shopify/react-performance's](https://www.npmjs.com/package/@shopify/react-performance) `<PerformanceReport />` component (or a custom report in the same format) and sending it to your application's StatsD endpoint as `distribution`s using [`StatsD-Instrument`](https://rubygems.org/gems/statsd-instrument).
642
-
643
- > **Note** `Quilt::Performance::Reportable` does not require you to use the `React::Renderable` mixin, React-Server, or even any server-side-rendering solution at all. It should work perfectly fine for applications using something like `sewing_kit_script_tag` based client-side-rendering.
644
-
645
- ```ruby
646
- class PerformanceController < ApplicationController
647
- include Quilt::Performance::Reportable
648
-
649
- def create
650
- process_report
651
- end
652
- end
653
- ```
654
-
655
- The params sent to the controller are expected to be of type `application/json`. Given the following example JSON sent by `@shopify/react-performance`,
656
-
657
- ```json
658
- {
659
- "connection": {
660
- "rtt": 100,
661
- "downlink": 2,
662
- "effectiveType": "3g",
663
- "type": "4g"
664
- },
665
- "navigations": [
666
- {
667
- "details": {
668
- "start": 12312312,
669
- "duration": 23924,
670
- "target": "/",
671
- "events": [
672
- {
673
- "type": "script",
674
- "start": 23123,
675
- "duration": 124
676
- },
677
- {
678
- "type": "style",
679
- "start": 23,
680
- "duration": 14
681
- }
682
- ],
683
- "result": 0
684
- },
685
- "metadata": {
686
- "index": 0,
687
- "supportsDetailedTime": true,
688
- "supportsDetailedEvents": true
689
- }
690
- }
691
- ],
692
- "events": [
693
- {
694
- "type": "ttfb",
695
- "start": 2,
696
- "duration": 1000
697
- }
698
- ]
699
- }
700
- ```
701
-
702
- given the the above controller input, the library would send the following metrics:
703
-
704
- ```ruby
705
- StatsD.distribution('time_to_first_byte', 2, tags: {
706
- browser_connection_type:'3g',
707
- })
708
- StatsD.distribution('time_to_first_byte', 2, tags: {
709
- browser_connection_type:'3g' ,
710
- })
711
- StatsD.distribution('navigation_complete', 23924, tags: {
712
- browser_connection_type:'3g' ,
713
- })
714
- StatsD.distribution('navigation_usable', 23924, tags: {
715
- browser_connection_type:'3g' ,
716
- })
717
- ```
718
-
719
- ##### Default Metrics
720
-
721
- The full list of metrics sent by default are as follows:
722
-
723
- ###### For full-page load
724
-
725
- - `AppName.time_to_first_byte`, representing the time from the start of the request to when the server began responding with data.
726
- - `AppName.time_to_first_paint`, representing the time from the start of the request to when the browser rendered anything to the screen.
727
- - `AppName.time_to_first_contentful_paint` representing the time from the start of the request to when the browser rendered meaningful content to the screen.
728
- - `AppName.dom_content_loaded` representing the time from the start of the request to when the browser fired the [DOMContentLoaded](https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event) event.
729
- - `AppName.dom_load` representing the time from the start of the request to when the browser fired the [window.load](https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event) event.
730
-
731
- ###### For both full-page navigations and client-side page transitions
732
-
733
- - `AppName.navigation_usable`, representing the time it took before for the page to be rendered in a usable state. Usually this does not include data fetching or asynchronous tasks.
734
- - `AppName.navigation_complete` representing the time it took for the page to be fully loaded, including any data fetching which blocks above-the-fold content.
735
- - `AppName.navigation_download_size`, representing the total weight of all client-side assets (eg. CSS, JS, images). This will only be sent if there are any events with a `type` of `script` or `style`.
736
- - `AppName.navigation_cache_effectiveness`, representing what percentage of client-side assets (eg. CSS, JS, images) were returned from the browser's cache. This will only be sent if there are any events with a `type` of `script` or `style`.
737
-
738
- ##### Customizing `process_report` with a block
739
-
740
- The behaviour of `process_report` can be customized by manipulating the `Quilt::Performance::Client` instance yielded into its implicit block parameter.
741
-
742
- ```ruby
743
- process_report do |client|
744
- # client.on_distribution do ....
745
- end
746
- ```
747
-
748
- #### Client
749
-
750
- The `Quilt::Performance::Client` class is yielded into the block parameter for `process_report`, and is the primary API for customizing what metrics are sent for a given POST.
751
-
752
- ##### Client#on_distribution
753
-
754
- The `on_distribution` method takes a block which is run for each distribution (including custom ones) sent during `process_report`.
755
-
756
- The provided callback can be used to easily add logging or other side-effects to your measurements.
757
-
758
- ```ruby
759
- client.on_distribution do |metric_name, value, tags|
760
- Rails.logger.debug "#{metric_name}: #{value}, tags: #{tags}"
761
- end
762
- ```
763
-
764
- ##### Client#on_navigation
765
-
766
- The `on_navigation` method takes a block which is run once per navigation reported to the performance controller _before_ the default distributions for the navigation are sent.
767
-
768
- The provided callback can be used to add tags to the default `distributions` for a given navigation.
769
-
770
- ```ruby
771
- client.on_navigation do |navigation, tags|
772
- # add tags to be sent with each distribution for this navigation
773
- tags[:connection_rtt] = navigation.connection.rtt
774
- tags[:connection_type] = navigation.connection.type
775
- tags[:navigation_target] = navigation.target
776
-
777
- # add a tag to allow filtering out navigations that are too long
778
- # this is useful when you are unable to rule out missing performance marks on some pages
779
- tags[:too_long_dont_read] = navigation.duration > 30.seconds.in_milliseconds
780
- end
781
- ```
782
-
783
- It can also be used to compute and send entirely custom metrics.
784
-
785
- ```ruby
786
- client.on_navigation do |navigation, tags|
787
- # calculate and then send an additional distribution
788
- weight = navigation.events_with_size.reduce(0) do |total, event|
789
- total + event.size
790
- end
791
- client.distribution('navigation_total_resource_weight', weight, tags)
792
- end
793
- ```
794
-
795
- ##### Client#on_event
796
-
797
- The `on_event` method takes a block which is run once per event reported to the performance controller _before_ the default distributions for the event are sent.
798
-
799
- The provided callback can be used to add tags to the default `distributions` for a given event, or perform other side-effects.
800
-
801
- ```ruby
802
- client.on_event do |event, tags|
803
- # add tags to be sent with each distribution for this event
804
- tags[:connection_rtt] = event.connection.rtt
805
- tags[:connection_type] = event.connection.type
806
- end
807
- ```
808
-
809
- ### Engine
810
-
811
- `Quilt::Engine` provides:
812
-
813
- - a preconfigured `UiController` which consumes `ReactRenderable`
814
- - a preconfigured `PerformanceReportController` which consumes `Performance::Reportable`
815
- - a `/performance_report` route mapped to `performance_report#index`
816
- - a catch-all index route mapped to the `UiController#index`
817
-
818
- ```ruby
819
- # config/routes.rb
820
- Rails.application.routes.draw do
821
- # ...
822
- mount Quilt::Engine, at: '/my-front-end'
823
- end
824
- ```
825
-
826
- The above is the equivalent of
827
-
828
- ```ruby
829
- post '/my-front-end/performance_report', to: 'performance_report#create'
830
- get '/my-front-end/*path', to: 'ui#index'
831
- get '/my-front-end', to: 'ui#index'
832
- ```
833
-
834
- ### Configuration
835
-
836
- The `configure` method allows customization of the address the service will proxy to for UI rendering.
837
-
838
- ```ruby
839
- # config/initializers/quilt.rb
840
- Quilt.configure do |config|
841
- config.react_server_host = "localhost:3000"
842
- config.react_server_protocol = 'https'
843
- end
844
- ```
845
-
846
- ### StatsD environment variables
847
-
848
- The `Performance::Reportable` mixin uses [https://github.com/Shopify/statsd-instrument](StatsD-Instrument) to send distributions. For detailed instructions on configuring where it sends data see [the documentation](https://github.com/Shopify/statsd-instrument#configuration).
849
-
850
- ### Generators
851
-
852
- #### `quilt:install`
853
-
854
- Installs the Node dependencies, provide a basic React app (in TypeScript) and mounts the Quilt engine in `config/routes.rb`.
295
+ Find all features this gem offer in this [API doc](./docs/api.md).
855
296
 
856
- #### `sewing_kit:install`
297
+ ## FAQ
857
298
 
858
- Adds a basic `sewing-kit.config.ts` file.
299
+ Find your [here](./docs/FAQ.md).