diff --git a/.babelrc b/.babelrc
new file mode 100644
index 00000000..84c2e570
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,16 @@
+{
+ "env": {
+ "test": {
+ "presets": [
+ [
+ "@babel/preset-env",
+ {
+ "targets": {
+ "node": "current"
+ }
+ }
+ ]
+ ]
+ }
+ }
+}
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..5d126348
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+# editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/.eslintrc.js b/.eslintrc.js
index 131c4192..08335fa5 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,26 +1,17 @@
module.exports = {
root: true,
env: {
+ browser: true,
node: true,
},
- extends: ['plugin:vue/essential', '@vue/prettier', '@vue/typescript'],
- rules: {
- 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
- 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
- 'prettier/prettier': 'off',
- },
- parserOptions: {
- parser: '@typescript-eslint/parser',
- },
- overrides: [
- {
- files: [
- '**/__tests__/*.{j,t}s?(x)',
- '**/tests/unit/**/*.spec.{j,t}s?(x)',
- ],
- env: {
- jest: true,
- },
- },
+ extends: [
+ '@nuxtjs/eslint-config-typescript',
+ 'prettier',
+ 'prettier/vue',
+ 'plugin:prettier/recommended',
+ 'plugin:nuxt/recommended',
],
+ plugins: ['prettier'],
+ // add your custom rules here
+ rules: {},
}
diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml
index 3e99d452..54049eb4 100644
--- a/.github/workflows/sync.yml
+++ b/.github/workflows/sync.yml
@@ -15,7 +15,7 @@ jobs:
- uses: actions/cache@v2
id: cache
with:
- path: "node_modules"
+ path: 'node_modules'
key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- name: Install dependencies
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 9d694578..6e36af91 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -15,7 +15,7 @@ jobs:
- uses: actions/cache@v2
id: cache
with:
- path: "node_modules"
+ path: 'node_modules'
key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- name: Install dependencies
diff --git a/.gitignore b/.gitignore
index a0dddc6f..e8f682ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,21 +1,90 @@
-.DS_Store
-node_modules
-/dist
-
-# local env files
-.env.local
-.env.*.local
-
-# Log files
+# Created by .ignore support plugin (hsz.mobi)
+### Node template
+# Logs
+/logs
+*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
-# Editor directories and files
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# TypeScript v1 declaration files
+typings/
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+
+# next.js build output
+.next
+
+# nuxt.js build output
+.nuxt
+
+# Nuxt generate
+dist
+
+# vuepress build output
+.vuepress/dist
+
+# Serverless directories
+.serverless
+
+# IDE / Editor
.idea
-.vscode
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
+
+# Service worker
+sw.*
+
+# macOS
+.DS_Store
+
+# Vim swap files
+*.swp
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..3d1f5e5c
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,6 @@
+{
+ "semi": false,
+ "singleQuote": true,
+ "trailingComma": "es5",
+ "arrowParens": "avoid"
+}
diff --git a/README.md b/README.md
deleted file mode 100644
index 3dba6f8f..00000000
--- a/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# roe.dev
-
-## Project setup
-```
-yarn install
-```
-
-### Compiles and hot-reloads for development
-```
-yarn serve
-```
-
-### Compiles and minifies for production
-```
-yarn build
-```
-
-### Run your unit tests
-```
-yarn test:unit
-```
-
-### Lints and fixes files
-```
-yarn lint
-```
-
-### Customize configuration
-See [Configuration Reference](https://cli.vuejs.org/config/).
diff --git a/api/build.js b/api/build.js
index 279a9cf3..3893c1c9 100644
--- a/api/build.js
+++ b/api/build.js
@@ -1,11 +1,10 @@
-const fs = require('fs')
const grayMatter = require('gray-matter')
const {
iterateOnDirectory,
getMatchOrReturn,
writeFile,
-} = require('../src/utils/global')
+} = require('../scripts/global')
const metadata = {}
@@ -26,5 +25,5 @@ writeFile(
'./metadata.json',
JSON.stringify({
metadata,
- }),
+ })
)
diff --git a/api/parser.ts b/api/parser.ts
index 2d5e629d..d9479298 100644
--- a/api/parser.ts
+++ b/api/parser.ts
@@ -1,6 +1,6 @@
import { IncomingMessage } from 'http'
-import { getMatchOrReturn } from '../src/utils/global'
+import { getMatchOrReturn } from '../scripts/global'
import { metadata } from './metadata.json'
diff --git a/babel.config.js b/babel.config.js
deleted file mode 100644
index 42458517..00000000
--- a/babel.config.js
+++ /dev/null
@@ -1,10 +0,0 @@
-module.exports = {
- presets: [
- [
- '@vue/cli-plugin-babel/preset',
- {
- loose: true,
- },
- ],
- ],
-}
diff --git a/commitlint.config.js b/commitlint.config.js
new file mode 100644
index 00000000..98ee7dfc
--- /dev/null
+++ b/commitlint.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ extends: ['@commitlint/config-conventional'],
+}
diff --git a/index.template.html b/index.template.html
deleted file mode 100644
index 9752b9a0..00000000
--- a/index.template.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{{ meta.inject().meta.text() }}}
- {{{ meta.inject().title.text() }}}
- {{{ meta.inject().link.text() }}}
- {{{ meta.inject().style.text() }}}
- {{{ meta.inject().script.text() }}}
- {{{ meta.inject().noscript.text() }}}
-
-
-
-
- {{{ meta.inject().script.text({ body: true }) }}}
-
-
-
\ No newline at end of file
diff --git a/jest.config.js b/jest.config.js
index 273b1461..7140a670 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,3 +1,23 @@
module.exports = {
- preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
+ moduleNameMapper: {
+ '^~/(.*)$': '/src/$1',
+ '^vue$': 'vue/dist/vue.common.js',
+ },
+ globals: {
+ 'vue-jest': {
+ experimentalCSSCompile: false,
+ },
+ },
+ snapshotSerializers: [require.resolve('jest-serializer-vue-tjw')],
+ moduleFileExtensions: ['ts', 'js', 'vue', 'json'],
+ transform: {
+ '^.+\\.ts$': 'ts-jest',
+ '^.+\\.js$': 'babel-jest',
+ '.*\\.(vue)$': 'vue-jest',
+ },
+ collectCoverage: true,
+ collectCoverageFrom: [
+ '/components/**/*.vue',
+ '/pages/**/*.vue',
+ ],
}
diff --git a/nuxt.config.js b/nuxt.config.js
new file mode 100644
index 00000000..17269b25
--- /dev/null
+++ b/nuxt.config.js
@@ -0,0 +1,94 @@
+export default {
+ target: 'static',
+
+ srcDir: 'src',
+
+ head: {
+ title: 'roe.dev',
+ htmlAttrs: {
+ lang: 'en',
+ },
+ meta: [
+ { charset: 'utf-8' },
+ { name: 'viewport', content: 'width=device-width, initial-scale=1' },
+ { name: 'msapplication-TileColor', content: '#1a202c' },
+ { name: 'theme-color', content: '#1a202c' },
+ {
+ hid: 'og:image',
+ property: 'og:image',
+ content: `https://roe.dev/og/og.jpg`,
+ },
+ { property: 'og:image:width', content: '1200' },
+ { property: 'og:image:height', content: '630' },
+ {
+ name: 'description',
+ content: `The personal website of Daniel Roe`,
+ hid: 'description',
+ },
+ {
+ property: 'og:description',
+ content: `The personal website of Daniel Roe`,
+ hid: 'og:description',
+ },
+ { name: 'twitter:card', content: 'summary_large_image' },
+ { name: 'twitter:site', content: '@danielcroe' },
+ { name: 'twitter:creator', content: '@danielcroe' },
+ ],
+ link: [
+ { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
+ {
+ rel: 'apple-touch-icon',
+ sizes: '180x180',
+ href: '/apple-touch-icon.png',
+ },
+ {
+ rel: 'icon',
+ type: 'image/png',
+ sizes: '32x32',
+ href: '/favicon-32x32.png',
+ },
+ {
+ rel: 'icon',
+ type: 'image/png',
+ sizes: '16x16',
+ href: '/favicon-16x16.png',
+ },
+ { rel: 'manifest', href: '/site.webmanifest' },
+ { rel: 'mask-icon', href: '/safari-pinned-tab.svg', color: '#1a202c' },
+ ],
+ },
+
+ components: true,
+
+ buildModules: [
+ '@nuxtjs/html-validator',
+ '@nuxt/typescript-build',
+ '@nuxtjs/stylelint-module',
+ '@nuxtjs/tailwindcss',
+ '@nuxtjs/color-mode',
+ '@nuxtjs/composition-api',
+ ],
+
+ content: {
+ markdown: {
+ prism: {
+ theme: 'prism-themes/themes/prism-material-dark.css',
+ },
+ },
+ },
+
+ tailwindcss: {
+ configPath: '../tailwind.config.js',
+ purge: false,
+ },
+
+ build: {
+ postcss: {
+ plugins: {
+ 'postcss-nested': {},
+ },
+ },
+ },
+
+ modules: ['@nuxt/content'],
+}
diff --git a/package.json b/package.json
index 5f1bebf2..eb4c58b6 100644
--- a/package.json
+++ b/package.json
@@ -1,66 +1,66 @@
{
"name": "roe.dev",
- "version": "0.1.0",
+ "version": "1.0.0",
"private": true,
"scripts": {
- "serve": "vue-cli-service serve",
- "build": "vapper build",
- "lint": "vue-cli-service lint",
- "build:cli": "vue-cli-service build",
- "dev": "vapper dev",
- "generate": "vapper generate",
- "now-build": "yarn generate",
- "start": "vapper start",
- "test": "vue-cli-service test:unit"
+ "dev": "nuxt-ts",
+ "build": "nuxt-ts generate",
+ "start": "nuxt-ts start",
+ "generate": "nuxt-ts generate",
+ "lint:js": "eslint --ext .js,.vue --ignore-path .gitignore .",
+ "lint:style": "stylelint **/*.{vue,css} --ignore-path .gitignore",
+ "lint": "yarn lint:js && yarn lint:style",
+ "test": "jest"
},
- "dependencies": {
- "@vapper/core": "1.11.2",
- "@vapper/plugin-prerender": "1.0.1",
- "@vue/composition-api": "1.0.0-beta.19",
- "core-js": "3.6.5",
- "shiki": "0.2.6",
- "vue": "2.6.12",
- "vue-router": "3.4.8",
- "vue-use-web": "1.0.1"
- },
- "devDependencies": {
- "@types/jest": "26.0.15",
- "@typescript-eslint/eslint-plugin": "4.6.1",
- "@typescript-eslint/parser": "4.6.1",
- "@vue/cli-plugin-babel": "4.5.8",
- "@vue/cli-plugin-eslint": "4.5.8",
- "@vue/cli-plugin-router": "4.5.8",
- "@vue/cli-plugin-typescript": "4.5.8",
- "@vue/cli-plugin-unit-jest": "4.5.8",
- "@vue/cli-service": "4.5.8",
- "@vue/eslint-config-prettier": "6.0.0",
- "@vue/eslint-config-typescript": "7.0.0",
- "@vue/test-utils": "1.1.1",
- "axios": "0.21.0",
- "eslint": "7.12.1",
- "eslint-plugin-prettier": "3.1.4",
- "eslint-plugin-vue": "7.1.0",
- "frontmatter-markdown-loader": "3.6.1",
- "lint-staged": "10.5.1",
- "postcss-preset-env": "6.7.0",
- "prettier": "2.1.2",
- "tailwindcss": "1.9.6",
- "typescript": "4.0.5",
- "vue-material-design-icons": "4.10.0",
- "vue-template-compiler": "2.6.12"
- },
- "engines": {
- "node": ">=12.x"
+ "lint-staged": {
+ "*.{js,vue}": ["eslint", "prettier --write"],
+ "*.{css,vue}": "stylelint"
},
- "gitHooks": {
- "pre-commit": "lint-staged"
+ "husky": {
+ "hooks": {
+ "commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
+ "pre-commit": "lint-staged"
+ }
},
- "lint-staged": {
- "*.{js,vue,ts}": [
- "vue-cli-service lint"
- ]
+ "dependencies": {
+ "@nuxt/content": "^1.8.1",
+ "@nuxt/typescript-runtime": "^2.0.0",
+ "core-js": "^3.7.0",
+ "nuxt": "^2.14.5",
+ "prism-themes": "^1.5.0"
},
- "volta": {
- "node": "14.15.0"
+ "devDependencies": {
+ "@commitlint/cli": "^11.0.0",
+ "@commitlint/config-conventional": "^11.0.0",
+ "@nuxt/types": "^2.14.5",
+ "@nuxt/typescript-build": "^2.0.3",
+ "@nuxtjs/color-mode": "^2.0.0",
+ "@nuxtjs/composition-api": "^0.14.0",
+ "@nuxtjs/eslint-config": "^4.0.0",
+ "@nuxtjs/eslint-config-typescript": "^4.0.0",
+ "@nuxtjs/eslint-module": "^3.0.0",
+ "@nuxtjs/html-validator": "^0.1.2",
+ "@nuxtjs/pwa": "^3.2.2",
+ "@nuxtjs/stylelint-module": "^4.0.0",
+ "@nuxtjs/tailwindcss": "^3.0.2",
+ "@vue/test-utils": "^1.1.0",
+ "babel-core": "7.0.0-bridge.0",
+ "babel-eslint": "^10.1.0",
+ "babel-jest": "^26.3.0",
+ "eslint": "^7.8.1",
+ "eslint-config-prettier": "^6.11.0",
+ "eslint-plugin-nuxt": "^1.0.0",
+ "eslint-plugin-prettier": "^3.1.4",
+ "husky": "^4.3.0",
+ "jest": "^26.4.2",
+ "jest-serializer-vue-tjw": "^3.15.0",
+ "lint-staged": "^10.3.0",
+ "prettier": "^2.1.1",
+ "stylelint": "^13.7.0",
+ "stylelint-config-prettier": "^8.0.2",
+ "stylelint-config-standard": "^20.0.0",
+ "ts-jest": "^26.3.0",
+ "vue-jest": "^3.0.4",
+ "vue-use-web": "^1.0.1"
}
}
diff --git a/postcss.config.js b/postcss.config.js
deleted file mode 100644
index 00c63e7d..00000000
--- a/postcss.config.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// const IN_PRODUCTION = process.env.NODE_ENV === 'production'
-
-module.exports = {
- plugins: [
- require('postcss-preset-env')({ stage: 0 }),
- require('postcss-nested')({}),
- require('tailwindcss')(),
- require('autoprefixer')(),
- ],
-}
diff --git a/prettier.config.js b/prettier.config.js
deleted file mode 100644
index e10a46d9..00000000
--- a/prettier.config.js
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports = {
- semi: false,
- singleQuote: true,
- trailingComma: 'all',
-}
diff --git a/public/index.html b/public/index.html
deleted file mode 100644
index be043a8c..00000000
--- a/public/index.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
- roe.dev
-
-
-
-
-
-
-
diff --git a/public/site.webmanifest b/public/site.webmanifest
deleted file mode 100644
index b20abb7c..00000000
--- a/public/site.webmanifest
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "",
- "short_name": "",
- "icons": [
- {
- "src": "/android-chrome-192x192.png",
- "sizes": "192x192",
- "type": "image/png"
- },
- {
- "src": "/android-chrome-512x512.png",
- "sizes": "512x512",
- "type": "image/png"
- }
- ],
- "theme_color": "#ffffff",
- "background_color": "#ffffff",
- "display": "standalone"
-}
diff --git a/src/utils/global.js b/scripts/global.js
similarity index 95%
rename from src/utils/global.js
rename to scripts/global.js
index 9714f55d..201a49b4 100644
--- a/src/utils/global.js
+++ b/scripts/global.js
@@ -17,7 +17,7 @@ function walkDir(dir, callback) {
*/
function iterateOnDirectory(directory, callback) {
walkDir(directory, path =>
- callback(path, fs.existsSync(path) && fs.readFileSync(path, 'utf8')),
+ callback(path, fs.existsSync(path) && fs.readFileSync(path, 'utf8'))
)
}
@@ -33,7 +33,7 @@ function getMatchOrReturn(haystack, needle, index = 0) {
/**
* @type {(message: string, filename: string, contents: string) => void} writeFile
*/
-function writeFile(message, filename, contents) {
+function writeFile(_message, filename, contents) {
if (fs && fs.writeFileSync) {
return fs.writeFileSync(filename, contents)
}
diff --git a/scripts/publish.js b/scripts/publish.js
index 321a0045..2cd34243 100644
--- a/scripts/publish.js
+++ b/scripts/publish.js
@@ -1,18 +1,19 @@
const axios = require('axios')
-const { iterateOnDirectory, getMatchOrReturn } = require('../src/utils/global')
+const { iterateOnDirectory, getMatchOrReturn } = require('./global')
const url = 'https://dev.to/api'
const token = process.env.DEVTO_TOKEN || 'CYgR6zbcVgtKDRkawFYZKrCT'
+
async function getMarkdownArticles() {
const articles = []
- iterateOnDirectory('./src/content/articles', (path, contents) => {
+ await iterateOnDirectory('./src/content/articles', (path, contents) => {
if (!/\.md$/.test(path)) return
const slug = getMatchOrReturn(path, /\/[^/]*$/, 0).slice(1, -3)
articles.push({
body_markdown: contents
.replace(/\(\//g, '(https://roe.dev/')
- .replace(/ --- /g, ' — '),
+ .replace(/ ---? /g, ' — '),
title: getMatchOrReturn(contents, /title: (.*)/, 1),
slug,
canonical_url: `https://roe.dev/blog/${slug}/`,
@@ -30,6 +31,7 @@ async function getArticles() {
return data
}
+// eslint-disable-next-line
async function postArticle({ title, body_markdown, canonical_url }) {
try {
const { data } = await axios.post(
@@ -46,7 +48,7 @@ async function postArticle({ title, body_markdown, canonical_url }) {
headers: {
'api-key': token,
},
- },
+ }
)
return data
} catch (e) {
@@ -54,6 +56,7 @@ async function postArticle({ title, body_markdown, canonical_url }) {
}
}
+// eslint-disable-next-line
async function updateArticle(id, { title, body_markdown, canonical_url }) {
try {
const { data } = await axios.put(
@@ -70,7 +73,7 @@ async function updateArticle(id, { title, body_markdown, canonical_url }) {
headers: {
'api-key': token,
},
- },
+ }
)
return data
} catch (e) {
@@ -83,7 +86,7 @@ getArticles().then(async articles => {
// console.log('TCL: markdownArticles', markdownArticles)
markdownArticles.forEach(markdownArticle => {
const article = articles.find(
- article => article.canonical_url === markdownArticle.canonical_url,
+ article => article.canonical_url === markdownArticle.canonical_url
)
// console.log('TCL: article', article)
if (article) {
diff --git a/src/shims-tsx.d.ts b/shims-tsx.d.ts
similarity index 100%
rename from src/shims-tsx.d.ts
rename to shims-tsx.d.ts
diff --git a/src/shims-vue.d.ts b/shims-vue.d.ts
similarity index 100%
rename from src/shims-vue.d.ts
rename to shims-vue.d.ts
diff --git a/src/App.vue b/src/App.vue
deleted file mode 100644
index 2faba7ac..00000000
--- a/src/App.vue
+++ /dev/null
@@ -1,179 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/css/tailwind.css b/src/assets/css/tailwind.css
new file mode 100644
index 00000000..2f02db53
--- /dev/null
+++ b/src/assets/css/tailwind.css
@@ -0,0 +1 @@
+@tailwind base;
diff --git a/src/components/BlogList.vue b/src/components/BlogList.vue
index ae5d2e0f..07bd11a2 100644
--- a/src/components/BlogList.vue
+++ b/src/components/BlogList.vue
@@ -1,7 +1,7 @@
-
Published
-
+
-
+
\ No newline at end of file
+
diff --git a/src/components/GithubRepos.vue b/src/components/GithubRepos.vue
index c60d26d3..33ae0231 100644
--- a/src/components/GithubRepos.vue
+++ b/src/components/GithubRepos.vue
@@ -31,12 +31,12 @@
diff --git a/src/components/layout/TheSiteFooter.vue b/src/components/layout/TheSiteFooter.vue
index dd9d8646..3d0020f7 100644
--- a/src/components/layout/TheSiteFooter.vue
+++ b/src/components/layout/TheSiteFooter.vue
@@ -5,7 +5,7 @@
@@ -16,6 +16,7 @@ export default defineComponent({})
&::before {
@apply block mx-auto my-4;
+
border-top: 2px solid theme('colors.gray.700');
width: 1rem;
content: '';
diff --git a/src/components/layout/TheSiteHeader.vue b/src/components/layout/TheSiteHeader.vue
index 8dcb07c2..e809603c 100644
--- a/src/components/layout/TheSiteHeader.vue
+++ b/src/components/layout/TheSiteHeader.vue
@@ -3,38 +3,31 @@
-
- DCR
+ DCR
- - Work
- - Blog
+ - Work
+ - Blog
-