Skip to content

Instantly share code, notes, and snippets.

@guiseek
Last active January 29, 2023 03:19
Show Gist options
  • Save guiseek/b97e20d98da05a5057a079d6c91b880c to your computer and use it in GitHub Desktop.
Save guiseek/b97e20d98da05a5057a079d6c91b880c to your computer and use it in GitHub Desktop.
Comandos pra começar um projeto simples usando TypeScript + HTML + ESBuild, usando Shell Script
#!/bin/bash
# Para usar, dê permissão de execução ao script
# usando o comando: chmod +x create-project.sh
# e então execute: ./create-project.sh projeto
mkdir $1
cd $1
npm init -y
echo '{
"compilerOptions": {
"target": "es5",
"lib": [
"es2020",
"dom",
"dom.iterable"
],
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": false,
"skipLibCheck": true
}
}' > tsconfig.json
npm i -D esbuild esbuild-serve typescript@latest prettier
mkdir src
echo "document.addEventListener('DOMContentLoaded', () => {
const form = document.querySelector('form')
if (form) {
const button = form.querySelector('button')
if (button) button.disabled = true
form.onchange = () => {
const valid = !form.checkValidity()
if (button) button.disabled = valid
}
form.onsubmit = (ev) => {
ev.preventDefault()
const data = new FormData(form)
const values = Object.fromEntries(data.entries())
console.log(values)
}
}
})
" > src/main.ts
mkdir -p public/styles
echo '<!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" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;500&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="styles/main.css" />
<script src="main.js" defer></script>
<title>Página da Web</title>
</head>
<body>
<header>
<h1>'$1'</h1>
</header>
<main>
<article>
<h2>Artigo sobre JavaScript</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sin
laboramus, quis est, qui alienae modum statuat industriae? Traditur,
inquit, ab Epicuro ratio neglegendi doloris. Duo Reges: constructio
interrete. Te enim iudicem aequum puto, modo quae dicat ille bene
noris. Quamquam id quidem licebit iis existimare, qui legerint. Sed
quid sentiat, non videtis. Duo enim genera quae erant, fecit tria.
Quodsi ipsam honestatem undique pertectam atque absolutam. Odium autem
et invidiam facile vitabis. Consequens enim est et post oritur, ut
dixi.
</p>
<pre><code>document.addEventListener("DOMContentLoaded", () => {
const form = document.querySelector("form")
if (form) {
const button = form.querySelector("button")
if (button) button.disabled = true
form.onchange = () => {
const valid = !form.checkValidity()
if (button) button.disabled = valid
}
form.onsubmit = (ev) => {
ev.preventDefault()
const data = new FormData(form)
const values = Object.fromEntries(data.entries())
console.log(values)
}
}
})</code></pre>
</article>
<form>
<section>
<label for="name">Nome</label>
<input
id="name"
type="text"
autofocus
autocomplete="given-name"
name="name"
required
/>
<output>Obrigatório</output>
</section>
<section>
<label for="email">E-mail</label>
<input
id="email"
type="email"
name="email"
autocomplete="email"
required
/>
<output>Email inválido</output>
</section>
<section>
<label for="password">Senha</label>
<input
id="password"
type="password"
name="password"
autocomplete="new-password"
minlength="6"
required
/>
<output>Mínimo de 6 caracteres</output>
</section>
<section>
<label> <input type="checkbox" name="terms" /> Li e concordo com os termos </label>
</section>
<hr />
<button>Enviar</button>
</form>
</main>
<footer>&copy; 2021</footer>
</body>
</html>
' > public/index.html
echo ':root {
/* Palette generated by Material Palette
materialpalette.com/deep-purple/cyan */
--dark-primary-color: #512da8;
--default-primary-color: #673ab7;
--light-primary-color: #d1c4e9;
--text-primary-color: #ffffff;
--accent-color: #00bcd4;
--primary-text-color: #212121;
--secondary-text-color: #757575;
--divider-color: #bdbdbd;
--warn-color: #eb3535;
--default-font-family: "Fira Sans", sans-serif;
--default-element-margin: 6px;
--default-element-padding: 8px;
--default-block-padding: 10px;
--default-border-width: 2px;
--border-radius-xs: 2px;
--border-radius-sm: 4px;
--border-radius-md: 8px;
--border-radius-lg: 12px;
}
html,
body {
height: 100%;
}
body {
margin: 0;
display: flex;
flex-direction: column;
accent-color: var(--accent-color);
color: var(--primary-text-color);
font-family: var(--default-font-family);
}
main {
flex: 1;
padding: var(--default-block-padding);
}
header,
footer {
color: var(--text-primary-color);
padding: var(--default-block-padding);
background-color: var(--dark-primary-color);
}
button {
padding: var(--default-element-padding)
calc(var(--default-element-padding) * 2);
background-color: var(--default-primary-color);
border-radius: var(--border-radius-sm);
color: var(--text-primary-color);
border: 0;
}
button:disabled {
background-color: var(--light-primary-color);
}
button.accent {
background-color: var(--accent-color);
}
form section output {
visibility: hidden;
}
form.invalid input:invalid,
form section input:invalid:focus + output {
visibility: visible;
}
form section output {
color: var(--warn-color);
}
form section {
display: flex;
flex-direction: column;
margin-top: var(--default-element-margin);
margin-bottom: var(--default-element-margin);
}
input {
border-radius: var(--border-radius-sm);
padding: var(--default-element-padding);
border: var(--default-border-width) solid var(--dark-primary-color);
}
input[type="checkbox"] {
transform: scale(1.2);
}
pre {
padding: var(--default-block-padding);
background-color: var(--primary-text-color);
}
code {
font-size: 16px;
color: var(--light-primary-color);
}
' > public/styles/main.css
echo 'import esbuildServe from "esbuild-serve";
esbuildServe(
{
logLevel: "info",
entryPoints: ["src/main.ts"],
bundle: true,
outfile: "public/main.js",
sourcemap: true,
},
{ root: "public" }
);' > esbuild.config.js
echo '{
"semi": false,
"singleQuote": true
}' > .prettierrc
npx json -I -f package.json -e "this.type = 'module';"
npx json -I -f package.json -e "this.scripts.build = 'node esbuild.config.js';"
npx json -I -f package.json -e "this.scripts.start = 'node esbuild.config.js -w';"
npm start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment