Merge pull request #36 from spotify/react-ssr-template

Add react-ssr-template
This commit is contained in:
Patrick Balestra
2020-02-04 16:02:07 +01:00
committed by GitHub
24 changed files with 293 additions and 0 deletions
@@ -0,0 +1,5 @@
{
"component_id": "",
"owner": "",
"description": "I promise to update this description // {{cookiecutter.owner}}",
}
@@ -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" }
]
}]
}
@@ -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 ||:
@@ -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 ||:
@@ -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
@@ -0,0 +1 @@
module.exports = require('@spotify/web-scripts/config/eslintrc.js');
@@ -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*
@@ -0,0 +1,14 @@
# {{ cookiecutter.component_id }}
## Description
{{ cookiecutter.description }}
## Develop
```bash
# install dependencies
$ yarn
# start development server
$ yarn dev
```
@@ -0,0 +1,9 @@
module.exports = {
plugins: [
'babel-plugin-styled-components'
],
presets: [
'next/babel',
'@zeit/next-typescript/babel'
]
};
@@ -0,0 +1,8 @@
module.exports = {
...require('@spotify/web-scripts/config/jest.config.js'),
testEnvironment: 'jsdom',
testPathIgnorePatterns: ['/node_modules/', '/build/'],
transform: {
'^.+\\.tsx?$': 'babel-jest',
},
};
@@ -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": ["/"] }] */
/// <reference types="next" />
/// <reference types="next/types/global" />
@@ -0,0 +1,3 @@
module.exports = {
distDir: 'build',
};
@@ -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"
]
}
}
@@ -0,0 +1 @@
module.exports = require('@spotify/web-scripts/config/prettier.config.js');
@@ -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(<Index />);
expect(queryByText('Hello!')).toBeTruthy();
});
});
@@ -0,0 +1,7 @@
import React from 'react';
export const Header = () => (
<h1>
Header
</h1>
)
@@ -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 (
<StyledApp>
<Head>
<link rel="stylesheet" href="/static/fonts.css" />
</Head>
<Header />
<Main>
<Component {...pageProps} />
</Main>
</StyledApp>
);
}
}
export default CustomApp;
@@ -0,0 +1,41 @@
/**
* This file extends the <Document /> and injects the server side rendered styles into the <head>
* 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<DocumentInitialProps> {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App: any) => props =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
}
@@ -0,0 +1,5 @@
import { NextApiRequest, NextApiResponse } from 'next';
export default function handle(_: NextApiRequest, res: NextApiResponse) {
res.status(200).send('ok');
}
@@ -0,0 +1,5 @@
import React from 'react';
const Index = () => <h1>Hello!</h1>;
export default Index;
@@ -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"]
}