├── .npmrc
├── src
├── assets
│ ├── styles
│ │ ├── abstractions
│ │ │ └── abstractions.scss
│ │ ├── vendor
│ │ │ ├── vendor.scss
│ │ │ └── sanitize.scss
│ │ ├── mixins
│ │ │ └── mixins.scss
│ │ ├── base
│ │ │ ├── base.scss
│ │ │ ├── common.scss
│ │ │ └── typography.scss
│ │ ├── main.scss
│ │ ├── README.md
│ │ └── settings
│ │ │ ├── settings.scss
│ │ │ ├── settings-fonts.scss
│ │ │ ├── settings-layout.scss
│ │ │ ├── settings-typography.scss
│ │ │ └── settings-color.scss
│ └── icons
│ │ └── logo.svg
├── react-app-env.d.ts
├── utils
│ ├── development.ts
│ └── serviceWorker.ts
├── views
│ ├── components
│ │ ├── Loading.tsx
│ │ ├── Footer.tsx
│ │ └── Header.tsx
│ └── containers
│ │ └── App
│ │ ├── App.test.js
│ │ └── App.tsx
├── typings
│ ├── index.d.ts
│ └── images.d.ts
├── index.tsx
└── setupProxy.js
├── public
├── favicons
│ ├── favicon.ico
│ ├── apple-touch-icon.png
│ ├── mstile-150x150.png
│ ├── android-chrome-192x192.png
│ ├── android-chrome-256x256.png
│ ├── browserconfig.xml
│ └── safari-pinned-tab.svg
├── manifest.json
├── development
│ ├── injector.css
│ └── injector.js
└── index.html
├── config
├── .release-it.json
├── loaders
│ ├── svg.js
│ ├── eslint.js
│ └── styles.js
├── setup
│ ├── utils
│ │ ├── schema.js
│ │ ├── index.js
│ │ ├── logger.js
│ │ ├── file.js
│ │ └── actions.js
│ ├── setup.js
│ ├── schema.js
│ ├── packages.js
│ └── actions.js
├── tsconfig.paths.json
├── config-overrides.js
├── paths.js
├── webpack.config.dev.js
├── utils
│ ├── index.js
│ └── proxy.js
├── webpack.config.common.js
└── webpack.config.prod.js
├── .babelrc
├── .prettierrc
├── .gitignore
├── .env.sample
├── .vscode
└── launch.json
├── tsconfig.json
├── .eslintrc.js
├── package.json
└── README.md
/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
--------------------------------------------------------------------------------
/src/assets/styles/abstractions/abstractions.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/styles/vendor/vendor.scss:
--------------------------------------------------------------------------------
1 | @import "sanitize";
2 |
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | //
2 |
--------------------------------------------------------------------------------
/src/assets/styles/mixins/mixins.scss:
--------------------------------------------------------------------------------
1 | // Vendor
2 | @import "~@adaptagency/fe_tools/main";
--------------------------------------------------------------------------------
/src/utils/development.ts:
--------------------------------------------------------------------------------
1 | export const isDev: boolean = process.env.NODE_ENV === 'development';
2 |
--------------------------------------------------------------------------------
/public/favicons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adaptdk/react_boilerplate/HEAD/public/favicons/favicon.ico
--------------------------------------------------------------------------------
/config/.release-it.json:
--------------------------------------------------------------------------------
1 | {
2 | "git": {
3 | "tagName": "${version}",
4 | "requireUpstream": false
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/assets/styles/base/base.scss:
--------------------------------------------------------------------------------
1 | @import "common"; // Common HTML tags
2 | @import "typography"; // Typography
3 |
--------------------------------------------------------------------------------
/config/loaders/svg.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 |
3 | module.exports = {
4 | test: /\.svg$/,
5 | use: ['@svgr/webpack'],
6 | };
7 |
--------------------------------------------------------------------------------
/public/favicons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adaptdk/react_boilerplate/HEAD/public/favicons/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/favicons/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adaptdk/react_boilerplate/HEAD/public/favicons/mstile-150x150.png
--------------------------------------------------------------------------------
/public/favicons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adaptdk/react_boilerplate/HEAD/public/favicons/android-chrome-192x192.png
--------------------------------------------------------------------------------
/public/favicons/android-chrome-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adaptdk/react_boilerplate/HEAD/public/favicons/android-chrome-256x256.png
--------------------------------------------------------------------------------
/src/views/components/Loading.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Loading = (): JSX.Element => Loading;
4 |
5 | export default Loading;
6 |
--------------------------------------------------------------------------------
/src/typings/index.d.ts:
--------------------------------------------------------------------------------
1 | // CSS Modules Styling
2 | declare module '*.scss' {
3 | const styles: { [className: string]: string };
4 | export default styles;
5 | }
6 |
--------------------------------------------------------------------------------
/src/views/components/Footer.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Footer = (): JSX.Element => ;
4 |
5 | export default Footer;
6 |
--------------------------------------------------------------------------------
/src/views/components/Header.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Header = (): JSX.Element => ;
4 |
5 | export default Header;
6 |
--------------------------------------------------------------------------------
/src/assets/styles/base/common.scss:
--------------------------------------------------------------------------------
1 | // Body
2 | body {
3 | font-size: 16px;
4 | }
5 |
6 | // Media
7 | img {
8 | display: inline-block;
9 | max-width: 100%;
10 | }
11 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["@babel/preset-env", { "useBuiltIns": "entry" } ],
4 | "babel-preset-react-app"
5 | ],
6 | "plugins": ["react-hot-loader/babel"]
7 | }
8 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "jsxSingleQuote": false,
4 | "trailingComma": "all",
5 | "printWidth": 100,
6 | "semi": true,
7 | "arrowParens": "always"
8 | }
9 |
--------------------------------------------------------------------------------
/src/typings/images.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.svg'
2 | declare module '*.png'
3 | declare module '*.jpg'
4 | declare module '*.jpeg'
5 | declare module '*.gif'
6 | declare module '*.bmp'
7 | declare module '*.tiff'
8 |
--------------------------------------------------------------------------------
/config/loaders/eslint.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | // Makes the ReWire look into the .eslintrc which isn't being affected out of the box with CRA.
3 | module.exports = function(options) {
4 | return options;
5 | };
6 |
--------------------------------------------------------------------------------
/config/setup/utils/schema.js:
--------------------------------------------------------------------------------
1 | const isYes = s => s === "yes" || s === "y" || s === "Yes" || s === "Y";
2 | const isNo = s => s === "no" || s === "n" || s === "No" || s === "N";
3 |
4 | module.exports = {
5 | isYes,
6 | isNo,
7 | };
8 |
--------------------------------------------------------------------------------
/src/views/containers/App/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | });
9 |
--------------------------------------------------------------------------------
/config/setup/utils/index.js:
--------------------------------------------------------------------------------
1 | const actions = require("./actions");
2 | const file = require("./file");
3 | const logger = require("./logger");
4 | const schema = require("./schema");
5 |
6 | module.exports = {
7 | ...actions,
8 | ...file,
9 | ...logger,
10 | ...schema,
11 | };
12 |
--------------------------------------------------------------------------------
/src/assets/styles/main.scss:
--------------------------------------------------------------------------------
1 | // Vendor
2 | @import "vendor/vendor";
3 |
4 | // Fonts
5 | @import "settings/settings-fonts";
6 |
7 | // Settings
8 | @import "settings/settings";
9 |
10 | // Base
11 | @import "base/base";
12 |
13 | // Elements
14 | @import "abstractions/abstractions";
15 |
--------------------------------------------------------------------------------
/public/favicons/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #da532c
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/assets/styles/README.md:
--------------------------------------------------------------------------------
1 | ## Structure
2 | - base - Base styling like html, body and base typography
3 | - abstractions - Class abstractions like .btn
4 | - mixins - Mixins
5 | - settings - Scss Variables, don't add anything that will bundle in the CSS.
6 |
7 | #### But where's the component?
8 | Each components scss file should be next to the jsx file in the
9 |
--------------------------------------------------------------------------------
/src/assets/styles/base/typography.scss:
--------------------------------------------------------------------------------
1 | // Creates the default typography settings
2 | @include respTypo((
3 | p: ($fz-normal),
4 | h1: ($fz-h1, $fz-h1*1.15),
5 | h2: ($fz-h2, $fz-h2*1.15),
6 | h3: ($fz-h3, $fz-h3*1.15),
7 | h4: ($fz-h4, $fz-h4*1.15),
8 | h5: ($fz-h5, $fz-h5*1.15),
9 | h6: ($fz-h6, $fz-h6*1.15),
10 | ));
11 |
12 | // Paragraph
13 | p {
14 | margin: 0;
15 |
16 | + p {
17 | margin-top: $fz-normal/1.25;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # editors
13 | .history
14 |
15 | # misc
16 | .DS_Store
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
26 | .idea
27 | .vscode/*
28 |
29 | .env
--------------------------------------------------------------------------------
/src/assets/styles/settings/settings.scss:
--------------------------------------------------------------------------------
1 | //
2 | // This is used both for the root scss files (main.scss, critical.scss etc),
3 | // but also for the scss components, which are not inside of the roots.
4 | //
5 |
6 | // Typography and Fonts settings
7 | @import "settings-typography";
8 |
9 | // Colors settings
10 | @import "settings-color";
11 |
12 | // Layout and appearance settings
13 | @import "settings-layout";
14 |
15 | // Mixins
16 | @import "../mixins/mixins";
17 |
--------------------------------------------------------------------------------
/src/assets/styles/settings/settings-fonts.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable
2 | // Path is relative to the compiled folder
3 | $fontsPath: '../public/fonts/';
4 |
5 | // Custom Font Light
6 | //@font-face {
7 | // font-family: 'customFont';
8 | // src: url("#{$fontsPath}customFont-Light?#iefix");
9 | // src: url("#{$fontsPath}customFont-Light?#iefix") format("eot"),
10 | // url('#{$fontsPath}customFont-Light.woff') format('woff'),
11 | // url('#{$fontsPath}customFont-Light.ttf') format('truetype');
12 | // font-weight: 300;
13 | // font-style: normal;
14 | //}
15 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | // Utils
5 | import * as serviceWorker from 'utils/serviceWorker';
6 |
7 | // Container
8 | import App from 'views/containers/App/App';
9 |
10 | // Styles
11 | import 'assets/styles/main.scss';
12 |
13 | ReactDOM.render(, document.querySelector('#root'));
14 |
15 | // If you want your app to work offline and load faster, you can change
16 | // unregister() to register() below. Note this comes with some pitfalls.
17 | // Learn more about service workers: http://bit.ly/CRA-PWA
18 | serviceWorker.register();
19 |
--------------------------------------------------------------------------------
/src/assets/styles/settings/settings-layout.scss:
--------------------------------------------------------------------------------
1 | // Layout Variables
2 | $l-space: 10px;
3 | $l-gutter: $l-space*2;
4 | $l-leading: $l-space*2;
5 |
6 | // Visual Variables
7 | $v-border: 1px solid $c-black;
8 | $v-radius: 2px;
9 | $v-shadow: 0 5px 20px rgba(0, 0, 0, 0.075);
10 |
11 | // Transition Timing
12 | $ts-easing: ease;
13 | $ts-timing: 0.3;
14 | $ts-base: #{$ts-timing}s $ts-easing;
15 | $ts-quick: #{$ts-timing/2}s $ts-easing;
16 |
17 | // Breakpoints
18 | $small: 420px;
19 | $medium: 768px;
20 | $large: 1024px;
21 | $xlarge: 1440px;
22 |
--------------------------------------------------------------------------------
/config/tsconfig.paths.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "../.",
4 | "paths": {
5 | "*": ["*", "generated/*"],
6 | "assets": ["src/assets"],
7 | "assets/*": ["src/assets/*"],
8 | "constants": ["src/constants"],
9 | "constants/*": ["src/constants/*"],
10 | "state": ["src/state"],
11 | "state/*": ["src/state/*"],
12 | "typings": ["src/typings"],
13 | "typings/*": ["src/typings/*"],
14 | "utils": ["src/utils"],
15 | "utils/*": ["src/utils/*"],
16 | "views": ["src/views"],
17 | "views/*": ["src/views/*"]
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/.env.sample:
--------------------------------------------------------------------------------
1 | SKIP_PREFLIGHT_CHECK=true
2 |
3 | # Build
4 | # Run a profiler and get the stats from the build
5 | PROFILER=false
6 | # Analyze the bundle including node_modules
7 | BUNDLE_ANALYZER=false
8 | # Critical CSS
9 | CRIT_CSS=false
10 | # Enables Polyfill
11 | POLYFILL=false
12 | # Enable Source Maps - Useful for Test Or Staging deploy sites
13 | SOURCE_MAP=true
14 | # Enables Gzipping of files
15 | GZIP=true
16 | # Add Hash to output files (Useful if you're serving the files through another system if and they hash it)
17 | HASH_BUILD=true
18 |
19 | # Proxy the React app onto another env.
20 | PROXY_URL="http://yourLocal.env"
21 | PROXY=false
--------------------------------------------------------------------------------
/src/assets/styles/settings/settings-typography.scss:
--------------------------------------------------------------------------------
1 | // Font Family
2 | $ff-Arial: "Arial", Helvetica, sans-serif;
3 |
4 | // Font Weight
5 | $fw-light: 300;
6 | $fw-regular: 400;
7 | $fw-bold: 700;
8 |
9 | // Font Line Height
10 | $flh-small: 1;
11 | $flh-normal: 1.15;
12 | $flh-large: 1.5;
13 |
14 | // Font Sizes
15 | // Paragraphs
16 | $fz-small: 0.9rem;
17 | $fz-normal: 1rem;
18 |
19 | // Headers
20 | $fz-h6: 1.1rem;
21 | $fz-h5: 1.15rem;
22 | $fz-h4: 1.25rem;
23 | $fz-h3: 1.75rem;
24 | $fz-h2: 2rem;
25 | $fz-h1: 2.5rem;
26 |
--------------------------------------------------------------------------------
/config/config-overrides.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | /* config-overrides.js */
3 |
4 | // Loading Configs
5 | const commonConfig = require("./webpack.config.common");
6 | const prodConfig = require("./webpack.config.prod");
7 | const devConfig = require("./webpack.config.dev");
8 |
9 | module.exports = function override(config, env) {
10 | const isProd = env === "production";
11 | const isDev = env === "development";
12 |
13 | // Loading Env Config
14 | config = {
15 | ...commonConfig(config, isProd),
16 | ...(isProd ? prodConfig(config) : {}),
17 | ...(isDev ? devConfig(config) : {}),
18 | };
19 |
20 | return config;
21 | };
22 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "chrome",
9 | "request": "launch",
10 | "name": "Launch Chrome",
11 | "url": "http://localhost:3000",
12 | "webRoot": "${workspaceFolder}",
13 | "userDataDir": false,
14 | "sourceMaps": true,
15 | "sourceMapPathOverrides": {
16 | "webpack:///*": "${workspaceFolder}/*"
17 | }
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicons/favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "favicons/android-chrome-192x192.png",
12 | "sizes": "192x192",
13 | "type": "image/png"
14 | },
15 | {
16 | "src": "favicons/android-chrome-256x256.png",
17 | "sizes": "256x256",
18 | "type": "image/png"
19 | }
20 | ],
21 | "start_url": "/",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const fs = require('fs');
3 |
4 | // Make sure any symlinks in the project folder are resolved:
5 | // https://github.com/facebookincubator/create-react-app/issues/637
6 | const appDirectory = fs.realpathSync(process.cwd());
7 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
8 |
9 | module.exports = {
10 | appBuild: resolveApp('build'),
11 | appHtml: resolveApp('public/index.html'),
12 | appIndex: resolveApp('src/index.tsx'),
13 | appNodeModules: resolveApp('node_modules'),
14 | appPackageJson: resolveApp('package.json'),
15 | appPublic: resolveApp('public'),
16 | appSrc: resolveApp('src'),
17 | appStatic: resolveApp('build/static'),
18 | dotenv: resolveApp('.env'),
19 | };
20 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true,
4 | "allowSyntheticDefaultImports": true,
5 | "esModuleInterop": true,
6 | "forceConsistentCasingInFileNames": true,
7 | "isolatedModules": true,
8 | "jsx": "preserve",
9 | "module": "esnext",
10 | "moduleResolution": "node",
11 | "noEmit": true,
12 | "noImplicitAny": false,
13 | "noResolve": false,
14 | "removeComments": true,
15 | "resolveJsonModule": true,
16 | "skipLibCheck": true,
17 | "sourceMap": true,
18 | "strict": true,
19 | "target": "es6",
20 | "lib": [
21 | "dom",
22 | "dom.iterable",
23 | "esnext"
24 | ]
25 | },
26 | "include": [
27 | "src",
28 | "typings"
29 | ],
30 | "exclude": [
31 | "./node_modules/**/*",
32 | "src/**/*.spec.*",
33 | "src/setupProxy.js"
34 | ],
35 | "extends": "./config/tsconfig.paths.json"
36 | }
37 |
--------------------------------------------------------------------------------
/config/webpack.config.dev.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 |
3 | // Plugins
4 | const ExtractCssChunks = require("extract-css-chunks-webpack-plugin");
5 | const rewireReactHotLoader = require("react-app-rewire-hot-loader");
6 |
7 | module.exports = function(config) {
8 | // Hot Loader
9 | config = rewireReactHotLoader(config, "development");
10 |
11 | // Set Source Map
12 | config.devtool = "source-map";
13 |
14 | // Resolve
15 | config.resolve.alias = {
16 | ...config.resolve.alias,
17 | "react-dom": "@hot-loader/react-dom",
18 | };
19 |
20 | // Plugins
21 | config.plugins = [
22 | ...config.plugins,
23 | // Minify CSS Etract Plugin
24 | new ExtractCssChunks({
25 | filename: "[name].css",
26 | chunkFilename: "[id].css",
27 | orderWarning: true, // Disable to remove warnings about conflicting order between imports
28 | }),
29 | ];
30 |
31 | return config;
32 | };
33 |
--------------------------------------------------------------------------------
/src/assets/styles/settings/settings-color.scss:
--------------------------------------------------------------------------------
1 | // Primary Colours
2 | $c-orange: #E94E1B; // Orange
3 | $c-peach: #EF7A39; // Peach
4 |
5 | // Secondary Colours
6 | $c-white: #FFFFFF; // White
7 | $c-lightBlue: #B5CDDB; // Light Blue
8 | $c-turquoise: #0DA8BF; // Turquoise
9 | $c-darkBlue: #00374F; // Dark Blue
10 | $c-black: #09181C; // Black
11 |
12 | // Greys
13 | $c-grey: #888888; // Base Grey
14 | $c-darkGrey: darken($c-grey, 35%); // Dark Grey
15 | $c-mediumGrey: lighten($c-grey, 20%); // Medium Grey
16 | $c-lightGrey: lighten($c-grey, 30%); // Light Grey
17 | $c-lighterGrey: lighten($c-grey, 35%); // Lighter Grey
18 |
19 | // Fonts
20 | $c-font: $c-black;
21 |
22 | // Overlay colors
23 | $c-overlay: rgba(0, 0, 0, 0.5);
24 | $c-transparent: rgba(255, 255, 255, 0);
25 |
--------------------------------------------------------------------------------
/config/setup/setup.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | const prompt = require("prompt");
3 |
4 | // Actions
5 | const { startPrompt, finishSetup, getPackages, getFeatures, getProjectName, setupGit, exited } = require("./actions");
6 |
7 | const project = {
8 | debug: false,
9 | branch: null,
10 | customizeFeature: false,
11 | deleteRepo: false,
12 | features: [],
13 | finished: false,
14 | machine: null,
15 | ownRepo: null,
16 | package: null,
17 | title: null,
18 | };
19 |
20 | // Initialize the Install process
21 | prompt.start();
22 |
23 | // Start the Prompt
24 | startPrompt(project)
25 | // Get Project Name
26 | .then(getProjectName)
27 | // Then Get Packages
28 | .then(getPackages)
29 | // If there's features in the selected package, load them
30 | .then(() => project.features.length > 0 && getFeatures(project))
31 | // Configure Git - Removing / Adding
32 | .then(setupGit)
33 | // Then finish up the setup
34 | .then(finishSetup)
35 | // If something goes wrong, do a smooth exit ❤️
36 | .catch(exited);
37 |
--------------------------------------------------------------------------------
/src/setupProxy.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 |
3 | const proxy = require("http-proxy-middleware");
4 |
5 | const { envs } = require("../config/utils");
6 | const { appendToProxyResponse } = require("../config/utils/proxy");
7 |
8 | module.exports = app => {
9 | // If you're not proxying to another site, just ignore this file.
10 | if (!envs.proxy) return;
11 | // Exclude specific URL's which shouldn't be proxied to the target URL,
12 | // but use the Webpack Dev Server. Like static files, hot module reloader and development script
13 | const excludes = ["/static/**", "/sockjs-node/**", "/asset-manifest.json", "/development/**"];
14 | // Setup Proxy
15 | app.use(
16 | proxy(`!(${excludes.join("|")})`, {
17 | target: process.env.PROXY_URL,
18 | changeOrigin: true,
19 | selfHandleResponse: true,
20 | headers: { "Access-Control-Allow-Origin": "*", "accept-encoding": "gzip;q=0,deflate,sdch" },
21 | onProxyRes: appendToProxyResponse([
22 | '',
23 | '',
24 | ]),
25 | })
26 | );
27 | };
28 |
--------------------------------------------------------------------------------
/src/views/containers/App/App.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import loadable from '@loadable/component';
3 | import { hot } from 'react-hot-loader';
4 |
5 | // Utilities
6 | import { isDev } from 'utils/development';
7 |
8 | // Components
9 | import Header from 'views/components/Header';
10 | import Loading from 'views/components/Loading';
11 |
12 | // Icons
13 | import Logo from 'assets/icons/logo.svg';
14 |
15 | // Loadables
16 | const Footer = loadable((): Promise => import('views/components/Footer'), {
17 | fallback: ,
18 | });
19 |
20 | const App = (): JSX.Element => {
21 | const [value, setValue] = useState('1');
22 |
23 | return (
24 |
25 |
26 |
27 |
28 | Home {value}
29 |
32 |
35 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | );
45 | };
46 |
47 | export default isDev ? hot(module)(App) : App;
48 |
--------------------------------------------------------------------------------
/public/development/injector.css:
--------------------------------------------------------------------------------
1 | @keyframes injectorLoaderIn {
2 | 0% {
3 | transform: translate3d(-50%, 0, 0);
4 | opacity: 0;
5 | }
6 |
7 | 100% {
8 | transform: translate3d(-50%, -70px, 0);
9 | opacity: 0.93;
10 | }
11 | }
12 |
13 | @keyframes injectorLoaderOut {
14 | 0% {
15 | transform: translate(-50%, -70px);
16 | opacity: 0.93;
17 | }
18 |
19 | 85% {
20 | transform: translate(-50%, -70px) scale(1);
21 | opacity: 0.93;
22 | }
23 |
24 | 95% {
25 | transform: translate(-50%, -75px) scale(1.1);
26 | opacity: 0.93;
27 | }
28 |
29 | 100% {
30 | transform: translate(-50%, 0) scale(1);
31 | opacity: 0;
32 | }
33 | }
34 |
35 | .injector-loader-element {
36 | position: fixed;
37 | top: 100%;
38 | left: 50%;
39 | background-color: #333;
40 | color: #fff;
41 | padding: 10px 15px;
42 | border-radius: 6px;
43 | font-family: "Helvetica", sans-serif;
44 | font-size: 14px;
45 | font-weight: 600;
46 | box-shadow: 0 5px 20px 3px rgba(0, 0, 0, 0.15);
47 | }
48 |
49 | .injector-loader-element:hover {
50 | opacity: 1;
51 | }
52 |
53 | body:not(.injector--loading) .injector-loader-element {
54 | animation: injectorLoaderOut 2.3s ease forwards;
55 | }
56 |
57 | body.injector--loading .injector-loader-element {
58 | animation: injectorLoaderIn 2s ease forwards;
59 | }
60 |
--------------------------------------------------------------------------------
/public/development/injector.js:
--------------------------------------------------------------------------------
1 | const body = document.querySelector("body");
2 |
3 | const filterRegExp = RegExp(/(\.js$|\.css$)/);
4 |
5 | const injector = {
6 | createLoadingElement: () => {
7 | const loaderElement = document.createElement("div");
8 | loaderElement.className = "injector-loader-element";
9 | loaderElement.innerHTML = "Injecting...";
10 | document.body.appendChild(loaderElement);
11 | },
12 | destroyLoadingElement: () => {
13 | const loaderElement = document.querySelector("div.injector-loader-element");
14 | document.body.removeChild(loaderElement);
15 | },
16 | setLoading: async () => {
17 | await injector.createLoadingElement();
18 | body.classList.add("injector--loading");
19 | },
20 | setLoaded: () => {
21 | body.classList.remove("injector--loading");
22 | },
23 | injectScripts: async () => {
24 | await fetch("/asset-manifest.json")
25 | .then(res => res.json())
26 | .then(res => {
27 | Object.values(res.files)
28 | .filter(file => filterRegExp.test(file))
29 | .forEach(file => file && import(file));
30 | });
31 | },
32 | init: async () => {
33 | injector.setLoading();
34 | await injector.injectScripts();
35 | injector.setLoaded();
36 | setTimeout(injector.destroyLoadingElement, 5000);
37 | },
38 | };
39 |
40 | injector.init();
41 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['airbnb', 'plugin:@typescript-eslint/recommended'],
3 | parser: '@typescript-eslint/parser',
4 | plugins: ['@typescript-eslint', 'prettier', 'import'],
5 | env: {
6 | browser: true,
7 | node: true,
8 | },
9 | globals: {
10 | window: false,
11 | document: false,
12 | it: false,
13 | describe: false,
14 | },
15 | settings: {
16 | 'import/parsers': {
17 | '@typescript-eslint/parser': ['.ts', '.tsx'],
18 | },
19 | 'import/resolver': {
20 | typescript: {},
21 | node: {
22 | extensions: ['.js', '.jsx', '.ts', '.tsx'],
23 | },
24 | },
25 | },
26 | rules: {
27 | 'react/jsx-filename-extension': [2, { extensions: ['.js', '.jsx', '.ts', '.tsx'] }],
28 | 'import/no-extraneous-dependencies': [2, { devDependencies: ['**/test.tsx', '**/test.ts'] }],
29 | '@typescript-eslint/indent': [2, 2],
30 | '@typescript-eslint/explicit-function-return-type': 0,
31 | '@typescript-eslint/no-explicit-any': 0,
32 | 'import/no-extraneous-dependencies': 0,
33 | 'import/prefer-default-export': 0,
34 | 'react/jsx-one-expression-per-line': 0,
35 | 'react/jsx-props-no-spreading': 0,
36 | 'react/prop-types': 0,
37 | 'implicit-arrow-linebreak': 0,
38 | 'operator-linebreak': [1, 'after'],
39 | 'import/no-unresolved': [2, { ignore: ['RootTypes'] }],
40 | },
41 | };
42 |
--------------------------------------------------------------------------------
/config/utils/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 |
3 | /**
4 | * Helper functions and variables for the loaders
5 | * @param {Array} rules - The rules array coming from the config.modules.rules,
6 | * @return {any}
7 | */
8 | const loaderUtil = rules => {
9 | /** The index of oneOf in the rules */
10 | const oneOfIndex = rules.findIndex(item => item["oneOf"]);
11 |
12 | /** The oneOf rule */
13 | const oneOf = rules[oneOfIndex].oneOf;
14 |
15 | /**
16 | * Find a specfic loader within the oneOf
17 | * @param {string} loader - RegEx testing each loader
18 | * @return {any} The Loader
19 | */
20 | const findLoader = loader =>
21 | oneOf.find(item => {
22 | return new RegExp(loader).test(item.loader);
23 | });
24 |
25 | /** The fileLoader object */
26 | const fileLoader = findLoader("file-loader");
27 |
28 | return {
29 | oneOfIndex,
30 | oneOf,
31 | findLoader,
32 | fileLoader,
33 | };
34 | };
35 |
36 | // Environment variables
37 | const envs = {
38 | bundleAnalyzer: process.env.BUNDLE_ANALYZER === "true",
39 | criticalCSS: process.env.CRIT_CSS === "true",
40 | gzip: process.env.GZIP === "true",
41 | hashBuild: process.env.HASH_BUILD === "true",
42 | polyfill: process.env.POLYFILL === "true",
43 | profiler: process.env.PROFILER === "true",
44 | proxy: process.env.PROXY === "true",
45 | sourceMap: process.env.SOURCE_MAP === "true",
46 | };
47 |
48 | module.exports = {
49 | envs,
50 | loaderUtil,
51 | };
52 |
--------------------------------------------------------------------------------
/config/setup/utils/logger.js:
--------------------------------------------------------------------------------
1 | const colors = require("colors/safe");
2 |
3 | // Color Functions
4 | const color = {
5 | bold: value => colors.bold(value),
6 | dim: value => colors.gray(value),
7 | warn: value => colors.yellow(value),
8 | underline: value => colors.underline(value),
9 | error: value => colors.red(value),
10 | highlight: value => colors.blue(value),
11 | };
12 |
13 | const spacer = amount => (amount > 0 ? new Array(amount).fill("").forEach(() => print(``)) : null);
14 |
15 | const print = (string, variant, space = [0, 0]) => {
16 | // Pre String Space
17 | spacer(space[0]);
18 |
19 | switch (variant) {
20 | case "bold":
21 | console.log(color.bold(string));
22 | break;
23 | case "dim":
24 | console.log(color.dim(string));
25 | break;
26 | case "error":
27 | console.log(color.error(string));
28 | break;
29 | case "warn":
30 | console.log(color.warn(string));
31 | break;
32 | case "underline":
33 | console.log(color.underline(string));
34 | break;
35 | default:
36 | console.log(string);
37 | break;
38 | }
39 |
40 | // Post String Space
41 | spacer(space[1]);
42 | };
43 |
44 | const printFeatureConf = features => {
45 | features.forEach(feature => {
46 | print(` {`);
47 | Object.entries(feature).forEach(([key, value]) => {
48 | print(` ${color.bold(`${key}:`)} ${value}`);
49 | });
50 | print(` }`, null, [0, 1]);
51 | });
52 | };
53 |
54 | module.exports = {
55 | ...color,
56 | spacer,
57 | print,
58 | printFeatureConf,
59 | };
60 |
--------------------------------------------------------------------------------
/config/setup/schema.js:
--------------------------------------------------------------------------------
1 | // The Questions
2 | const schema = {
3 | name: {
4 | properties: {
5 | machine: {
6 | description: "Machine name [only lowercase]",
7 | message: "Name must be only be lowercase letters",
8 | pattern: /^[a-z]+$/,
9 | required: true,
10 | },
11 | title: {
12 | description: "Project title [letters and spaces]",
13 | message: "Name must be only letters and spaces, and no foreign characters",
14 | pattern: /^[a-zA-Z-\s]+$/,
15 | required: true,
16 | },
17 | },
18 | },
19 | packages: {
20 | properties: {
21 | package: {
22 | message: "You must select a package by entering it's number [0-9]",
23 | description: "Which package do you want to setup? [1 is default]",
24 | pattern: /[0-9]/,
25 | default: "1",
26 | required: true,
27 | },
28 | },
29 | },
30 | features: {
31 | properties: {
32 | features: {
33 | message: "Do you want customize the package?",
34 | description: "yes|y or no|n",
35 | pattern: /(y|yes|n|no)/,
36 | default: "no",
37 | required: true,
38 | },
39 | },
40 | },
41 | git: {
42 | properties: {
43 | ownRepo: {
44 | message:
45 | "Keep empty to get an empty repo or enter a valid git repository SSH URL. like [git@github.com:user/repo.git]",
46 | description: "SSH Url",
47 | default: "no",
48 | pattern: /^(no|(https|git)(:\/\/|@)([^\/:]+)[\/:]([^\/:]+)\/(.+).git)$/,
49 | },
50 | },
51 | },
52 | };
53 |
54 | module.exports = {
55 | schema,
56 | };
57 |
--------------------------------------------------------------------------------
/public/favicons/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
31 |
--------------------------------------------------------------------------------
/config/setup/packages.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 |
3 | // Utilities
4 | const { dim } = require("./utils");
5 |
6 | // Read more about the different packages here: https://github.com/adaptdk/react_boilerplate
7 | const packages = [
8 | {
9 | type: "break",
10 | title: "Typescript",
11 | },
12 | {
13 | id: "1",
14 | title: "Base",
15 | branch: "typescript/base",
16 | features: [{ name: "proxy" }],
17 | },
18 | {
19 | id: "2",
20 | title: "Complex",
21 | branch: "typescript/complex",
22 | features: [{ name: "proxy" }],
23 | },
24 | {
25 | id: "3",
26 | title: "Widgets",
27 | branch: "typescript/widgets",
28 | features: [{ name: "proxy" }],
29 | },
30 | {
31 | type: "break",
32 | title: "Regular",
33 | },
34 | {
35 | id: "4",
36 | title: "Base",
37 | branch: "regular/base",
38 | features: [{ name: "proxy" }],
39 | },
40 | {
41 | id: "5",
42 | title: "Complex",
43 | branch: "regular/complex",
44 | features: [{ name: "proxy" }],
45 | },
46 | ];
47 |
48 | // Features that have multiple structures
49 | // This will not be used, if none of the packages includes one of it's features.
50 | const features = [
51 | {
52 | name: "proxy",
53 | title: "Proxy another site?",
54 | description: `Do you want to proxy the site onto another local environment? ${dim(
55 | "You can always enable later in config/config-overrides.js"
56 | )}`,
57 | schema: {
58 | properties: {
59 | proxy: {
60 | message: `Add URL or keep empty to continue without proxying. ${dim(
61 | "You can always enable later in config/config-overrides.js"
62 | )}`,
63 | description: "Local Env. URL",
64 | pattern: /(no|^htt(ps|p).*(:|.))/,
65 | default: "no",
66 | required: true,
67 | },
68 | },
69 | },
70 | },
71 | ];
72 |
73 | module.exports = {
74 | packages,
75 | features,
76 | };
77 |
--------------------------------------------------------------------------------
/config/utils/proxy.js:
--------------------------------------------------------------------------------
1 | const cssRegExp = RegExp(/(\.css$)/);
2 | const jsRegExp = RegExp(/(\.js$)/);
3 | const gzipRegExp = RegExp(/gzip/);
4 |
5 | const settingHeaders = (proxyRes, req, res) => {
6 | if (jsRegExp.test(req.path)) res.setHeader("Content-Type", "application/javascript");
7 |
8 | if (cssRegExp.test(req.path)) res.setHeader("Content-Type", "text/css");
9 |
10 | if (gzipRegExp.test(proxyRes.headers["content-encoding"])) res.setHeader("Content-Encoding", "gzip");
11 | };
12 |
13 | const appendToProxyResponse = inject => (proxyRes, req, res) => {
14 | if (Array.isArray(inject)) inject = inject.join("");
15 |
16 | // Handle error codes
17 | if (proxyRes.statusCode === 404) {
18 | res.sendStatus(proxyRes.statusCode);
19 | return;
20 | }
21 |
22 | // Setting Headers
23 | settingHeaders(proxyRes, req, res);
24 |
25 | if (proxyRes.headers["content-type"] && proxyRes.headers["content-type"].indexOf("text/html") >= 0) {
26 | let body = Buffer.from("");
27 | // Create flag to detect modification
28 | let responseModified = false;
29 | // need to remove this header as we may modify the response
30 | if (proxyRes.headers["content-length"]) delete proxyRes.headers["content-length"];
31 |
32 | // Listen to Proxy Response.
33 | proxyRes.on("data", data => {
34 | body = Buffer.concat([body, data]);
35 | // The Tag which we're going to inject before
36 | const tag = "
35 |
38 |
39 |
49 | ";
37 | const dataAsString = data.toString();
38 | // Check whether the we've modified before
39 | if (!responseModified && dataAsString.indexOf(tag) >= 0) {
40 | responseModified = true;
41 | // Inject the scripts
42 | inject = `${inject}${tag}`;
43 | res.write(Buffer.from(dataAsString.replace(tag, inject), "utf8"));
44 | } else {
45 | res.write(data);
46 | }
47 | });
48 | proxyRes.on("end", () => res.end(body));
49 | } else {
50 | proxyRes.pipe(res);
51 | }
52 | };
53 |
54 | module.exports = {
55 | appendToProxyResponse,
56 | };
57 |
--------------------------------------------------------------------------------
/config/webpack.config.common.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 |
3 | // Plugins
4 | const CircularDependencyPlugin = require("circular-dependency-plugin");
5 | const {
6 | useBabelRc,
7 | useEslintRc,
8 | enableEslintTypescript,
9 | } = require("customize-cra");
10 | // Utils
11 | const { loaderUtil } = require("./utils");
12 |
13 | // Paths
14 | const paths = require("./paths");
15 |
16 | // Loaders
17 | const { stylesLoaders } = require("./loaders/styles");
18 | const svgLoader = require("./loaders/svg");
19 |
20 | module.exports = function(config, isProd) {
21 | const { fileLoader, oneOf } = loaderUtil(config.module.rules);
22 |
23 | // Use the local .babelrc file
24 | useBabelRc();
25 |
26 | // Use custom .eslintrc file
27 | useEslintRc();
28 |
29 | // Enables Eslint Typescript
30 | enableEslintTypescript();
31 |
32 | // Resolve
33 | config.resolve = {
34 | ...config.resolve,
35 | modules: [...config.resolve.modules, "./src"],
36 | extensions: [...config.resolve.extensions, ".ts", ".tsx", ".js"],
37 | alias: {
38 | assets: `${paths.appSrc}/assets`,
39 | constants: `${paths.appSrc}/constants`,
40 | state: `${paths.appSrc}/state`,
41 | utils: `${paths.appSrc}/utils`,
42 | typings: `${paths.appSrc}/typings`,
43 | views: `${paths.appSrc}/views`,
44 | },
45 | };
46 |
47 | // Exclude the new file from the file loader, so we can add custom loader for them.
48 | fileLoader.exclude.push(/\.(sa|sc|c)ss$/);
49 |
50 | // // Extend with the extra loaders
51 | const loaders = [svgLoader, ...stylesLoaders(isProd)];
52 | if (oneOf) {
53 | oneOf.unshift(...loaders);
54 | } else {
55 | config.module.rules.push(...loaders);
56 | }
57 |
58 | // Plugins
59 | config.plugins = [
60 | ...config.plugins,
61 | new CircularDependencyPlugin({
62 | // exclude detection of files based on a RegExp
63 | exclude: /a\.js|node_modules/,
64 | // add errors to webpack instead of warnings
65 | failOnError: true,
66 | // set the current working directory for displaying module paths
67 | cwd: process.cwd(),
68 | }),
69 | ];
70 |
71 | return config;
72 | };
73 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |