From 53dde83f7768f8f494f7c6ea013b31f45bad653a Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Sat, 7 Nov 2020 10:35:37 +0000 Subject: [PATCH] feat: use nuxt (#285) --- .babelrc | 16 + .editorconfig | 13 + .eslintrc.js | 29 +- .github/workflows/sync.yml | 2 +- .github/workflows/test.yml | 2 +- .gitignore | 101 +- .prettierrc | 6 + README.md | 29 - api/build.js | 5 +- api/parser.ts | 2 +- babel.config.js | 10 - commitlint.config.js | 3 + index.template.html | 30 - jest.config.js | 22 +- nuxt.config.js | 94 + package.json | 112 +- postcss.config.js | 10 - prettier.config.js | 5 - public/index.html | 17 - public/site.webmanifest | 19 - {src/utils => scripts}/global.js | 4 +- scripts/publish.js | 15 +- src/shims-tsx.d.ts => shims-tsx.d.ts | 0 src/shims-vue.d.ts => shims-vue.d.ts | 0 src/App.vue | 179 - src/assets/css/tailwind.css | 1 + src/components/BlogList.vue | 50 +- src/components/GithubRepos.vue | 16 +- src/components/ItemList.vue | 8 +- src/components/icons/GithubCircle.vue | 46 +- src/components/layout/TheSiteFooter.vue | 3 +- src/components/layout/TheSiteHeader.vue | 38 +- ...ilding-your-own-vue-rich-text-component.md | 13 +- .../articles/good-ux-and-giving-birth.md | 6 +- src/content/articles/introduction.md | 2 +- .../serverless-functions-nuxt-zeit-now.md | 17 +- src/content/index.md | 3 + src/layouts/default.vue | 195 +- src/main.ts | 20 - src/modules.d.ts | 37 - src/pages/blog/_article.vue | 154 +- src/pages/blog/index.vue | 12 +- src/pages/index.vue | 21 +- src/pages/work.vue | 19 +- src/router/index.ts | 54 - src/shims-md.d.ts | 13 - .../static}/android-chrome-192x192.png | Bin .../static}/android-chrome-512x512.png | Bin {public => src/static}/apple-touch-icon.png | Bin {public => src/static}/browserconfig.xml | 0 {public => src/static}/favicon-16x16.png | Bin {public => src/static}/favicon-32x32.png | Bin {public => src/static}/favicon.ico | Bin {public => src/static}/img/freya1.jpg | Bin {public => src/static}/img/freya2.jpg | Bin {public => src/static}/img/freya3.jpg | Bin .../img/icons/android-chrome-192x192.png | Bin .../img/icons/android-chrome-512x512.png | Bin .../img/icons/apple-touch-icon-120x120.png | Bin .../img/icons/apple-touch-icon-152x152.png | Bin .../img/icons/apple-touch-icon-180x180.png | Bin .../img/icons/apple-touch-icon-60x60.png | Bin .../img/icons/apple-touch-icon-76x76.png | Bin .../static}/img/icons/apple-touch-icon.png | Bin .../static}/img/icons/favicon-16x16.png | Bin .../static}/img/icons/favicon-32x32.png | Bin .../img/icons/msapplication-icon-144x144.png | Bin .../static}/img/icons/mstile-150x150.png | Bin .../static}/img/icons/safari-pinned-tab.svg | 0 {public => src/static}/img/pbc.jpg | Bin .../static}/img/tiptap-webpack-bundle.png | Bin {public => src/static}/mstile-150x150.png | Bin {public => src/static}/robots.txt | 0 {public => src/static}/safari-pinned-tab.svg | 0 src/static/site.webmanifest | 19 + src/utils/blogs.ts | 18 - src/utils/github.ts | 4 +- src/utils/global.ts | 9 + src/utils/local-storage.ts | 10 +- src/utils/theme.ts | 2 +- src/vapper.d.ts | 19 - stylelint.config.js | 19 + tailwind.config.js | 74 +- {tests => test}/unit/ItemList.spec.ts | 3 +- test/unit/__snapshots__/ItemList.spec.ts.snap | 3 + tsconfig.json | 45 +- vapper-webpack.js | 3 - vapper.config.js | 24 - now.json => vercel.json | 0 vue.config.js | 64 - yarn.lock | 7624 ++++++++++------- 91 files changed, 5566 insertions(+), 3827 deletions(-) create mode 100644 .babelrc create mode 100644 .editorconfig create mode 100644 .prettierrc delete mode 100644 README.md delete mode 100644 babel.config.js create mode 100644 commitlint.config.js delete mode 100644 index.template.html create mode 100644 nuxt.config.js delete mode 100644 postcss.config.js delete mode 100644 prettier.config.js delete mode 100644 public/index.html delete mode 100644 public/site.webmanifest rename {src/utils => scripts}/global.js (95%) rename src/shims-tsx.d.ts => shims-tsx.d.ts (100%) rename src/shims-vue.d.ts => shims-vue.d.ts (100%) delete mode 100644 src/App.vue create mode 100644 src/assets/css/tailwind.css delete mode 100644 src/main.ts delete mode 100644 src/modules.d.ts delete mode 100644 src/router/index.ts delete mode 100644 src/shims-md.d.ts rename {public => src/static}/android-chrome-192x192.png (100%) rename {public => src/static}/android-chrome-512x512.png (100%) rename {public => src/static}/apple-touch-icon.png (100%) rename {public => src/static}/browserconfig.xml (100%) rename {public => src/static}/favicon-16x16.png (100%) rename {public => src/static}/favicon-32x32.png (100%) rename {public => src/static}/favicon.ico (100%) rename {public => src/static}/img/freya1.jpg (100%) rename {public => src/static}/img/freya2.jpg (100%) rename {public => src/static}/img/freya3.jpg (100%) rename {public => src/static}/img/icons/android-chrome-192x192.png (100%) rename {public => src/static}/img/icons/android-chrome-512x512.png (100%) rename {public => src/static}/img/icons/apple-touch-icon-120x120.png (100%) rename {public => src/static}/img/icons/apple-touch-icon-152x152.png (100%) rename {public => src/static}/img/icons/apple-touch-icon-180x180.png (100%) rename {public => src/static}/img/icons/apple-touch-icon-60x60.png (100%) rename {public => src/static}/img/icons/apple-touch-icon-76x76.png (100%) rename {public => src/static}/img/icons/apple-touch-icon.png (100%) rename {public => src/static}/img/icons/favicon-16x16.png (100%) rename {public => src/static}/img/icons/favicon-32x32.png (100%) rename {public => src/static}/img/icons/msapplication-icon-144x144.png (100%) rename {public => src/static}/img/icons/mstile-150x150.png (100%) rename {public => src/static}/img/icons/safari-pinned-tab.svg (100%) rename {public => src/static}/img/pbc.jpg (100%) rename {public => src/static}/img/tiptap-webpack-bundle.png (100%) rename {public => src/static}/mstile-150x150.png (100%) rename {public => src/static}/robots.txt (100%) rename {public => src/static}/safari-pinned-tab.svg (100%) create mode 100644 src/static/site.webmanifest delete mode 100644 src/utils/blogs.ts create mode 100644 src/utils/global.ts delete mode 100644 src/vapper.d.ts create mode 100644 stylelint.config.js rename {tests => test}/unit/ItemList.spec.ts (75%) create mode 100644 test/unit/__snapshots__/ItemList.spec.ts.snap delete mode 100644 vapper-webpack.js delete mode 100644 vapper.config.js rename now.json => vercel.json (100%) delete mode 100644 vue.config.js 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 @@ \ 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
- - - diff --git a/src/main.ts b/src/main.ts deleted file mode 100644 index 2c99f34b..00000000 --- a/src/main.ts +++ /dev/null @@ -1,20 +0,0 @@ -import Vue from 'vue' -import VueCompositionApi from '@vue/composition-api' -Vue.use(VueCompositionApi) - -import App from './App.vue' -import createRouter from './router' -import { ComponentOptions } from 'vue' - -Vue.config.productionTip = false - -export default function createApp() { - const router = createRouter() - const options: ComponentOptions = { - router, - head: {}, - render: h => h(App), - } - - return options -} diff --git a/src/modules.d.ts b/src/modules.d.ts deleted file mode 100644 index 4ed8af0f..00000000 --- a/src/modules.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -declare module 'tailwindcss/defaultConfig.js' { - type Screens = 'sm' | 'md' | 'lg' | 'xl' - type Range = 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 - interface TailwindConfig { - prefix: string - important: boolean - separator: string - theme: { - screens: Record - colors: { - transparent: string - - black: string - white: string - - gray: Record - red: Record - orange: Record - yellow: Record - green: Record - teal: Record - blue: Record - indigo: Record - purple: Record - pink: Record - } - } - } - const config: TailwindConfig - export default config -} - -declare module 'tailwindcss/resolveConfig' { - import defaultConfig from 'tailwindcss/defaultConfig.js' - const resolveConfig: (config: T) => T & typeof defaultConfig - export default resolveConfig -} diff --git a/src/pages/blog/_article.vue b/src/pages/blog/_article.vue index 98b2c3f5..d68905a5 100644 --- a/src/pages/blog/_article.vue +++ b/src/pages/blog/_article.vue @@ -15,16 +15,14 @@ -
- -
-
+
+ +
@@ -93,6 +88,7 @@ export default defineComponent({ h4 { @apply uppercase text-sm; + letter-spacing: 0.1rem; } * + h3, @@ -100,38 +96,16 @@ export default defineComponent({ @apply mt-8; } - p { - + pre, - + p { - @apply mt-4; - } - - + ul, - + ol { - @apply my-2; - } - - + table { - @apply my-4; - } - } - p > code, - li > code { - @apply px-2 py-1 mx-1 text-sm; - - color: var(--background, theme('colors.gray.800')); - background-color: var(--text-base, theme('colors.white')); + :global(.nuxt-content-highlight) { + @apply mb-6; } - p ~ div { - @apply mt-4 py-1 uppercase text-xs font-bold text-gray-600; - letter-spacing: 0.15rem; - background-color: theme('colors.gray.900'); - margin-left: -50vw; - margin-right: -50vw; - padding: 1rem 50vw; + p + :global(.nuxt-content-highlight) { + @apply mt-6; } + pre { - @apply font-code text-sm; + @apply font-code text-sm my-0; + background-color: theme('colors.gray.900') !important; margin-left: -50vw; margin-right: -50vw; @@ -140,26 +114,23 @@ export default defineComponent({ white-space: pre-wrap; } - + * { - @apply mt-4; - } + h3, + h4 { @apply mt-8; } } - blockquote { - @apply pl-4 border-l-4; - } + ol, ul { @apply pl-6; li { @apply my-4; + counter-increment: list; &::before { @apply -ml-6 mt-2 mr-2 inline-block font-semibold leading-none; + width: 1rem; } @@ -168,12 +139,51 @@ export default defineComponent({ } } } + ul li::before { content: '›'; } ol li::before { @apply text-xs; + content: counter(list); } + + p { + + pre, + + p { + @apply mt-4; + } + + + ul, + + ol { + @apply my-2; + } + + + table { + @apply my-4; + } + } + p > code, + li > code { + @apply px-2 py-1 mx-1 text-sm; + + color: var(--background, theme('colors.gray.800')); + background-color: var(--text-base, theme('colors.white')); + } + + p + div:not(:global(.nuxt-content-highlight)) { + @apply mt-6 py-1 uppercase text-xs font-bold text-gray-600; + + letter-spacing: 0.15rem; + background-color: theme('colors.gray.900'); + margin-left: -50vw; + margin-right: -50vw; + padding: 1rem 50vw; + } + + blockquote { + @apply pl-4 border-l-4; + } } diff --git a/src/pages/blog/index.vue b/src/pages/blog/index.vue index dfe333fc..69848311 100644 --- a/src/pages/blog/index.vue +++ b/src/pages/blog/index.vue @@ -1,5 +1,5 @@ - - diff --git a/src/pages/index.vue b/src/pages/index.vue index 9c435818..92e331a7 100644 --- a/src/pages/index.vue +++ b/src/pages/index.vue @@ -4,7 +4,7 @@

Welcome!

- +

Recent articles

@@ -15,22 +15,17 @@ @@ -43,4 +38,4 @@ export default defineComponent({ @apply mt-12; } } - \ No newline at end of file + diff --git a/src/pages/work.vue b/src/pages/work.vue index e89e1e4a..80093f82 100644 --- a/src/pages/work.vue +++ b/src/pages/work.vue @@ -15,16 +15,16 @@