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.
@@ -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