chore: init

This commit is contained in:
Anthony Fu 2021-07-19 23:23:01 +08:00
commit a43d054604
34 changed files with 3678 additions and 0 deletions

3
.eslintignore Normal file
View File

@ -0,0 +1,3 @@
dist
node_modules
public

3
.eslintrc Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "@antfu"
}

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
github: antfu

12
.github/ISSUE_TEMPLATE/general.md vendored Normal file
View File

@ -0,0 +1,12 @@
---
name: General
about: General issue
title: ''
labels: ''
assignees: ''
---
PLEASE READ: I originally made this template for myself to mocking up apps quicker. I am glad to see you are willing to give it a try! Before your open the issue, please make sure you are reporting bugs in the template itself. **I am NOT creating this template to solve the problems you faced in your project, please use Vue or Vite's discord server to ask questions.** Thank you.
**Describe the bug/issue**

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
.DS_Store
.vite-ssg-dist
.vite-ssg-temp
*.local
dist
dist-ssr
node_modules
# intellij stuff
.idea/
# logs
*.log

1
.npmrc Normal file
View File

@ -0,0 +1 @@
shamefully-hoist=true

10
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,10 @@
{
"recommendations": [
"antfu.vite",
"johnsoncodehk.volar",
"antfu.iconify",
"dbaeumer.vscode-eslint",
"voorjaar.windicss-intellisense",
"csstools.postcss"
]
}

13
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,13 @@
{
"cSpell.words": ["Vitesse"],
"prettier.enable": false,
"typescript.tsdk": "node_modules/typescript/lib",
"volar.tsPlugin": true,
"volar.tsPluginStatus": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
},
"files.associations": {
"*.css": "postcss",
},
}

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-2021 Anthony Fu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

66
README.md Normal file
View File

@ -0,0 +1,66 @@
<p align='center'>
<img src='https://user-images.githubusercontent.com/11247099/111864893-a457fd00-899e-11eb-9f05-f4b88987541d.png' alt='Vitesse - Opinionated Vite Starter Template' width='600'/>
</p>
<h6 align='center'>
<a href="https://vitesse.netlify.app/">Live Demo</a>
</h6>
<h5 align='center'>
<b>Lightweight version of <a href="https://github.com/antfu/vitesse">Vitesse</a></b>
</h5>
<br>
## Dropped Features
- ~~i18n~~
- ~~Layouts~~
- ~~SSG~~
- ~~PWA~~
- ~~Markdown~~
## Features
- ⚡️ [Vue 3](https://github.com/vuejs/vue-next), [Vite 2](https://github.com/vitejs/vite), [pnpm](https://pnpm.js.org/), [ESBuild](https://github.com/evanw/esbuild) - born with fastness
- 🗂 [File based routing](./src/pages)
- 📦 [Components auto importing](./src/components)
- 🎨 [Windi CSS](https://github.com/windicss/windicss) - next generation utility-first CSS framework
- 😃 [Use icons from any icon sets, with no compromise](./src/components)
- 🔥 Use the [new `<script setup>` style](https://github.com/vuejs/rfcs/pull/227)
- 🦾 TypeScript, of course
- ☁️ Deploy on Netlify, zero-config
See [Vitesse](https://github.com/antfu/vitesse) for full featureset.
<br>
## Pre-packed
### UI Frameworks
- [Windi CSS](https://github.com/windicss/windicss) (On-demand [TailwindCSS](https://tailwindcss.com/)) - lighter and faster, with a bunch of additional features!
- [Windi CSS Typography](https://windicss.org/plugins/official/typography.html)
### Icons
- [Iconify](https://iconify.design) - use icons from any icon sets [🔍Icônes](https://icones.netlify.app/)
- [`vite-plugin-icons`](https://github.com/antfu/vite-plugin-icons) - icons as Vue components
### Plugins
- [Vue Router](https://github.com/vuejs/vue-router)
- [`vite-plugin-pages`](https://github.com/hannoeru/vite-plugin-pages) - file system based routing
- [`vite-plugin-components`](https://github.com/antfu/vite-plugin-components) - components auto import
- [`vite-plugin-windicss`](https://github.com/antfu/vite-plugin-windicss) - WindiCSS support
- [VueUse](https://github.com/antfu/vueuse) - collection of useful composition APIs
- [`@vueuse/head`](https://github.com/vueuse/head) - manipulate document head reactively
- [`vue-global-api`](https://github.com/antfu/vue-global-api) - Use Vue Composition API globally

15
components.d.ts vendored Normal file
View File

@ -0,0 +1,15 @@
// generated by vite-plugin-components
// read more https://github.com/vuejs/vue-next/pull/3399
declare module 'vue' {
export interface GlobalComponents {
CarbonCampsite: typeof import('virtual:vite-icons/carbon/campsite')['default']
CarbonLogoGithub: typeof import('virtual:vite-icons/carbon/logo-github')['default']
CarbonMoon: typeof import('virtual:vite-icons/carbon/moon')['default']
CarbonPedestrian: typeof import('virtual:vite-icons/carbon/pedestrian')['default']
CarbonSun: typeof import('virtual:vite-icons/carbon/sun')['default']
Footer: typeof import('./src/components/Footer.vue')['default']
}
}
export { }

22
index.html Normal file
View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/pwa-192x192.png">
<meta name="theme-color" content="#ffffff">
</head>
<body>
<div id="app"></div>
<script>
(function() {
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
const setting = localStorage.getItem('color-schema') || 'auto'
if (setting === 'dark' || (prefersDark && setting !== 'light'))
document.documentElement.classList.toggle('dark', true)
})()
</script>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

17
netlify.toml Executable file
View File

@ -0,0 +1,17 @@
[build.environment]
NPM_FLAGS = "--prefix=/dev/null"
NODE_VERSION = "14"
[build]
publish = "dist"
command = "npx pnpm i --store=node_modules/.pnpm-store && npx pnpm run build"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[[headers]]
for = "/manifest.webmanifest"
[headers.values]
Content-Type = "application/manifest+json"

32
package.json Normal file
View File

@ -0,0 +1,32 @@
{
"private": true,
"scripts": {
"dev": "vite --port 3333 --open",
"build": "cross-env NODE_ENV=production vite build",
"preview": "vite preview"
},
"dependencies": {
"@vueuse/core": "^5.1.3",
"@vueuse/head": "^0.6.0",
"vue": "^3.1.4",
"vue-demi": "^0.11.2",
"vue-global-api": "^0.2.4",
"vue-router": "^4.0.10"
},
"devDependencies": {
"@antfu/eslint-config": "^0.7.0",
"@iconify/json": "^1.1.376",
"@typescript-eslint/eslint-plugin": "^4.28.3",
"@vitejs/plugin-vue": "^1.2.5",
"@vue/compiler-sfc": "^3.1.4",
"cross-env": "^7.0.3",
"eslint": "^7.30.0",
"pnpm": "^6.10.1",
"typescript": "^4.3.5",
"vite": "^2.4.2",
"vite-plugin-components": "^0.12.2",
"vite-plugin-icons": "^0.6.5",
"vite-plugin-pages": "^0.15.0",
"vite-plugin-windicss": "^1.2.4"
}
}

3071
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

9
public/favicon.svg Normal file
View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<style>
path { fill: #222; }
@media (prefers-color-scheme: dark) {
path { fill: #ffffff; }
}
</style>
<path d="M27.562 26L17.17 8.928l2.366-3.888L17.828 4L16 7.005L14.17 4l-1.708 1.04l2.366 3.888L4.438 26H2v2h28v-2zM16 10.85L25.22 26H17v-8h-2v8H6.78z" />
</svg>

After

Width:  |  Height:  |  Size: 347 B

BIN
public/pwa-192x192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
public/pwa-512x512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

2
public/robots.txt Normal file
View File

@ -0,0 +1,2 @@
User-agent: *
Allow: /

20
src/App.vue Normal file
View File

@ -0,0 +1,20 @@
<script setup lang="ts">
import { useHead } from '@vueuse/head'
// https://github.com/vueuse/head
// you can use this to manipulate the document head in any components,
// they will be rendered correctly in the html results with vite-ssg
useHead({
title: 'Vitesse Lite',
meta: [
{ name: 'description', content: 'Opinionated Vite Starter Template' },
],
})
</script>
<template>
<main class="px-4 py-10 text-center text-gray-700 dark:text-gray-200">
<router-view />
<Footer />
</main>
</template>

16
src/components/Footer.vue Normal file
View File

@ -0,0 +1,16 @@
<script setup lang="ts">
import { isDark, toggleDark } from '~/logic'
</script>
<template>
<nav class="text-xl mt-6">
<button class="icon-btn mx-2 !outline-none" @click="toggleDark">
<carbon-moon v-if="isDark" />
<carbon-sun v-else />
</button>
<a class="icon-btn mx-2" rel="noreferrer" href="https://github.com/antfu/vitesse-lite" target="_blank" title="GitHub">
<carbon-logo-github />
</a>
</nav>
</template>

10
src/components/README.md Normal file
View File

@ -0,0 +1,10 @@
## Components
Components in this dir will be auto-registered and on-demand, powered by [`vite-plugin-components`](https://github.com/antfu/vite-plugin-components).
### Icons
You can use icons from almost any icon sets by the power of [Iconify](https://iconify.design/).
It will only bundle the icons you use. Check out [vite-plugin-icons](https://github.com/antfu/vite-plugin-icons) for more details.

4
src/logic/dark.ts Normal file
View File

@ -0,0 +1,4 @@
import { useDark, useToggle } from '@vueuse/core'
export const isDark = useDark()
export const toggleDark = useToggle(isDark)

1
src/logic/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './dark'

24
src/main.ts Normal file
View File

@ -0,0 +1,24 @@
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import routes from 'virtual:generated-pages'
import { createHead } from '@vueuse/head'
import App from './App.vue'
// windicss layers
import 'virtual:windi-base.css'
import 'virtual:windi-components.css'
import './styles/main.css'
import 'virtual:windi-utilities.css'
// register vue composition api globally
import 'vue-global-api'
const app = createApp(App)
const router = createRouter({
history: createWebHistory(),
routes,
})
const head = createHead()
app.use(head)
app.use(router)
app.mount('#app')

20
src/pages/README.md Normal file
View File

@ -0,0 +1,20 @@
## File-based Routing
Routes will be auto-generated for Vue files in this dir with the same file structure.
Check out [`vite-plugin-pages`](https://github.com/hannoeru/vite-plugin-pages) for more details.
### Path Aliasing
`~/` is aliased to `./src/` folder.
For example, instead of having
```ts
import { isDark } from '../../../../logic'
```
now, you can use
```ts
import { isDark } from '~/logic'
```

10
src/pages/[...all].vue Executable file
View File

@ -0,0 +1,10 @@
<template>
<div>
Not Found
</div>
</template>
<route lang="yaml">
meta:
layout: 404
</route>

29
src/pages/hi/[name].vue Normal file
View File

@ -0,0 +1,29 @@
<script setup lang="ts">
import { useRouter } from 'vue-router'
const props = defineProps<{ name: string }>()
const router = useRouter()
</script>
<template>
<div>
<p class="text-4xl">
<carbon-pedestrian class="inline-block" />
</p>
<p>
Hi, {{ props.name }}
</p>
<p class="text-sm opacity-50">
<em>Dynamic route!</em>
</p>
<div>
<button
class="btn m-3 text-sm mt-8"
@click="router.back()"
>
Back
</button>
</div>
</div>
</template>

54
src/pages/index.vue Normal file
View File

@ -0,0 +1,54 @@
<script setup lang="ts">
import { useRouter } from 'vue-router'
const name = ref('')
const router = useRouter()
const go = () => {
if (name.value)
router.push(`/hi/${encodeURIComponent(name.value)}`)
}
</script>
<template>
<div>
<p class="text-4xl">
<carbon-campsite class="inline-block" />
</p>
<p>
<a rel="noreferrer" href="https://github.com/antfu/vitesse-lite" target="_blank">
Vitesse Lite
</a>
</p>
<p>
<em class="text-sm opacity-75">Opinionated Vite Starter Template</em>
</p>
<div class="py-4" />
<input
id="input"
v-model="name"
placeholder="What's your name?"
type="text"
autocomplete="false"
p="x-4 y-2"
w="250px"
text="center"
bg="transparent"
border="~ rounded gray-200 dark:gray-700"
outline="none active:none"
@keydown.enter="go"
>
<div>
<button
class="m-3 text-sm btn"
:disabled="!name"
@click="go"
>
Go
</button>
</div>
</div>
</template>

12
src/shims.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
/* eslint-disable import/no-duplicates */
declare interface Window {
// extend the window
}
// with vite-plugin-md, markdowns can be treat as Vue components
declare module '*.md' {
import { ComponentOptions } from 'vue'
const component: ComponentOptions
export default component
}

41
src/styles/main.css Executable file
View File

@ -0,0 +1,41 @@
html,
body,
#app {
height: 100%;
margin: 0;
padding: 0;
}
html.dark {
background: #121212;
}
#nprogress {
pointer-events: none;
}
#nprogress .bar {
@apply bg-teal-600 opacity-75;
position: fixed;
z-index: 1031;
top: 0;
left: 0;
width: 100%;
height: 2px;
}
.btn {
@apply px-4 py-1 rounded inline-block
bg-teal-600 text-white cursor-pointer
hover:bg-teal-700
disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50;
}
.icon-btn {
@apply inline-block cursor-pointer select-none
opacity-75 transition duration-200 ease-in-out
hover:opacity-100 hover:text-teal-600;
font-size: 0.9em;
}

26
tsconfig.json Normal file
View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"baseUrl": ".",
"module": "ESNext",
"target": "es2016",
"lib": ["DOM", "ESNext"],
"strict": true,
"esModuleInterop": true,
"incremental": false,
"skipLibCheck": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"noUnusedLocals": true,
"strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"types": [
"vite/client",
"vite-plugin-pages/client",
"vite-plugin-vue-layouts/client"
],
"paths": {
"~/*": ["src/*"]
}
},
"exclude": ["dist", "node_modules"]
}

59
vite.config.ts Normal file
View File

@ -0,0 +1,59 @@
import path from 'path'
import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import Pages from 'vite-plugin-pages'
import ViteIcons, { ViteIconsResolver } from 'vite-plugin-icons'
import ViteComponents from 'vite-plugin-components'
import WindiCSS from 'vite-plugin-windicss'
export default defineConfig({
resolve: {
alias: {
'~/': `${path.resolve(__dirname, 'src')}/`,
},
},
plugins: [
Vue(),
// https://github.com/hannoeru/vite-plugin-pages
Pages(),
// https://github.com/antfu/vite-plugin-components
ViteComponents({
// generate `components.d.ts` for ts support with Volar
globalComponentsDeclaration: true,
// auto import icons
customComponentResolvers: [
// https://github.com/antfu/vite-plugin-icons
ViteIconsResolver({
componentPrefix: '',
// enabledCollections: ['carbon']
}),
],
}),
// https://github.com/antfu/vite-plugin-icons
ViteIcons(),
// https://github.com/antfu/vite-plugin-windicss
WindiCSS(),
],
server: {
fs: {
strict: true,
},
},
optimizeDeps: {
include: [
'vue',
'vue-router',
'@vueuse/core',
],
exclude: [
'vue-demi',
],
},
})

43
windi.config.ts Normal file
View File

@ -0,0 +1,43 @@
import { defineConfig } from 'windicss/helpers'
import colors from 'windicss/colors'
import typography from 'windicss/plugin/typography'
export default defineConfig({
darkMode: 'class',
// https://windicss.org/posts/v30.html#attributify-mode
attributify: true,
plugins: [
typography(),
],
theme: {
extend: {
typography: {
DEFAULT: {
css: {
maxWidth: '65ch',
color: 'inherit',
a: {
'color': 'inherit',
'opacity': 0.75,
'fontWeight': '500',
'textDecoration': 'underline',
'&:hover': {
opacity: 1,
color: colors.teal[600],
},
},
b: { color: 'inherit' },
strong: { color: 'inherit' },
em: { color: 'inherit' },
h1: { color: 'inherit' },
h2: { color: 'inherit' },
h3: { color: 'inherit' },
h4: { color: 'inherit' },
code: { color: 'inherit' },
},
},
},
},
},
})