Skip to content

Instantly share code, notes, and snippets.

@ferdiebergado
Last active January 12, 2024 02:29
Show Gist options
  • Save ferdiebergado/fd9ced9056a053b8dfdc3ba38b768536 to your computer and use it in GitHub Desktop.
Save ferdiebergado/fd9ced9056a053b8dfdc3ba38b768536 to your computer and use it in GitHub Desktop.
My shell script to scaffold a new typescript project; usage: tsnew.sh [path]
#!/usr/bin/env bash
AUTHOR="Ferdinand Saporas Bergado <ferdiebergado@gmail.com> (https://github.com/ferdiebergado/)"
LICENSE=MIT
ROOT_DIR=src
OUT_DIR=out
### PROJECT ###
PROJECT_DIR=${1:-./tsproj}
mkdir "$PROJECT_DIR"
cd "$PROJECT_DIR" || exit
### ###
### NPM ###
npm init -y
npm pkg set author="$AUTHOR"
npm pkg set license=$LICENSE
npm pkg set scripts.dev="npx ts-node src/app.ts"
npm pkg set scripts.start="npx tsc && node ./out/app.js"
npm pkg set main="./out/app.js"
npm i -D typescript ts-node ts-jest @types/node @types/jest
npm i -D prettier --save-exact
npm i -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-config-standard-with-typescript eslint-plugin-import eslint-plugin-jest eslint-plugin-n eslint-plugin-promise eslint-plugin-security
npm i -D esbuild esbuild-sass-plugin stylelint stylelint-config-standard postcss postcss-preset-env postcss-scss autoprefixer
### ###
### TYPESCRIPT ###
npx tsc --init --rootDir $ROOT_DIR --outDir $OUT_DIR
### ###
### JEST ###
npm init jest@latest
sed -ri s'/^\s+\/\/ preset: undefined,/ preset: "ts-jest",/' jest.config.js
### ###
### ESLINT ###
npm init @eslint/config -- --config airbnb-typescript
cat <<EOF >tsconfig.eslint.json
{
"extends": ["./tsconfig.json"],
"include": ["./src/**/*.ts", "./tests/**/*.ts"]
}
EOF
cat <<EOF >.eslintrc.js
module.exports = {
env: {
es2021: true,
node: true,
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-type-checked',
'plugin:jest/recommended',
'prettier',
],
plugins: ['@typescript-eslint', 'import', 'security', 'n', 'promise', 'jest'],
parser: '@typescript-eslint/parser',
parserOptions: {
project: ['./tsconfig.eslint.json'],
tsconfigRootDir: __dirname,
ecmaVersion: 'latest',
sourceType: 'module',
warnOnUnsupportedTypeScriptVersion: true,
EXPERIMENTAL_useProjectService: true,
},
ignorePatterns: ['**/*.js', 'node_modules', 'out', '.netlify', 'netlify'],
overrides: [
{
files: ['.eslintrc.{js,cjs}'],
parserOptions: {
sourceType: 'script',
},
},
{
files: ['**/*.test.ts', '**/*.test.tsx'],
env: {
node: true,
jest: true,
},
},
{
files: ['src/client/**/*.ts'],
env: {
browser: true,
},
},
],
root: true,
};
EOF
### ###
### EDITORCONFIG ###
cat <<EOF >.editorconfig
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
[*.json]
indent_size = 2
# TypeScript files
[*.ts]
indent_size = 2
EOF
### PRETTIER ###
cat <<EOF >.prettierrc.json
{
"arrowParens": "avoid",
"singleQuote": true,
"tabWidth": 2,
"useTabs": false,
"trailingComma": "all",
"printWidth": 80
}
EOF
### ###
### STYLELINT ###
cat <<EOF >.stylelintrc.json
{
"extends": ["stylelint-config-standard"],
"overrides": [{ "files": ["**/*.scss"], "customSyntax": "postcss-scss" }]
}
EOF
### ESBUILD ###
cat <<EOF >build.dev.js
const esbuild = require('esbuild');
const postcss = require('postcss');
const autoprefixer = require('autoprefixer');
const postcssPresetEnv = require('postcss-preset-env');
const { sassPlugin } = require('esbuild-sass-plugin');
esbuild
.context({
entryPoints: ['src/app.ts'],
bundle: true,
outdir: 'public',
entryNames: '[name]',
sourcemap: true,
logLevel: 'info',
plugins: [
sassPlugin({
async transform(source, _resolveDir) {
const { css } = await postcss([
autoprefixer,
postcssPresetEnv({ stage: 0 }),
]).process(source, { from: undefined });
return css;
},
}),
],
})
.then(ctx => {
ctx.watch();
console.log('watching...');
})
.catch(() => process.exit(1));
EOF
cat <<EOF >build.js
const esbuild = require('esbuild');
const postcss = require('postcss');
const autoprefixer = require('autoprefixer');
const postcssPresetEnv = require('postcss-preset-env');
const { sassPlugin } = require('esbuild-sass-plugin');
esbuild
.build({
entryPoints: ['src/app.ts'],
bundle: true,
outdir: 'public',
entryNames: '[name]',
minify: true,
plugins: [
sassPlugin({
async transform(source, _resolveDir) {
const { css } = await postcss([
autoprefixer,
postcssPresetEnv({ stage: 0 }),
]).process(source, { from: undefined });
return css;
},
}),
],
})
.catch(() => process.exit(1));
EOF
### NETLIFY ###
cat <<EOF >netlify.toml
[build]
publish = "public"
[[headers]]
for = "/*"
[headers.values]
Referrer-Policy = "same-origin"
X-Content-Type-Options = "nosniff"
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
Content-Security-Policy = "default-src 'self'; script-src 'self'; font-src 'self' https://fonts.gstatic.com; style-src 'self' https://fonts.googleapis.com; img-src 'self'; connect-src 'self';"
EOF
### GIT ###
git init
curl -JLO https://github.com/github/gitignore.git
### ###
mkdir -p src/sass
mkdir tests
cat <<EOF >tests/app.test.ts
describe('Initial tests', () => {
test("test 1 is 1", () => {
expect(1).toBe(1);
});
});
EOF
cat <<EOF >src/sass/app.scss
:root {
--primary-color: #3498db;
--background-color: #eee;
--secondary-background-color: #fff;
--text-color: #333;
--link-color: var(--primary-color);
}
@media (prefers-color-scheme: dark) {
:root {
--primary-color: #1976d2;
--background-color: #222;
--secondary-background-color: #333;
--text-color: #fff;
--link-color: #0dd;
}
}
EOF
echo "import './sass/app.scss';" >src/app.ts
npm t
npm run dev
# vim: ft=sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment