Add react-ssr-template
Signed-off-by: Patrick Balestra <patrickb@spotify.com>
This commit is contained in:
@@ -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 ||:
|
||||
+13
@@ -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
|
||||
+1
@@ -0,0 +1 @@
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = require('@spotify/web-scripts/config/eslintrc.js');
|
||||
+18
@@ -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 @@
|
||||
lts/*
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
# {{ cookiecutter.component_id }}
|
||||
|
||||
## Description
|
||||
|
||||
{{ cookiecutter.description }}
|
||||
|
||||
## Develop
|
||||
|
||||
```bash
|
||||
# install dependencies
|
||||
$ yarn
|
||||
# start development server
|
||||
$ yarn dev
|
||||
```
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
'babel-plugin-styled-components'
|
||||
],
|
||||
presets: [
|
||||
'next/babel',
|
||||
'@zeit/next-typescript/babel'
|
||||
]
|
||||
};
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
...require('@spotify/web-scripts/config/jest.config.js'),
|
||||
testEnvironment: 'jsdom',
|
||||
testPathIgnorePatterns: ['/node_modules/', '/build/'],
|
||||
transform: {
|
||||
'^.+\\.tsx?$': 'babel-jest',
|
||||
},
|
||||
};
|
||||
Vendored
+5
@@ -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" />
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
distDir: 'build',
|
||||
};
|
||||
+52
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = require('@spotify/web-scripts/config/prettier.config.js');
|
||||
+13
@@ -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();
|
||||
});
|
||||
});
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
export const Header = () => (
|
||||
<h1>
|
||||
Header
|
||||
</h1>
|
||||
)
|
||||
+37
@@ -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;
|
||||
+41
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
export default function handle(_: NextApiRequest, res: NextApiResponse) {
|
||||
res.status(200).send('ok');
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
const Index = () => <h1>Hello!</h1>;
|
||||
|
||||
export default Index;
|
||||
+20
@@ -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"]
|
||||
}
|
||||
Reference in New Issue
Block a user