jekyll-theme-alta-docs 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/_includes/guidelines/rails/api_only_project_tree.md +90 -0
- data/_includes/guidelines/rails/api_only_project_tree_with_files.md +56 -0
- data/_includes/guidelines/rails/api_only_psql_no_admin_setup_instructions.md +236 -0
- data/_includes/guidelines/rails/rails_cheatsheet.md +275 -0
- data/_includes/guidelines/react/react_csr_setup_instructions.md +600 -0
- data/_includes/guidelines/react/react_guidelines.md +443 -0
- data/_includes/guidelines/react/react_project_tree.md +99 -0
- data/_includes/nav.html +24 -1
- data/_includes/templates/rails/rails_readme.md +52 -0
- data/_includes/templates/react/react_readme.md +54 -0
- data/_sass/jekyll-theme-alta-docs.scss +77 -3
- metadata +11 -2
@@ -0,0 +1,600 @@
|
|
1
|
+
{% assign project_name = 'project-name' %}
|
2
|
+
{% if include.project_name %}
|
3
|
+
{% assign project_name = include.project_name %}
|
4
|
+
{% endif %}
|
5
|
+
|
6
|
+
*Node: 10.16.0, Yarn: 1.21.1, NPM: 6.9.0, NPX: 6.9.0*
|
7
|
+
|
8
|
+
**Purpose:** Create-react-app (Client Side Rendering)
|
9
|
+
|
10
|
+
### Prerequisites
|
11
|
+
|
12
|
+
* Node installed
|
13
|
+
* Yarn, NPM or NPX installed
|
14
|
+
|
15
|
+
### A) Create project with Create-react-app
|
16
|
+
|
17
|
+
1. Run:
|
18
|
+
|
19
|
+
$ npx create-react-app {{ project_name }}-web
|
20
|
+
|
21
|
+
# ...OR...
|
22
|
+
$ yarn create react-app {{ project_name }}-web
|
23
|
+
|
24
|
+
# ...OR
|
25
|
+
$ npm init react-app {{ project_name }}-web
|
26
|
+
|
27
|
+
2. Go to the project folder:
|
28
|
+
|
29
|
+
$ cd {{ project_name }}-web
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
### B) Setup project tree
|
34
|
+
|
35
|
+
The example of the project tree. The final outcome depends on the project needs.
|
36
|
+
|
37
|
+
{% include guidelines/react/react_project_tree.md %}
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
#### 1. Config
|
42
|
+
|
43
|
+
Create folder `src/config` and add `src/config/app.js` file:
|
44
|
+
|
45
|
+
```javascript
|
46
|
+
const prod = {
|
47
|
+
API_URL: 'https://domain.com/api/v1/'
|
48
|
+
}
|
49
|
+
|
50
|
+
const dev = {
|
51
|
+
API_URL: 'http://xxx.xxx.xx.xx:4000/api/v1/'
|
52
|
+
}
|
53
|
+
|
54
|
+
const config = process.env.NODE_ENV === 'production'
|
55
|
+
? prod
|
56
|
+
: dev
|
57
|
+
|
58
|
+
// const EXAMPLE_VAR = 'xxx'
|
59
|
+
|
60
|
+
export default {
|
61
|
+
...config,
|
62
|
+
// EXAMPLE_VAR,
|
63
|
+
}
|
64
|
+
```
|
65
|
+
|
66
|
+
#### 2. Add basic folders to the project tree
|
67
|
+
|
68
|
+
```
|
69
|
+
|--src
|
70
|
+
|-- assets
|
71
|
+
| |-- images
|
72
|
+
| |-- .keep
|
73
|
+
|
|
74
|
+
|-- components
|
75
|
+
| |-- UI
|
76
|
+
| |-- .keep
|
77
|
+
|
|
78
|
+
|-- containers
|
79
|
+
| |-- .keep
|
80
|
+
|
|
81
|
+
|-- helpers
|
82
|
+
| |-- .keep
|
83
|
+
|
|
84
|
+
|-- layouts
|
85
|
+
| |-- .keep
|
86
|
+
|
|
87
|
+
|-- models
|
88
|
+
| |-- .keep
|
89
|
+
|
|
90
|
+
|-- modules
|
91
|
+
| |-- .keep
|
92
|
+
|
|
93
|
+
|-- services
|
94
|
+
|-- .keep
|
95
|
+
```
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
#### 3. Add Routes and set up App.jsx
|
100
|
+
|
101
|
+
Install:
|
102
|
+
|
103
|
+
```bash
|
104
|
+
$ yarn add react-router-dom
|
105
|
+
```
|
106
|
+
|
107
|
+
Create `src/routes` folder and add `src/routes/routes.jsx` file:
|
108
|
+
|
109
|
+
```javascript
|
110
|
+
import React from 'react'
|
111
|
+
import {
|
112
|
+
Route,
|
113
|
+
Switch
|
114
|
+
} from 'react-router'
|
115
|
+
import HomeRoute from './home/HomeRoute'
|
116
|
+
|
117
|
+
const routes = (
|
118
|
+
<Switch>
|
119
|
+
<Route exact path='/' component={HomeRoute} />
|
120
|
+
</Switch>
|
121
|
+
)
|
122
|
+
|
123
|
+
export default routes
|
124
|
+
```
|
125
|
+
|
126
|
+
Add file `src/routes/home/HomeRoute.jsx`:
|
127
|
+
|
128
|
+
```javascript
|
129
|
+
import React from 'react'
|
130
|
+
|
131
|
+
const Home = () => (
|
132
|
+
<div>
|
133
|
+
<h1>Home page</h1>
|
134
|
+
</div>
|
135
|
+
)
|
136
|
+
|
137
|
+
export default Home
|
138
|
+
```
|
139
|
+
|
140
|
+
Add `src/history.js`:
|
141
|
+
|
142
|
+
```javascript
|
143
|
+
import { createBrowserHistory } from 'history'
|
144
|
+
|
145
|
+
export default createBrowserHistory()
|
146
|
+
```
|
147
|
+
|
148
|
+
|
149
|
+
Edit `src/App.jsx`:
|
150
|
+
|
151
|
+
```javascript
|
152
|
+
import React, {
|
153
|
+
useState,
|
154
|
+
useEffect,
|
155
|
+
} from 'react'
|
156
|
+
import PropTypes from 'prop-types'
|
157
|
+
import { Router } from 'react-router'
|
158
|
+
import routes from './routes/routes'
|
159
|
+
import history from './history'
|
160
|
+
import './App.css'
|
161
|
+
|
162
|
+
function App() {
|
163
|
+
return (
|
164
|
+
<div className='app'>
|
165
|
+
<Router history={history}>
|
166
|
+
{routes}
|
167
|
+
</Router>
|
168
|
+
</div>
|
169
|
+
)
|
170
|
+
}
|
171
|
+
|
172
|
+
export default App
|
173
|
+
```
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
#### 4. Add initialization script
|
180
|
+
|
181
|
+
Add file `src/Init.js`:
|
182
|
+
|
183
|
+
```javascript
|
184
|
+
/**
|
185
|
+
* Initialization script loading functions in a sequence.
|
186
|
+
*
|
187
|
+
* Statuses:
|
188
|
+
* 0 - sequence has been halted. It may mean that there was an error during initialization
|
189
|
+
* 1 - initialized with success.
|
190
|
+
* 2 - redirection
|
191
|
+
*
|
192
|
+
* @returns {{status: number, message: string, data: Object }}
|
193
|
+
*/
|
194
|
+
class Init {
|
195
|
+
static init() {
|
196
|
+
return this.firstFunction()
|
197
|
+
}
|
198
|
+
|
199
|
+
static async firstFunction() {
|
200
|
+
if (true) {
|
201
|
+
return this.secondFunction()
|
202
|
+
}
|
203
|
+
return {
|
204
|
+
status: 0,
|
205
|
+
message: 'APP_INITIALIZATION_FAILED',
|
206
|
+
}
|
207
|
+
}
|
208
|
+
|
209
|
+
static async secondFunction() {
|
210
|
+
return {
|
211
|
+
status: 0,
|
212
|
+
message: 'SUCCESS',
|
213
|
+
data: { a: 1, b: 2 }
|
214
|
+
}
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
218
|
+
export default Init
|
219
|
+
```
|
220
|
+
|
221
|
+
Add the Init to the `src/App.jsx`:
|
222
|
+
|
223
|
+
```javascript
|
224
|
+
import Init from './Init.js'
|
225
|
+
|
226
|
+
function App() {
|
227
|
+
const [initPerformed, setInitPerformed] = useState(false)
|
228
|
+
useEffect(() => {
|
229
|
+
if (!initPerformed) {
|
230
|
+
initializeApp()
|
231
|
+
}
|
232
|
+
}, [initPerformed])
|
233
|
+
|
234
|
+
async function initializeApp() {
|
235
|
+
await Init.init()
|
236
|
+
// OR:
|
237
|
+
// const response = await Init.init()
|
238
|
+
// Do something with response.. (i.e. Set Redux)
|
239
|
+
setInitPerformed(true)
|
240
|
+
}
|
241
|
+
|
242
|
+
(...)
|
243
|
+
}
|
244
|
+
```
|
245
|
+
|
246
|
+
|
247
|
+
#### 5. Add I18n
|
248
|
+
|
249
|
+
Install:
|
250
|
+
|
251
|
+
```bash
|
252
|
+
$ yarn add react-i18next i18next
|
253
|
+
```
|
254
|
+
|
255
|
+
Create file `src/i18n.js`:
|
256
|
+
|
257
|
+
```javascript
|
258
|
+
import i18n from "i18next"
|
259
|
+
import { initReactI18next } from "react-i18next"
|
260
|
+
|
261
|
+
const appEn = require('./locales/en/app.json')
|
262
|
+
|
263
|
+
const resources = {
|
264
|
+
en: {
|
265
|
+
app: appEn
|
266
|
+
}
|
267
|
+
}
|
268
|
+
|
269
|
+
i18n
|
270
|
+
.use(initReactI18next) // passes i18n down to react-i18next
|
271
|
+
.init({
|
272
|
+
resources,
|
273
|
+
lng: 'en',
|
274
|
+
fallbackLng: 'en',
|
275
|
+
interpolation: {
|
276
|
+
escapeValue: false // react already safes from xss
|
277
|
+
}
|
278
|
+
})
|
279
|
+
|
280
|
+
export default i18n
|
281
|
+
```
|
282
|
+
|
283
|
+
Add file: `src/locales/en/app.json`
|
284
|
+
|
285
|
+
```json
|
286
|
+
{
|
287
|
+
"MY_TRANSLATION": "Translation example"
|
288
|
+
}
|
289
|
+
```
|
290
|
+
|
291
|
+
Import `i18n` in `src/index.js`:
|
292
|
+
|
293
|
+
```javascript
|
294
|
+
import './i18n'
|
295
|
+
```
|
296
|
+
|
297
|
+
|
298
|
+
#### 6. Add Redux
|
299
|
+
|
300
|
+
**Add Redux only if necessary.**
|
301
|
+
|
302
|
+
Install:
|
303
|
+
|
304
|
+
```bash
|
305
|
+
$ yarn add redux react-redux redux-devtools-extension redux-thunk
|
306
|
+
```
|
307
|
+
|
308
|
+
Add folders:
|
309
|
+
|
310
|
+
```
|
311
|
+
|-- src
|
312
|
+
|-- actions
|
313
|
+
| |-- .keep
|
314
|
+
|
|
315
|
+
|-- reducers
|
316
|
+
| |-- index.js
|
317
|
+
|
|
318
|
+
|-- store.js
|
319
|
+
```
|
320
|
+
|
321
|
+
Edit `src/reducers/index.js`:
|
322
|
+
|
323
|
+
```javascript
|
324
|
+
import { combineReducers } from 'redux'
|
325
|
+
// import appReducer from './appReducer'
|
326
|
+
|
327
|
+
export default () => combineReducers({
|
328
|
+
// app: appReducer,
|
329
|
+
})
|
330
|
+
```
|
331
|
+
|
332
|
+
Edit `src/store.js`:
|
333
|
+
|
334
|
+
```javascript
|
335
|
+
import { createStore, applyMiddleware } from 'redux'
|
336
|
+
import thunk from 'redux-thunk'
|
337
|
+
import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly'
|
338
|
+
import rootReducer from './reducers'
|
339
|
+
|
340
|
+
|
341
|
+
export const store = createStore(
|
342
|
+
rootReducer(),
|
343
|
+
composeWithDevTools(
|
344
|
+
applyMiddleware(
|
345
|
+
thunk
|
346
|
+
)
|
347
|
+
)
|
348
|
+
)
|
349
|
+
export default store
|
350
|
+
```
|
351
|
+
|
352
|
+
Edit `src/index.js`:
|
353
|
+
|
354
|
+
```javascript
|
355
|
+
(...)
|
356
|
+
import { Provider } from 'react-redux'
|
357
|
+
import { store } from './store'
|
358
|
+
(...)
|
359
|
+
|
360
|
+
ReactDOM.render(
|
361
|
+
<React.StrictMode>
|
362
|
+
<Provider store={store}>
|
363
|
+
<App />
|
364
|
+
</Provider>
|
365
|
+
</React.StrictMode>,
|
366
|
+
document.getElementById('root')
|
367
|
+
)
|
368
|
+
(...)
|
369
|
+
|
370
|
+
```
|
371
|
+
|
372
|
+
|
373
|
+
### C) Install other Node modules
|
374
|
+
|
375
|
+
Install only required modules.
|
376
|
+
|
377
|
+
#### 1. Axios
|
378
|
+
|
379
|
+
```bash
|
380
|
+
$ yarn add axios
|
381
|
+
```
|
382
|
+
|
383
|
+
#### 2. AWS Amplify
|
384
|
+
|
385
|
+
```bash
|
386
|
+
$ yarn add aws-amplify
|
387
|
+
```
|
388
|
+
|
389
|
+
|
390
|
+
|
391
|
+
|
392
|
+
### D) Set up SCSS and 7-1 pattern
|
393
|
+
|
394
|
+
Install:
|
395
|
+
|
396
|
+
```bash
|
397
|
+
$ yarn add node-sass
|
398
|
+
```
|
399
|
+
|
400
|
+
Rename `src/App.css` to `src/App.scss` and change import in `src/App.js`:
|
401
|
+
|
402
|
+
```javascript
|
403
|
+
import './App.scss'
|
404
|
+
```
|
405
|
+
|
406
|
+
Create `src/styles` folder and recreate 7-1 pattern:
|
407
|
+
|
408
|
+
```
|
409
|
+
|
|
410
|
+
|– base/
|
411
|
+
| |– _reset.scss # Reset/normalize
|
412
|
+
| |– _typography.scss # Typography rules
|
413
|
+
| ... # Etc…
|
414
|
+
|
|
415
|
+
|– components/
|
416
|
+
| |– .keep
|
417
|
+
|
|
418
|
+
|– layout/
|
419
|
+
| |– .keep
|
420
|
+
|
|
421
|
+
|– pages/
|
422
|
+
| |– .keep
|
423
|
+
|
|
424
|
+
|– themes/
|
425
|
+
| |– _theme.scss # Default theme
|
426
|
+
|
|
427
|
+
|– utils/
|
428
|
+
| |– _variables.scss # Sass Variables
|
429
|
+
| |– _functions.scss # Sass Functions
|
430
|
+
| |– _mixins.scss # Sass Mixins
|
431
|
+
| |– _helpers.scss # Class & placeholders helpers
|
432
|
+
|
|
433
|
+
|– vendors/
|
434
|
+
| |– .keep
|
435
|
+
|
|
436
|
+
|
|
437
|
+
|– main.scss # Main Sass file
|
438
|
+
```
|
439
|
+
|
440
|
+
Edit `src/styles/main.scss`:
|
441
|
+
|
442
|
+
```scss
|
443
|
+
@import
|
444
|
+
'utils/variables',
|
445
|
+
'utils/functions',
|
446
|
+
'utils/mixins',
|
447
|
+
'utils/helpers';
|
448
|
+
|
449
|
+
// @import 'vendors/bootstrap';
|
450
|
+
|
451
|
+
@import
|
452
|
+
'base/reset',
|
453
|
+
'base/typography';
|
454
|
+
|
455
|
+
// @import
|
456
|
+
// 'layout/navigation',
|
457
|
+
// 'layout/grid',
|
458
|
+
// 'layout/header',
|
459
|
+
// 'layout/footer',
|
460
|
+
// 'layout/sidebar',
|
461
|
+
// 'layout/forms';
|
462
|
+
|
463
|
+
// @import 'components/buttons';
|
464
|
+
|
465
|
+
// @import 'pages/home';
|
466
|
+
|
467
|
+
@import 'themes/theme';
|
468
|
+
|
469
|
+
```
|
470
|
+
|
471
|
+
|
472
|
+
Import `src/styles/main.scss` in `src/App.scss`:
|
473
|
+
|
474
|
+
```scss
|
475
|
+
@import './styles/main.scss'
|
476
|
+
```
|
477
|
+
|
478
|
+
### E) Set up ESlint and Prettier
|
479
|
+
|
480
|
+
Install:
|
481
|
+
|
482
|
+
```bash
|
483
|
+
$ yarn add -D babel-eslint eslint eslint-config-airbnb \
|
484
|
+
eslint-config-prettier eslint-plugin-react eslint-plugin-import \
|
485
|
+
prettier pretty-quick eslint-plugin-jsx-a11y
|
486
|
+
```
|
487
|
+
|
488
|
+
Initialize eslint:
|
489
|
+
|
490
|
+
```bash
|
491
|
+
$ ./node_modules/bin/eslint.js --init
|
492
|
+
# OR:
|
493
|
+
$ npx eslint --init
|
494
|
+
```
|
495
|
+
|
496
|
+
Add file `.prettierrc`:
|
497
|
+
|
498
|
+
```javascript
|
499
|
+
{
|
500
|
+
"printWidth": 100,
|
501
|
+
"trailingComma": "all",
|
502
|
+
"tabWidth": 2,
|
503
|
+
"semi": false,
|
504
|
+
"singleQuote": true
|
505
|
+
}
|
506
|
+
```
|
507
|
+
|
508
|
+
Add file `.eslintignore`:
|
509
|
+
|
510
|
+
```
|
511
|
+
build/*
|
512
|
+
node_modules/*
|
513
|
+
```
|
514
|
+
|
515
|
+
Add file `.eslintrc.js`:
|
516
|
+
|
517
|
+
```
|
518
|
+
module.exports = {
|
519
|
+
"extends": ["airbnb", "prettier"],
|
520
|
+
"parser": "babel-eslint",
|
521
|
+
"env": {
|
522
|
+
"browser": true,
|
523
|
+
"es2021": true
|
524
|
+
},
|
525
|
+
"parserOptions": {
|
526
|
+
"ecmaFeatures": {
|
527
|
+
"jsx": true
|
528
|
+
},
|
529
|
+
"ecmaVersion": 12,
|
530
|
+
"sourceType": "module"
|
531
|
+
},
|
532
|
+
"plugins": [
|
533
|
+
"react"
|
534
|
+
],
|
535
|
+
"rules": {
|
536
|
+
"semi": [2, "never"],
|
537
|
+
"no-use-before-define": ["error", { "functions": false, "classes": false, "variables": false }],
|
538
|
+
"import/no-extraneous-dependencies": ["error", {"devDependencies": false, "optionalDependencies": false, "peerDependencies": false}],
|
539
|
+
"import/no-cycle": 0,
|
540
|
+
'jsx-quotes': ["error", "prefer-single"],
|
541
|
+
"no-underscore-dangle": 0,
|
542
|
+
"react/require-default-props": 0,
|
543
|
+
"jsx-a11y/anchor-is-valid": 0,
|
544
|
+
"jsx-a11y/label-has-for": [ 2, {
|
545
|
+
"required": {
|
546
|
+
"some": [ "nesting", "id" ]
|
547
|
+
}
|
548
|
+
}],
|
549
|
+
"react-hooks/exhaustive-deps": 0,
|
550
|
+
"react/forbid-prop-types": 0,
|
551
|
+
"comma-dangle": ["error", {
|
552
|
+
"arrays": "only-multiline",
|
553
|
+
"objects": "only-multiline",
|
554
|
+
"imports": "only-multiline",
|
555
|
+
"exports": "only-multiline",
|
556
|
+
"functions": "never",
|
557
|
+
}],
|
558
|
+
"react/jsx-pascal-case": 0,
|
559
|
+
"react/no-array-index-key": 0,
|
560
|
+
},
|
561
|
+
};
|
562
|
+
|
563
|
+
```
|
564
|
+
|
565
|
+
Add to `package.json`:
|
566
|
+
|
567
|
+
```json
|
568
|
+
"scripts": {
|
569
|
+
(...)
|
570
|
+
"lint": "./node_modules/eslint/bin/eslint.js --ext .js --ext .jsx .",
|
571
|
+
"format": "prettier --write \"**/*.+(js|jsx|json|css|md)\""
|
572
|
+
},
|
573
|
+
```
|
574
|
+
|
575
|
+
And you can run:
|
576
|
+
|
577
|
+
```bash
|
578
|
+
$ yarn lint
|
579
|
+
$ yarn format
|
580
|
+
```
|
581
|
+
|
582
|
+
|
583
|
+
|
584
|
+
### F) Set up tests
|
585
|
+
|
586
|
+
TODO
|
587
|
+
|
588
|
+
|
589
|
+
|
590
|
+
### G) Edit README.md
|
591
|
+
|
592
|
+
```markdown
|
593
|
+
{% include templates/react/react_readme.md project_name=project_name %}
|
594
|
+
```
|
595
|
+
|
596
|
+
|
597
|
+
|
598
|
+
### H) Service worker
|
599
|
+
|
600
|
+
TODO
|