Skip to content

Commit 748c049

Browse files
committed
chore: initial commit
0 parents  commit 748c049

15 files changed

+6185
-0
lines changed

.babelrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["@babel/env", "@babel/react", "@babel/preset-typescript"]
3+
}

.eslintrc.yml

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
parser: '@typescript-eslint/parser'
2+
3+
extends:
4+
- 'eslint:recommended'
5+
- 'plugin:react/recommended'
6+
- 'plugin:react-hooks/recommended'
7+
- 'plugin:@typescript-eslint/recommended'
8+
- 'prettier'
9+
10+
rules:
11+
'@typescript-eslint/explicit-module-boundary-types': off
12+
'@typescript-eslint/ban-ts-comment': off
13+
'@typescript-eslint/explicit-member-accessibility': off
14+
'@typescript-eslint/explicit-function-return-type': off
15+
'@typescript-eslint/no-explicit-any': off
16+
'@typescript-eslint/interface-name-prefix': off
17+
'@typescript-eslint/no-empty-interface': off
18+
'@typescript-eslint/no-object-literal-type-assertion': off
19+
'@typescript-eslint/ban-types': off
20+
'@typescript-eslint/no-non-null-assertion': off
21+
'@typescript-eslint/no-parameter-properties': off
22+
'@typescript-eslint/ban-ts-ignore': off
23+
'@typescript-eslint/no-unused-vars':
24+
- error
25+
- vars: all
26+
args: after-used
27+
ignoreRestSiblings: true
28+
'react/display-name': off
29+
'react/prop-types': off
30+
31+
settings:
32+
react:
33+
version: detect

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* text=auto
2+
yarn.lock binary

.gitignore

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# dependencies
2+
/node_modules
3+
4+
# production
5+
/dist
6+
7+
# misc
8+
.DS_Store
9+
.env*
10+
.vscode
11+
12+
# debug
13+
npm-debug.log*
14+
yarn-debug.log*
15+
yarn-error.log*

.prettierrc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"singleQuote": true,
3+
"tabWidth": 2,
4+
"useTabs": false,
5+
"printWidth": 120,
6+
"arrowParens": "always",
7+
"trailingComma": "none"
8+
}

README.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# React Typescript Tailwind Template
2+
3+
Web app react template with typescript and tailwindcss with Fast Refresh HMR.
4+
5+
## Development
6+
7+
`yarn dev`
8+
9+
`yarn lint`
10+
11+
`yarn typecheck`
12+
13+
## Build
14+
15+
`yarn build`
16+
17+
## Analyze bundle
18+
19+
`yarn analyze`

package.json

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"name": "react-typescript-tailwind-template",
3+
"description": "Web app react template with typescript and tailwindcss.",
4+
"keywords": [
5+
"react",
6+
"typescript",
7+
"tailwindcss"
8+
],
9+
"version": "1.0.0",
10+
"main": "src/index.ts",
11+
"author": "Botond Veress <[email protected]>",
12+
"license": "MIT",
13+
"scripts": {
14+
"dev": "webpack serve",
15+
"lint": "eslint --max-warnings 0 --ext .tsx --ext .ts src/",
16+
"typecheck": "tsc --noEmit",
17+
"build": "webpack --mode=production",
18+
"analyze": "webpack --mode=production --profile --json > stats.json && webpack-bundle-analyzer --mode static stats.json dist"
19+
},
20+
"dependencies": {
21+
"react": "^17.0.2",
22+
"react-dom": "^17.0.2",
23+
"tailwindcss": "^2.2.16",
24+
"typescript": "^4.4.3"
25+
},
26+
"devDependencies": {
27+
"@babel/core": "^7.15.8",
28+
"@babel/preset-env": "^7.15.8",
29+
"@babel/preset-react": "^7.14.5",
30+
"@babel/preset-typescript": "^7.15.0",
31+
"@babel/register": "^7.15.3",
32+
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
33+
"@types/css-minimizer-webpack-plugin": "^3.0.2",
34+
"@types/mini-css-extract-plugin": "^2.3.0",
35+
"@types/react": "^17.0.27",
36+
"@types/react-dom": "^17.0.9",
37+
"@types/webpack-dev-server": "^4.3.1",
38+
"@typescript-eslint/eslint-plugin": "^4.33.0",
39+
"@typescript-eslint/parser": "^4.33.0",
40+
"autoprefixer": "^10.3.7",
41+
"babel-loader": "^8.2.2",
42+
"css-loader": "^6.4.0",
43+
"css-minimizer-webpack-plugin": "^3.1.1",
44+
"eslint": "^7.32.0",
45+
"eslint-config-prettier": "^8.3.0",
46+
"eslint-plugin-react": "^7.26.1",
47+
"eslint-plugin-react-hooks": "^4.2.0",
48+
"html-webpack-plugin": "^5.3.2",
49+
"mini-css-extract-plugin": "^2.4.2",
50+
"postcss": "^8.3.9",
51+
"postcss-loader": "^6.1.1",
52+
"prettier": "^2.4.1",
53+
"react-refresh": "^0.10.0",
54+
"style-loader": "^3.3.0",
55+
"type-fest": "^2.3.4",
56+
"webpack": "^5.58.1",
57+
"webpack-bundle-analyzer": "^4.4.2",
58+
"webpack-cli": "^4.9.0",
59+
"webpack-dev-server": "^4.3.1"
60+
}
61+
}

postcss.config.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {}
5+
}
6+
};

src/App.tsx

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react';
2+
3+
export const App: React.FC = () => (
4+
<div className="max-w-7xl mx-auto space-y-4">
5+
<header>
6+
<small className="text-small text-gray-500 font-semibold tracking-wide uppercase">Header</small>
7+
</header>
8+
9+
<main>
10+
<small className="text-small text-gray-500 font-semibold tracking-wide uppercase">Main</small>
11+
</main>
12+
13+
<footer className="divide-y-2 divide-gray-900">
14+
<small className="text-small text-gray-500 font-semibold tracking-wide uppercase">Footer</small>
15+
</footer>
16+
</div>
17+
);

src/index.html

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<html lang="en" dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
3+
<head>
4+
<base href="/" />
5+
6+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
7+
<meta name="format-detection" content="telephone=no" />
8+
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
9+
<meta charset="utf-8" />
10+
11+
<title>React</title>
12+
</head>
13+
14+
<body>
15+
<div id="app"></div>
16+
</body>
17+
</html>

src/index.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import React from 'react';
2+
import { render } from 'react-dom';
3+
4+
import 'tailwindcss/tailwind.css';
5+
6+
import { App } from '@/App';
7+
8+
render(<App />, document.getElementById('app'));

tailwind.config.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module.exports = {
2+
mode: 'jit',
3+
purge: ['./src/**/*.{ts,tsx}'],
4+
darkMode: false, // or 'media' or 'class'
5+
theme: {
6+
extend: {}
7+
},
8+
variants: {
9+
extend: {}
10+
},
11+
plugins: []
12+
};

tsconfig.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"target": "esnext",
4+
"moduleResolution": "node",
5+
"baseUrl": ".",
6+
"paths": {
7+
"@/*": ["src/*"]
8+
},
9+
"allowJs": true,
10+
"strict": true,
11+
"isolatedModules": true,
12+
"esModuleInterop": true,
13+
"outDir": "dist",
14+
"jsx": "react",
15+
"skipLibCheck": true,
16+
"forceConsistentCasingInFileNames": true,
17+
"sourceMap": true
18+
},
19+
"include": ["./src/**/*"]
20+
}

webpack.config.ts

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import path from 'path';
2+
import webpack from 'webpack';
3+
import HtmlWebpackPlugin from 'html-webpack-plugin';
4+
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
5+
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
6+
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
7+
8+
const directories = {
9+
source: 'src',
10+
distribution: 'dist'
11+
};
12+
13+
export default (env, { mode }): webpack.Configuration => {
14+
const production = mode === 'production';
15+
16+
return {
17+
mode: production ? 'production' : 'development',
18+
devtool: production ? 'source-map' : 'eval',
19+
entry: {
20+
app: path.resolve(directories.source, 'index.tsx')
21+
},
22+
devServer: !production
23+
? {
24+
compress: true,
25+
historyApiFallback: true,
26+
hot: true,
27+
host: '0.0.0.0',
28+
port: 3000
29+
}
30+
: undefined,
31+
output: {
32+
path: path.resolve(directories.distribution),
33+
filename: 'assets/scripts/[name].bundle.js',
34+
chunkFilename: 'assets/scripts/[id].chunk.js',
35+
clean: true
36+
},
37+
module: {
38+
rules: [
39+
{
40+
exclude: /node_modules/,
41+
loader: 'babel-loader',
42+
test: /\.tsx?$/,
43+
options: {
44+
plugins: production ? [] : ['react-refresh/babel']
45+
}
46+
},
47+
{
48+
test: /\.css$/,
49+
use: [production ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader', 'postcss-loader']
50+
}
51+
]
52+
},
53+
resolve: {
54+
alias: {
55+
'@': path.resolve(directories.source)
56+
},
57+
extensions: ['.js', '.jsx', '.ts', '.tsx']
58+
},
59+
plugins: [
60+
new HtmlWebpackPlugin({
61+
template: path.join(directories.source, 'index.html')
62+
}),
63+
...(production
64+
? [
65+
new MiniCssExtractPlugin({
66+
filename: 'assets/stylesheets/[name].css',
67+
chunkFilename: 'assets/stylesheets/[id].css'
68+
})
69+
]
70+
: [new ReactRefreshWebpackPlugin()])
71+
],
72+
optimization: {
73+
minimizer: [
74+
`...`,
75+
...(production
76+
? [
77+
new CssMinimizerPlugin({
78+
minimizerOptions: {
79+
preset: ['default', { discardComments: { removeAll: true } }]
80+
}
81+
})
82+
]
83+
: [])
84+
]
85+
}
86+
};
87+
};

0 commit comments

Comments
 (0)