Skip to content

Instantly share code, notes, and snippets.

@DouglasdeMoura
Last active September 7, 2021 15:08
Show Gist options
  • Save DouglasdeMoura/f634e337953eb21d11f4110d83798d80 to your computer and use it in GitHub Desktop.
Save DouglasdeMoura/f634e337953eb21d11f4110d83798d80 to your computer and use it in GitHub Desktop.
React template
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-typescript',
[
'@babel/preset-react',
{ runtime: 'automatic' }
],
]
};
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="Douglas Moura">
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
#!/usr/bin/env node
'use strict';
const fs = require('fs');
const cp = require('child_process');
const htmlTemplate = 'https://gist.githubusercontent.com/DouglasdeMoura/f634e337953eb21d11f4110d83798d80/raw/6676376ad7f54bb53013ec9c488f08900d962f29/index.html';
const webpackConfig = 'https://gist.githubusercontent.com/DouglasdeMoura/f634e337953eb21d11f4110d83798d80/raw/2ba3c05fd82fb7379e652bde76dba47e4f4eae63/webpack.config.js';
const editorConfig = 'https://gist.githubusercontent.com/DouglasdeMoura/f634e337953eb21d11f4110d83798d80/raw/d8c5f9ca68573304ff431babdb77209e8d4bce5f/.editorconfig';
const jestConfig = 'https://gist.githubusercontent.com/DouglasdeMoura/f634e337953eb21d11f4110d83798d80/raw/6e3326fd4358b1eaa84e0d6ceba9cfd518732a9b/jest.config.js';
const jestSetup = 'https://gist.githubusercontent.com/DouglasdeMoura/f634e337953eb21d11f4110d83798d80/raw/05f5cb4e7c13baa94b3ff72e11fd1195cd38ac78/jest.setup.js';
const tsConfig = 'https://gist.githubusercontent.com/DouglasdeMoura/f634e337953eb21d11f4110d83798d80/raw/fec2dfe4a0549e5547e875fd4812eec9d3c2dd26/tsconfig.json';
const babelConfig = 'https://gist.github.com/DouglasdeMoura/f634e337953eb21d11f4110d83798d80/raw/fc64143f70fe2982281ef49c9959f78d272ee4b9/babel.config.js';
const dependencies = [
'react',
'react-dom',
];
const devDependencies = [
'@babel/core',
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript',
'@pmmmwh/react-refresh-webpack-plugin',
'@testing-library/dom',
'@testing-library/jest-dom',
'@testing-library/react',
'@types/react',
'@types/react-dom',
'babel-jest',
'babel-loader',
'cross-env',
'css-loader',
'html-webpack-plugin',
'jest',
'react-refresh',
'style-loader',
'type-fest',
'typescript',
'webpack',
'webpack-cli',
'webpack-dev-server',
];
const logError = (message) => {
console.log('');
console.log(message);
process.exit(1);
};
const createDirectory = (dir) => {
if (!dir)
logError('Please provide a directory to start a new React project');
if (fs.existsSync(dir))
logError(`Directory '${dir}' already exists`);
fs.mkdirSync(dir);
}
const updatePackageJson = (dir) => {
const filename = `${dir}/package.json`;
const content = JSON.parse(fs.readFileSync(`${dir}/package.json`));
content.scripts = {
dev: 'webpack serve',
build: 'cross-env NODE_ENV=production webpack',
test: 'jest'
};
fs.writeFileSync(filename, JSON.stringify(content, null, 2));
}
const installDependencies = (dir) => {
const exec = (command) => (
console.log(cp.execSync(`cd ${dir} && ${command}`).toString())
);
exec('npm init -y');
exec(`npm i react react-dom ${dependencies.join(' ')}`);
exec(`npm i -D ${devDependencies.join(' ')}`);
exec(`npx gitignore node`);
exec('mkdir public src');
exec('touch src/index.tsx');
exec(`cd public && wget ${htmlTemplate}`);
exec(`wget ${webpackConfig}`);
exec(`wget ${editorConfig}`);
exec(`wget ${jestConfig}`);
exec(`wget ${jestSetup}`);
exec(`wget ${tsConfig}`);
exec(`wget ${babelConfig}`);
}
const [ , , dir] = process.argv;
createDirectory(dir);
installDependencies(dir);
updatePackageJson(dir);
module.exports = {
testIgnorePatterns: ['/node_modules/', '.next'],
setupFilesAfter: ['<rootDir>/jest.setup.js'],
transform: {
'^.\\.(js|jsx|ts|tsx)$': '<rootDir>/node_modules/babel-jest'
},
testEnvironment: 'jsdom',
};
import '@testing-library/jest-dom/extend-expect';
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"allowSyntheticDefaultImports": true,
"skipDefaultLibCheck": true,
"esModuleInterop": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src"]
}
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = {
mode: isDevelopment ? 'development' : 'production',
devtool: isDevelopment ? 'eval-source-map' : 'source-map',
entry: path.resolve(__dirname, 'src', 'index.tsx'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx']
},
devServer: {
contentBase: path.resolve(__dirname, 'public'),
hot: true,
},
plugins: [
isDevelopment && new ReactRefreshWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'public', 'index.html')
})
].filter(Boolean),
module: {
rules: [
{
test: /\.(j|t)sx$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: [
isDevelopment && require.resolve('react-refresh/babel')
].filter(Boolean)
}
}
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
]
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment