From e85d5cc0414cf0389e2940581f918a771f24e3ee Mon Sep 17 00:00:00 2001 From: Patrick Balestra Date: Tue, 4 Feb 2020 15:59:55 +0100 Subject: [PATCH] Add react-ssr-template Signed-off-by: Patrick Balestra --- .../react-ssr-template/cookiecutter.json | 5 ++ .../react-ssr-template/custom-fields.json | 13 +++++ .../hooks/post_gen_project.sh | 12 +++++ .../hooks/pre_gen_project.sh | 9 ++++ .../.editorconfig | 13 +++++ .../.eslintignore | 1 + .../.eslintrc.js | 1 + .../{{cookiecutter.component_id}}/.gitignore | 18 +++++++ .../{{cookiecutter.component_id}}/.nvmrc | 1 + .../{{cookiecutter.component_id}}/README.md | 14 +++++ .../babel.config.js | 9 ++++ .../jest.config.js | 8 +++ .../next-env.d.ts | 5 ++ .../next.config.js | 3 ++ .../package.json | 52 +++++++++++++++++++ .../prettier.config.js | 1 + .../public/static/fonts.css | 0 .../src/__tests__/index.test.tsx | 13 +++++ .../src/components/Header.tsx | 7 +++ .../src/pages/_app.tsx | 37 +++++++++++++ .../src/pages/_document.tsx | 41 +++++++++++++++ .../src/pages/api/ping.ts | 5 ++ .../src/pages/index.tsx | 5 ++ .../tsconfig.json | 20 +++++++ 24 files changed, 293 insertions(+) create mode 100644 backend/scaffolder/templates/react-ssr-template/cookiecutter.json create mode 100644 backend/scaffolder/templates/react-ssr-template/custom-fields.json create mode 100644 backend/scaffolder/templates/react-ssr-template/hooks/post_gen_project.sh create mode 100644 backend/scaffolder/templates/react-ssr-template/hooks/pre_gen_project.sh create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.editorconfig create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.eslintignore create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.eslintrc.js create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.gitignore create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.nvmrc create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/README.md create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/babel.config.js create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/jest.config.js create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/next-env.d.ts create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/next.config.js create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/package.json create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/prettier.config.js create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/public/static/fonts.css create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/__tests__/index.test.tsx create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/components/Header.tsx create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/_app.tsx create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/_document.tsx create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/api/ping.ts create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/index.tsx create mode 100644 backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/tsconfig.json diff --git a/backend/scaffolder/templates/react-ssr-template/cookiecutter.json b/backend/scaffolder/templates/react-ssr-template/cookiecutter.json new file mode 100644 index 0000000000..3a1b2ae344 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/cookiecutter.json @@ -0,0 +1,5 @@ +{ + "component_id": "", + "owner": "", + "description": "I promise to update this description // {{cookiecutter.owner}}", +} diff --git a/backend/scaffolder/templates/react-ssr-template/custom-fields.json b/backend/scaffolder/templates/react-ssr-template/custom-fields.json new file mode 100644 index 0000000000..1acacc3a25 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/custom-fields.json @@ -0,0 +1,13 @@ +{ + "schema": [{ + "id": "owner", + "title": "owner", + "type": "text", + "description": "The owner name used to identify the owner of this component", + "validators": [ + { "type": "required" }, + { "type": "string-range", "min": 4, "max": 33 }, + { "type": "regex", "match": "^[a-z][a-z0-9]+$", "message": "Owner names must consist only of lowercase letters" } + ] + }] +} diff --git a/backend/scaffolder/templates/react-ssr-template/hooks/post_gen_project.sh b/backend/scaffolder/templates/react-ssr-template/hooks/post_gen_project.sh new file mode 100644 index 0000000000..c6d477d91a --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/hooks/post_gen_project.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# package name is "__component_id__" so that yarn doesn't throw an error +# about invalid characters when running yarn commands. here we replace it with the actual name +sed -i -e "s/__component_id__/{{ cookiecutter.component_id }}/g" package.json + +# node_modules was moved out of the template folder, during the pre_gen hook, +# to avoid cookie_cutter from copying all of them. time to move it back +mv ../../node_modules.tmp ../../\{\{cookiecutter.component_id\}\}/node_modules 2>/dev/null ||: + +# move back the build directory that was moved out in the pre_gen hook (if it exists) +mv ../../build.tmp ../../\{\{cookiecutter.component_id\}\}/build 2>/dev/null ||: \ No newline at end of file diff --git a/backend/scaffolder/templates/react-ssr-template/hooks/pre_gen_project.sh b/backend/scaffolder/templates/react-ssr-template/hooks/pre_gen_project.sh new file mode 100644 index 0000000000..142fda9ad9 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/hooks/pre_gen_project.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# no way to ignore files in cookiecutter, so move node_modules out while building +# to avoid cookiecutter from copying all of them +mv ../../\{\{cookiecutter.component_id\}\}/node_modules ../../node_modules.tmp 2>/dev/null ||: + +# cookicutter really doesn't like the next.js build directory, so if the app has +# been built from inside the template folder, that folders needs to be moved out as well +mv ../../\{\{cookiecutter.component_id\}\}/build ../../build.tmp 2>/dev/null ||: diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.editorconfig b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.editorconfig new file mode 100644 index 0000000000..23c3268a0f --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +insert_final_newline = false \ No newline at end of file diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.eslintignore b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.eslintignore new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.eslintignore @@ -0,0 +1 @@ + diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.eslintrc.js b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.eslintrc.js new file mode 100644 index 0000000000..8623614899 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@spotify/web-scripts/config/eslintrc.js'); diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.gitignore b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.gitignore new file mode 100644 index 0000000000..4d1e0d9635 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.gitignore @@ -0,0 +1,18 @@ +# See https://help.github.com/ignore-files/ for more about ignoring files. + +# dependencies +/node_modules + +# testing +/coverage +junit.xml + +# build +/build + +# misc +.DS_Store + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.nvmrc b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.nvmrc new file mode 100644 index 0000000000..b009dfb9d9 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/.nvmrc @@ -0,0 +1 @@ +lts/* diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/README.md b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/README.md new file mode 100644 index 0000000000..415065179b --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/README.md @@ -0,0 +1,14 @@ +# {{ cookiecutter.component_id }} + +## Description + +{{ cookiecutter.description }} + +## Develop + +```bash +# install dependencies +$ yarn +# start development server +$ yarn dev +``` \ No newline at end of file diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/babel.config.js b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/babel.config.js new file mode 100644 index 0000000000..038a71835e --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/babel.config.js @@ -0,0 +1,9 @@ +module.exports = { + plugins: [ + 'babel-plugin-styled-components' + ], + presets: [ + 'next/babel', + '@zeit/next-typescript/babel' + ] +}; diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/jest.config.js b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/jest.config.js new file mode 100644 index 0000000000..0dc2a9c0ca --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/jest.config.js @@ -0,0 +1,8 @@ +module.exports = { + ...require('@spotify/web-scripts/config/jest.config.js'), + testEnvironment: 'jsdom', + testPathIgnorePatterns: ['/node_modules/', '/build/'], + transform: { + '^.+\\.tsx?$': 'babel-jest', + }, +}; diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/next-env.d.ts b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/next-env.d.ts new file mode 100644 index 0000000000..fd10310f68 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/next-env.d.ts @@ -0,0 +1,5 @@ +// read more about this file here ---> https://github.com/zeit/next.js/blob/canary/docs/basic-features/typescript.md +/* eslint spaced-comment: ["error", "always", { "markers": ["/"] }] */ + +/// +/// diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/next.config.js b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/next.config.js new file mode 100644 index 0000000000..be8b159307 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/next.config.js @@ -0,0 +1,3 @@ +module.exports = { + distDir: 'build', +}; diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/package.json b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/package.json new file mode 100644 index 0000000000..cf9d469e39 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/package.json @@ -0,0 +1,52 @@ +{ + "name": "__component_id__", + "version": "0.0.0", + "description": "{{ cookiecutter.description }}", + "license": "UNLICENSED", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start", + "lint": "web-scripts lint --ignore-path=.gitignore", + "test": "web-scripts test --config jest.config.js", + "pretest:ci": "yarn lint", + "test:ci": "yarn test --ci --coverage --reporters=default --reporters=jest-junit" + }, + "dependencies": { + "@zeit/next-typescript": "^1.1.1", + "babel-plugin-styled-components": "^1.10.6", + "next": "^9.1.1", + "react": "^16.8.5", + "react-dom": "^16.8.5", + "styled-components": "^4.3.2" + }, + "devDependencies": { + "@spotify/tsconfig": "^5.0.0", + "@spotify/web-scripts": "^5.0.0", + "@testing-library/react": "^8.0.1", + "@types/node": "^13.1.4", + "@types/react": "^16.8.7", + "@types/react-dom": "^16.8.2", + "@types/styled-components": "^4.1.18", + "husky": "^2.7.0", + "jest-junit": "^8.0.0", + "typescript": "^3.4.5" + }, + "husky": { + "hooks": { + "pre-commit": "web-scripts precommit" + } + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/prettier.config.js b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/prettier.config.js new file mode 100644 index 0000000000..93df970dd6 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/prettier.config.js @@ -0,0 +1 @@ +module.exports = require('@spotify/web-scripts/config/prettier.config.js'); diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/public/static/fonts.css b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/public/static/fonts.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/__tests__/index.test.tsx b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/__tests__/index.test.tsx new file mode 100644 index 0000000000..8612ead08f --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/__tests__/index.test.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { cleanup, render } from '@testing-library/react'; + +import Index from '../pages/index'; + +afterEach(cleanup); + +describe('Index', () => { + it('Says hello', () => { + const { queryByText } = render(); + expect(queryByText('Hello!')).toBeTruthy(); + }); +}); diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/components/Header.tsx b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/components/Header.tsx new file mode 100644 index 0000000000..eebee43662 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/components/Header.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +export const Header = () => ( +

+ Header +

+) diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/_app.tsx b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/_app.tsx new file mode 100644 index 0000000000..a3853e47c9 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/_app.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import App from 'next/app'; +import Head from 'next/head'; +import styled from 'styled-components'; +import { Header } from '../components/Header'; + +const StyledApp = styled.div` + > * { + padding-left: 16px; + padding-right: 16px; + } +`; + +const Main = styled.div` + margin: 2em auto; + height: 85vh; +`; + +class CustomApp extends App { + render() { + const { Component, pageProps } = this.props; + + return ( + + + + +
+
+ +
+ + ); + } +} + +export default CustomApp; diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/_document.tsx b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/_document.tsx new file mode 100644 index 0000000000..210de6412c --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/_document.tsx @@ -0,0 +1,41 @@ +/** + * This file extends the and injects the server side rendered styles into the + * By server-side rendering CSS we avoid visual changes in the layout while loading the JS. + * + * Taken from this example: + * https://github.com/zeit/next.js/tree/master/examples/with-styled-components + */ + +import React from 'react'; +import Document, { DocumentContext, DocumentInitialProps } from 'next/document'; +import { ServerStyleSheet } from 'styled-components'; + +export default class MyDocument extends Document { + static async getInitialProps( + ctx: DocumentContext, + ): Promise { + const sheet = new ServerStyleSheet(); + const originalRenderPage = ctx.renderPage; + + try { + ctx.renderPage = () => + originalRenderPage({ + enhanceApp: (App: any) => props => + sheet.collectStyles(), + }); + + const initialProps = await Document.getInitialProps(ctx); + return { + ...initialProps, + styles: ( + <> + {initialProps.styles} + {sheet.getStyleElement()} + + ), + }; + } finally { + sheet.seal(); + } + } +} diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/api/ping.ts b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/api/ping.ts new file mode 100644 index 0000000000..8bc772c182 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/api/ping.ts @@ -0,0 +1,5 @@ +import { NextApiRequest, NextApiResponse } from 'next'; + +export default function handle(_: NextApiRequest, res: NextApiResponse) { + res.status(200).send('ok'); +} diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/index.tsx b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/index.tsx new file mode 100644 index 0000000000..c01d844f9f --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/src/pages/index.tsx @@ -0,0 +1,5 @@ +import React from 'react'; + +const Index = () =>

Hello!

; + +export default Index; diff --git a/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/tsconfig.json b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/tsconfig.json new file mode 100644 index 0000000000..03508ff043 --- /dev/null +++ b/backend/scaffolder/templates/react-ssr-template/{{cookiecutter.component_id}}/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "@spotify/tsconfig", + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve" + }, + "exclude": ["node_modules", "output/node_modules"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"] +}