Upgrade to Nuxt 4 folder structure
36
Dockerfile
|
@ -1,36 +0,0 @@
|
|||
ARG NODE_ENV=development
|
||||
ARG HOST=localhost
|
||||
ARG PORT=3000
|
||||
|
||||
FROM node:18-alpine as build
|
||||
RUN apk update && apk upgrade
|
||||
|
||||
# Create application directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files to the application directory and install dependencies
|
||||
COPY package* ./
|
||||
RUN npm install
|
||||
|
||||
# Copy everything else from the project
|
||||
COPY . ./
|
||||
RUN npm run build
|
||||
|
||||
|
||||
FROM node:18-alpine as production
|
||||
RUN apk update && apk upgrade && apk add dumb-init && adduser -D nuxt
|
||||
|
||||
# Set non-root user
|
||||
USER nuxt
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /opt/index
|
||||
COPY --chown=nuxt:nuxt --from=build /app/.output ./
|
||||
|
||||
# Expose the listening port
|
||||
EXPOSE ${PORT}
|
||||
|
||||
# Set Nitro variables and run the application
|
||||
# https://go.enderman.ch/vws4k
|
||||
ENV HOST=${HOST} PORT=${PORT} NODE_ENV=${NODE_ENV}
|
||||
CMD ["dumb-init", "node", "/opt/index/server/index.mjs"]
|
|
@ -7,7 +7,7 @@ services:
|
|||
- PORT=3000
|
||||
- HOST=0.0.0.0
|
||||
build:
|
||||
context: .
|
||||
context: ./src
|
||||
ports:
|
||||
- "127.0.0.1:3670:3000"
|
||||
restart: unless-stopped
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
import type { ParsedContent } from '@nuxt/content/dist/runtime/types'
|
||||
import { formatDate } from 'date-fns'
|
||||
|
||||
import { serverQueryContent } from '#content/server'
|
||||
|
||||
export default defineSitemapEventHandler(async (e) => {
|
||||
const contentList = (await serverQueryContent(e).find()) as ParsedContent[]
|
||||
return contentList.map((c) => {
|
||||
return asSitemapUrl({
|
||||
loc: c._path,
|
||||
lastmod: formatDate(c.updated, 'yyyy-MM-dd'),
|
||||
changefreq: 'monthly',
|
||||
priority: 0.9,
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,31 @@
|
|||
FROM oven/bun:alpine AS base
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# install dependencies into temp directory
|
||||
# this will cache them and speed up future builds
|
||||
FROM base AS install
|
||||
RUN mkdir -p /temp
|
||||
|
||||
COPY package.json bun.lockb /temp/
|
||||
RUN cd /temp && bun install --production
|
||||
|
||||
# copy node_modules from temp directory
|
||||
# then copy all (non-ignored) project files into the image
|
||||
FROM base AS prerelease
|
||||
COPY --from=install /temp/node_modules node_modules
|
||||
COPY . .
|
||||
|
||||
ENV NODE_ENV=production
|
||||
RUN bun test
|
||||
RUN bun --bun run build
|
||||
|
||||
# copy production dependencies and source code into final image
|
||||
FROM base AS release
|
||||
COPY --from=install /temp/node_modules node_modules
|
||||
COPY --from=prerelease /usr/src/app/.output .
|
||||
COPY --from=prerelease /usr/src/app/package.json .
|
||||
|
||||
ENV HOST=0.0.0.0
|
||||
USER bun
|
||||
|
||||
ENTRYPOINT [ "bun", "run", "server/index.mjs" ]
|
|
@ -1,4 +1,4 @@
|
|||
import config from './config'
|
||||
import config from '../config'
|
||||
|
||||
export default defineAppConfig({
|
||||
...config,
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 139 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
@ -0,0 +1,13 @@
|
|||
import { defineCollection, defineContentConfig } from '@nuxt/content'
|
||||
import { asSitemapCollection } from '@nuxtjs/sitemap/content'
|
||||
|
||||
export default defineContentConfig({
|
||||
collections: {
|
||||
content: defineCollection(
|
||||
asSitemapCollection({
|
||||
type: 'page',
|
||||
source: '**/*.md',
|
||||
}),
|
||||
),
|
||||
},
|
||||
})
|
|
@ -31,6 +31,7 @@ export default defineNuxtConfig({
|
|||
pageTransition: { name: 'page', mode: 'out-in' },
|
||||
rootId: 'ender-app',
|
||||
},
|
||||
|
||||
colorMode: {
|
||||
preference: 'system',
|
||||
fallback: 'dark',
|
||||
|
@ -39,6 +40,9 @@ export default defineNuxtConfig({
|
|||
componentName: 'NuxtTheme',
|
||||
storageKey: 'ecmatheme',
|
||||
},
|
||||
|
||||
compatibilityDate: '2025-01-26',
|
||||
|
||||
components: {
|
||||
dirs: [
|
||||
{
|
||||
|
@ -48,6 +52,7 @@ export default defineNuxtConfig({
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
content: {
|
||||
markdown: {
|
||||
remarkPlugins: ['remark-reading-time'],
|
||||
|
@ -87,16 +92,21 @@ export default defineNuxtConfig({
|
|||
],
|
||||
},
|
||||
},
|
||||
|
||||
css: ['~/assets/styles/main.scss'],
|
||||
|
||||
devtools: {
|
||||
enabled: true,
|
||||
},
|
||||
|
||||
experimental: {
|
||||
inlineRouteRules: true,
|
||||
},
|
||||
features: {
|
||||
inlineStyles: false,
|
||||
|
||||
future: {
|
||||
compatibilityVersion: 4,
|
||||
},
|
||||
|
||||
googleFonts: {
|
||||
download: true,
|
||||
families: {
|
||||
|
@ -104,17 +114,27 @@ export default defineNuxtConfig({
|
|||
Alexandria: true,
|
||||
},
|
||||
},
|
||||
|
||||
linkChecker: {
|
||||
failOnError: true,
|
||||
report: {
|
||||
html: true,
|
||||
markdown: true,
|
||||
},
|
||||
},
|
||||
|
||||
modules: [
|
||||
'@pinia/nuxt',
|
||||
'@nuxt/image',
|
||||
'@nuxt/content',
|
||||
'@nuxtjs/seo',
|
||||
'@nuxt/content',
|
||||
'@nuxtjs/google-fonts',
|
||||
'@nuxtjs/tailwindcss',
|
||||
'@nuxtjs/color-mode',
|
||||
'@nuxt/eslint',
|
||||
['@nuxtjs/stylelint-module', { failOnError: true, lintOnStart: false }],
|
||||
],
|
||||
|
||||
nitro: {
|
||||
prerender: {
|
||||
crawlLinks: true,
|
||||
|
@ -123,14 +143,9 @@ export default defineNuxtConfig({
|
|||
routes: ['/robots.txt', '/sitemap.xml'],
|
||||
},
|
||||
},
|
||||
linkChecker: {
|
||||
failOnError: true,
|
||||
report: {
|
||||
html: true,
|
||||
markdown: true,
|
||||
},
|
||||
},
|
||||
|
||||
plugins: [],
|
||||
|
||||
robots: {
|
||||
enabled: true,
|
||||
blockNonSeoBots: false,
|
||||
|
@ -140,6 +155,7 @@ export default defineNuxtConfig({
|
|||
groups: [],
|
||||
disallow: [' '],
|
||||
},
|
||||
|
||||
site: {
|
||||
env: process.env.NODE_ENV,
|
||||
url: config.url,
|
||||
|
@ -147,8 +163,11 @@ export default defineNuxtConfig({
|
|||
indexable: true,
|
||||
trailingSlash: false,
|
||||
},
|
||||
|
||||
sitemap: {
|
||||
sources: ['/api/__sitemap__/content'],
|
||||
sources: [
|
||||
/*'/api/__sitemap__/content'*/
|
||||
],
|
||||
cacheMaxAgeSeconds: 360,
|
||||
exclude: [],
|
||||
credits: false,
|
||||
|
@ -166,12 +185,15 @@ export default defineNuxtConfig({
|
|||
lastmod: config.build.date,
|
||||
},
|
||||
},
|
||||
|
||||
tailwindcss: {
|
||||
exposeConfig: true,
|
||||
},
|
||||
|
||||
typescript: {
|
||||
typeCheck: true,
|
||||
},
|
||||
|
||||
vue: {
|
||||
compilerOptions: {
|
||||
isCustomElement: (tag) => tag === 'iconify-icon',
|
|
@ -14,41 +14,39 @@
|
|||
"lint": "npm run lint:js && npm run lint:style && npm run lint:prettier",
|
||||
"lint:fix": "prettier --write --list-different . && npm run lint:js -- --fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/content": "^2.12.1",
|
||||
"@nuxt/devtools": "^1.3.3",
|
||||
"dependencies": {
|
||||
"@nuxt/content": "^3.0.0",
|
||||
"@nuxt/eslint": "^0.3.13",
|
||||
"@nuxt/image": "^1.8.1",
|
||||
"@nuxt/types": "^2.17.3",
|
||||
"@nuxtjs/color-mode": "^3.4.1",
|
||||
"@nuxtjs/google-fonts": "^3.2.0",
|
||||
"@nuxtjs/seo": "^2.0.0-rc.10",
|
||||
"@nuxtjs/seo": "^2.1.0",
|
||||
"@nuxtjs/stylelint-module": "^5.2.0",
|
||||
"@nuxtjs/tailwindcss": "^6.12.0",
|
||||
"@pinia/nuxt": "^0.5.1",
|
||||
"@tailwindcss/typography": "^0.5.13",
|
||||
"animate.css": "latest",
|
||||
"caniuse-lite": "^1.0.30001634",
|
||||
"nuxt": "^3.12.1",
|
||||
"nuxt": "^3.15.3",
|
||||
"pinia": "^2.1.7",
|
||||
"sass-embedded": "^1.82.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.4.5",
|
||||
"vue-tsc": "^2.2.0",
|
||||
"iconify-icon": "^2.1.0",
|
||||
"animate.css": "latest",
|
||||
"remark-reading-time": "^2.0.1",
|
||||
"@date-io/date-fns": "^3.0.0",
|
||||
"date-fns": "^3.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"caniuse-lite": "^1.0.30001634",
|
||||
"prettier": "^3.3.2",
|
||||
"sass": "^1.77.5",
|
||||
"stylelint": "^16.6.1",
|
||||
"stylelint-config-recommended-scss": "^14.0.0",
|
||||
"stylelint-config-recommended-vue": "^1.5.0",
|
||||
"stylelint-config-standard-scss": "^13.1.0",
|
||||
"stylelint-config-tailwindcss": "^0.0.7",
|
||||
"stylelint-scss": "^6.3.1",
|
||||
"typescript": "^5.4.5",
|
||||
"vue": "^3.4.28",
|
||||
"vue-router": "^4.3.3",
|
||||
"vue-tsc": "^1.8.22"
|
||||
},
|
||||
"dependencies": {
|
||||
"@date-io/date-fns": "^3.0.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"iconify-icon": "^2.1.0",
|
||||
"remark-reading-time": "^2.0.1"
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"browserslist": [
|
||||
">0.3%",
|
Before Width: | Height: | Size: 632 B After Width: | Height: | Size: 632 B |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 204 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |