Merge branch 'vue-3'
commit
acb115bb0c
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules/
|
||||||
|
dist/
|
|
@ -0,0 +1,7 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = false
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
|
@ -0,0 +1,15 @@
|
||||||
|
env:
|
||||||
|
browser: true
|
||||||
|
es2021: true
|
||||||
|
vue/setup-compiler-macros: true
|
||||||
|
extends:
|
||||||
|
- 'plugin:vue/vue3-recommended'
|
||||||
|
- standard
|
||||||
|
parserOptions:
|
||||||
|
ecmaVersion: 13
|
||||||
|
parser: '@typescript-eslint/parser'
|
||||||
|
sourceType: module
|
||||||
|
plugins:
|
||||||
|
- vue
|
||||||
|
- '@typescript-eslint'
|
||||||
|
rules: {}
|
|
@ -0,0 +1,5 @@
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
25
Dockerfile
25
Dockerfile
|
@ -1,3 +1,26 @@
|
||||||
|
# ======Building the project=====
|
||||||
|
FROM node:17.2.0 AS builder
|
||||||
|
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
# Install Node dependencies
|
||||||
|
COPY package.json yarn.lock ./
|
||||||
|
RUN yarn install
|
||||||
|
|
||||||
|
# Copy over source code & build project
|
||||||
|
COPY vite.config.ts tsconfig.json index.html ./
|
||||||
|
COPY src/ ./src
|
||||||
|
COPY public/ ./public
|
||||||
|
RUN yarn run build
|
||||||
|
|
||||||
|
|
||||||
|
# =====Packaging inside an Nginx container=====
|
||||||
FROM nginx:1.21.4-alpine
|
FROM nginx:1.21.4-alpine
|
||||||
|
|
||||||
COPY default.conf.template /etc/nginx/templates/default.conf.template
|
# Copy over the Nginx config files
|
||||||
|
COPY nginx/nginx.conf /etc/nginx/nginx.conf
|
||||||
|
COPY nginx/*.conf.template /etc/nginx/templates/
|
||||||
|
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
# Copy over build artifacts
|
||||||
|
COPY --from=builder /usr/src/app/dist /usr/share/nginx/html
|
||||||
|
|
12
README.md
12
README.md
|
@ -1,3 +1,11 @@
|
||||||
# web
|
# Vue 3 + Typescript + Vite
|
||||||
|
|
||||||
Frontend microservice for the Rusty Bever blogging software.
|
This template should help get you started developing with Vue 3 and Typescript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||||
|
|
||||||
|
## Recommended IDE Setup
|
||||||
|
|
||||||
|
- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)
|
||||||
|
|
||||||
|
## Type Support For `.vue` Imports in TS
|
||||||
|
|
||||||
|
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's `.vue` type support plugin by running `Volar: Switch TS Plugin on/off` from VSCode command palette.
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite App</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,20 @@
|
||||||
|
# vim: ft=nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
|
||||||
|
# =====FRONTEND HOSTING=====
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 404 /404.html;
|
||||||
|
|
||||||
|
# redirect server error pages to the static page /50x.html
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
# vim: ft=nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
location /api/v1/posts/ {
|
||||||
|
proxy_pass http://${RB_BLOG}/v1/posts/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/v1/sections/ {
|
||||||
|
proxy_pass http://${RB_BLOG}/v1/sections/;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
# vim: ft=nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
|
||||||
|
# =====MATRIX WELL-KNOWN FILES=====
|
||||||
|
# Used for server federation
|
||||||
|
location = /.well-known/matrix/server {
|
||||||
|
charset utf-8;
|
||||||
|
default_type application/json;
|
||||||
|
|
||||||
|
if ($request_method = 'GET') {
|
||||||
|
add_header Access-Control-Allow-Origin '*';
|
||||||
|
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
|
||||||
|
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type, Authorization';
|
||||||
|
|
||||||
|
return 200 '{"m.server":"${MATRIX_SERVER}"}';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request_method = 'OPTIONS') {
|
||||||
|
add_header Access-Control-Allow-Origin '*';
|
||||||
|
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
|
||||||
|
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type, Authorization';
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 405;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /.well-known/matrix/client {
|
||||||
|
charset utf-8;
|
||||||
|
default_type application/json;
|
||||||
|
|
||||||
|
if ($request_method = 'GET') {
|
||||||
|
add_header Access-Control-Allow-Origin '*';
|
||||||
|
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
|
||||||
|
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type, Authorization';
|
||||||
|
|
||||||
|
return 200 '{"m.homeserver":{"base_url":"${MATRIX_CLIENT_SERVER}"}}';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request_method = 'OPTIONS') {
|
||||||
|
add_header Access-Control-Allow-Origin '*';
|
||||||
|
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
|
||||||
|
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type, Authorization';
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 405;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
|
||||||
|
error_log /var/log/nginx/error.log notice;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
|
||||||
|
# This order is important, as the Matrix matches should be evaluated first
|
||||||
|
include /etc/nginx/conf.d/matrix.conf;
|
||||||
|
include /etc/nginx/conf.d/gateway.conf;
|
||||||
|
include /etc/nginx/conf.d/default.conf;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"name": "rb-web",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vue-tsc --noEmit && vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"image": "docker build -t chewingbever/rb-blog .",
|
||||||
|
"lint": "eslint --ext .js,.vue,.ts src",
|
||||||
|
"format": "yarn run lint --fix"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vue": "^3.2.25"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.8.1",
|
||||||
|
"@typescript-eslint/parser": "^5.8.1",
|
||||||
|
"@vitejs/plugin-vue": "^2.0.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"eslint-config-standard": "^16.0.3",
|
||||||
|
"eslint-plugin-import": "^2.25.3",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint-plugin-promise": "^5.2.0",
|
||||||
|
"eslint-plugin-vue": "^8.2.0",
|
||||||
|
"miragejs": "^0.1.43",
|
||||||
|
"null-loader": "^4.0.1",
|
||||||
|
"typescript": "^4.4.4",
|
||||||
|
"vite": "^2.7.2",
|
||||||
|
"vue-tsc": "^0.29.8"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
// This starter template is using Vue 3 <script setup> SFCs
|
||||||
|
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
|
||||||
|
import HelloWorld from './components/HelloWorld.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
alt="Vue logo"
|
||||||
|
src="./assets/logo.png"
|
||||||
|
>
|
||||||
|
<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#app {
|
||||||
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-align: center;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
</style>
|
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
|
@ -0,0 +1,71 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
defineProps<{ msg: string }>()
|
||||||
|
|
||||||
|
const count = ref(0)
|
||||||
|
|
||||||
|
fetch('/api/v1/sections').then(res => res.json()).then(res => console.log(res))
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Recommended IDE setup:
|
||||||
|
<a
|
||||||
|
href="https://code.visualstudio.com/"
|
||||||
|
target="_blank"
|
||||||
|
>VSCode</a>
|
||||||
|
+
|
||||||
|
<a
|
||||||
|
href="https://github.com/johnsoncodehk/volar"
|
||||||
|
target="_blank"
|
||||||
|
>Volar</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>See <code>README.md</code> for more information.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a
|
||||||
|
href="https://vitejs.dev/guide/features.html"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Vite Docs
|
||||||
|
</a>
|
||||||
|
|
|
||||||
|
<a
|
||||||
|
href="https://v3.vuejs.org/"
|
||||||
|
target="_blank"
|
||||||
|
>Vue 3 Docs</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="count++"
|
||||||
|
>
|
||||||
|
count is: {{ count }}
|
||||||
|
</button>
|
||||||
|
<p>
|
||||||
|
Edit
|
||||||
|
<code>components/HelloWorld.vue</code> to test hot module replacement.
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
a {
|
||||||
|
color: #42b983;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin: 0 0.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: #eee;
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #304455;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
|
declare module '*.vue' {
|
||||||
|
import { DefineComponent } from 'vue'
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
||||||
|
const component: DefineComponent<{}, {}, any>
|
||||||
|
export default component
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
// @ts-ignore
|
||||||
|
import { makeServer } from './mirage/v1'
|
||||||
|
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
makeServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
createApp(App).mount('#app')
|
|
@ -0,0 +1,52 @@
|
||||||
|
export const sections = [
|
||||||
|
{
|
||||||
|
id: '837ba6a5-47ed-4682-bff5-90bc5c5f9646',
|
||||||
|
title: 'Section One',
|
||||||
|
shortname: 'one',
|
||||||
|
description: 'The first section.',
|
||||||
|
is_default: true,
|
||||||
|
has_titles: true,
|
||||||
|
is_private: false,
|
||||||
|
is_archived: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '5e661b3f-61e6-4aed-a93b-8cae0896f656',
|
||||||
|
title: 'Section Two',
|
||||||
|
shortname: 'two',
|
||||||
|
description: 'The second section.',
|
||||||
|
is_default: true,
|
||||||
|
has_titles: false,
|
||||||
|
is_private: false,
|
||||||
|
is_archived: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '5fcbeaca-1496-438e-ace2-18e99e11f384',
|
||||||
|
title: 'Section Three',
|
||||||
|
shortname: 'three',
|
||||||
|
description: 'The third section.',
|
||||||
|
is_default: false,
|
||||||
|
has_titles: true,
|
||||||
|
is_private: false,
|
||||||
|
is_archived: false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const posts = [
|
||||||
|
{
|
||||||
|
id: 'af08bbcd-f6eb-446e-b355-13e0a0ef008e',
|
||||||
|
section_id: sections[0]['id'],
|
||||||
|
is_private: false,
|
||||||
|
is_archived: false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const versions = [
|
||||||
|
{
|
||||||
|
id: '8c5bc2f9-e52f-4e19-bd76-119cc42ff863',
|
||||||
|
post_id: posts[0]['id'],
|
||||||
|
title: 'This Is A Title',
|
||||||
|
publish_date: '2021-12-28',
|
||||||
|
content: 'Hello. This is some content!',
|
||||||
|
is_draft: false
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { createServer, Model } from 'miragejs';
|
||||||
|
import { sections, posts, versions } from './models';
|
||||||
|
|
||||||
|
export function makeServer ({ environment = 'development' } = {}) {
|
||||||
|
const server = createServer({
|
||||||
|
environment,
|
||||||
|
|
||||||
|
models: {
|
||||||
|
section: Model,
|
||||||
|
Post: Model,
|
||||||
|
version: Model
|
||||||
|
},
|
||||||
|
|
||||||
|
seeds (server) {
|
||||||
|
sections.forEach(s => server.create('section', s));
|
||||||
|
posts.forEach(s => server.create('post', s));
|
||||||
|
versions.forEach(s => server.create('version', s));
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
routes () {
|
||||||
|
this.namespace = 'api/v1';
|
||||||
|
|
||||||
|
this.get('/sections', (schema) => {
|
||||||
|
return schema.sections.all();
|
||||||
|
})
|
||||||
|
this.get('/posts', (schema) => {
|
||||||
|
return schema.posts.all();
|
||||||
|
})
|
||||||
|
this.get('/versions', (schema) => {
|
||||||
|
return schema.versions.all();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return server;
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
// src/server.js
|
||||||
|
import { createServer, Model } from 'miragejs'
|
||||||
|
|
||||||
|
export function makeServer ({ environment = 'development' } = {}) {
|
||||||
|
const server = createServer({
|
||||||
|
environment,
|
||||||
|
|
||||||
|
models: {
|
||||||
|
user: Model
|
||||||
|
},
|
||||||
|
|
||||||
|
seeds (server) {
|
||||||
|
server.create('user', { name: 'Bob' })
|
||||||
|
server.create('user', { name: 'Alice' })
|
||||||
|
},
|
||||||
|
|
||||||
|
routes () {
|
||||||
|
this.namespace = 'api'
|
||||||
|
|
||||||
|
this.get('/users', (schema) => {
|
||||||
|
return schema.users.all()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return server
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "esnext",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"strict": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"sourceMap": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"lib": ["esnext", "dom"]
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()]
|
||||||
|
})
|
|
@ -0,0 +1,14 @@
|
||||||
|
module.exports = {
|
||||||
|
chainWebpack: (config) => {
|
||||||
|
if (
|
||||||
|
process.env.NODE_ENV === "production" &&
|
||||||
|
process.env.MIRAGE_ENABLED !== "true"
|
||||||
|
) {
|
||||||
|
config.module
|
||||||
|
.rule("exclude-mirage")
|
||||||
|
.test(/node_modules\/miragejs\//)
|
||||||
|
.use("null-loader")
|
||||||
|
.loader("null-loader")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
Loading…
Reference in New Issue