feat: compile server using esbuild

This commit is contained in:
Nicolas Meienberger 2023-02-17 18:39:18 +01:00 committed by Nicolas Meienberger
parent 4cb9cfa6d2
commit 7e1af1069c
12 changed files with 1868 additions and 3034 deletions

View file

@ -1,32 +1,43 @@
ARG NODE_VERSION="18.12.1"
ARG ALPINE_VERSION="3.16"
FROM node:${NODE_VERSION}-buster-slim AS builder
FROM node:${NODE_VERSION}-buster-slim AS node_base
RUN apt update
RUN apt install -y openssl
FROM node_base AS builder_base
RUN npm install node-gyp -g
RUN npm install pnpm -g
WORKDIR /dashboard
COPY ./packages/dashboard/package.json /dashboard/package.json
COPY ./packages/dashboard/prisma/schema.prisma /dashboard/prisma/
RUN npm i
# BUILDER
FROM builder_base AS builder
WORKDIR /app
COPY ./packages/dashboard/pnpm-lock.yaml ./
RUN pnpm fetch
COPY ./packages/dashboard/package*.json ./
COPY ./packages/dashboard/prisma/schema.prisma ./prisma/
RUN pnpm install -r --prefer-offline
COPY ./packages/dashboard ./
COPY ./packages/dashboard /dashboard
RUN npm run build
FROM node:${NODE_VERSION}-buster-slim as app
# APP
FROM node_base AS app
RUN apt update
RUN apt install -y openssl
WORKDIR /app
WORKDIR /dashboard
COPY --from=builder /dashboard/next.config.mjs ./
COPY --from=builder /dashboard/migrations ./migrations
COPY --from=builder /dashboard/public ./public
COPY --from=builder /dashboard/package.json ./package.json
COPY --from=builder --chown=node:node /dashboard/.next/standalone ./
COPY --from=builder --chown=node:node /dashboard/.next/static ./.next/static
COPY --from=builder /app/dist ./
COPY --from=builder /app/next.config.mjs ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder --chown=node:node /app/.next/standalone ./
COPY --from=builder --chown=node:node /app/.next/static ./.next/static
EXPOSE 3000
CMD ["npm", "run", "start"]

View file

@ -2,18 +2,22 @@ ARG NODE_VERSION="18.12.1"
ARG ALPINE_VERSION="3.16"
FROM node:${NODE_VERSION}-buster-slim
WORKDIR /
RUN apt update
RUN apt install -y openssl
RUN npm install pnpm -g
RUN npm install node-gyp -g
WORKDIR /dashboard
COPY ./packages/dashboard/package*.json /dashboard/
COPY ./packages/dashboard/prisma/schema.prisma /dashboard/prisma/
RUN npm install
WORKDIR /app
COPY ./packages/dashboard /dashboard
COPY ./packages/dashboard/pnpm-lock.yaml ./
RUN pnpm fetch
COPY ./packages/dashboard/package*.json ./
COPY ./packages/dashboard/prisma/schema.prisma ./prisma/
RUN pnpm install -r --prefer-offline
COPY ./packages/dashboard ./
CMD ["npm", "run", "dev"]

View file

@ -76,8 +76,7 @@ services:
networks:
- tipi_main_network
volumes:
- ${PWD}/packages/dashboard/src:/dashboard/src
- ${PWD}/packages/dashboard/server.ts:/dashboard/server.ts
- ${PWD}/packages/dashboard/src:/app/src
# - /dashboard/node_modules
# - /dashboard/.next
- ${PWD}/state:/runtipi/state

View file

@ -78,7 +78,6 @@ services:
- ${STORAGE_PATH}:/app/storage
labels:
traefik.enable: true
# Web
traefik.http.routers.dashboard.rule: PathPrefix("/")
traefik.http.routers.dashboard.service: dashboard

View file

@ -29,7 +29,7 @@ module.exports = {
'react/jsx-props-no-spreading': 0,
'react/no-unused-prop-types': 0,
'react/button-has-type': 0,
'import/no-extraneous-dependencies': ['error', { devDependencies: ['**/*.test.{ts,tsx}', '**/*.spec.{ts,tsx}', '**/*.factory.{ts,tsx}', '**/mocks/**', 'tests/**'] }],
'import/no-extraneous-dependencies': ['error', { devDependencies: ['esbuild.js', '**/*.test.{ts,tsx}', '**/*.spec.{ts,tsx}', '**/*.factory.{ts,tsx}', '**/mocks/**', 'tests/**'] }],
'no-underscore-dangle': 0,
},
globals: {

View file

@ -0,0 +1,40 @@
#!/usr/bin/env node
/* eslint-disable @typescript-eslint/no-var-requires */
const esbuild = require('esbuild');
const { spawn } = require('child_process');
const pkg = require('./package.json');
const isDev = process.argv[2] !== 'build';
process.env.NODE_ENV = isDev ? 'development' : 'production';
let server;
const onRebuild = () => {
if (isDev) {
if (server) server.kill('SIGINT');
server = spawn('node', ['dist/index.js'], { stdio: [0, 1, 2] });
} else {
spawn('yarn', ['next', 'build'], { stdio: [0, 1, 2] });
}
};
const included = ['express', 'pg', '@runtipi/postgres-migrations'];
const excluded = ['pg-native', '*required-server-files.json'];
const external = Object.keys(pkg.dependencies || {}).filter((dep) => !included.includes(dep));
external.push(...excluded);
esbuild
.build({
entryPoints: ['src/server/index.ts'],
external,
define: { 'process.env.NODE_ENV': `"${process.env.NODE_ENV}"` },
platform: 'node',
target: 'node14',
outfile: 'dist/index.js',
tsconfig: 'tsconfig.json',
bundle: true,
minify: isDev,
sourcemap: isDev,
watch: isDev,
})
.finally(onRebuild);

View file

@ -1,5 +0,0 @@
{
"watch": ["server.ts", "src/server"],
"exec": "ts-node --project tsconfig.server.json server.ts",
"ext": "js ts"
}

View file

@ -3,16 +3,19 @@
"version": "0.8.1",
"private": true,
"scripts": {
"copy:migrations": "cp -r src/server/migrations dist/migrations",
"prisma:pull": "prisma db pull",
"test": "dotenv -e .env.test -- jest --colors",
"test:client": "jest --colors --selectProjects client --",
"test:server": "jest --colors --selectProjects server --",
"postinstall": "prisma generate",
"dev": "nodemon",
"build": "next build",
"start": "NODE_ENV=production node server.js",
"dev": "npm run copy:migrations && node ./esbuild.js dev",
"start": "NODE_ENV=production node index.js",
"lint": "next lint",
"lint:fix": "next lint --fix"
"lint:fix": "next lint --fix",
"build": "npm run copy:migrations && node ./esbuild.js build",
"build:server": "node ./esbuild.js build",
"build:next": "next build"
},
"dependencies": {
"@hookform/resolvers": "^2.9.10",
@ -21,10 +24,10 @@
"@tabler/core": "1.0.0-beta16",
"@tabler/icons": "^1.109.0",
"@tanstack/react-query": "^4.24.4",
"@trpc/client": "^10.7.0",
"@trpc/next": "^10.9.1",
"@trpc/react-query": "^10.9.1",
"@trpc/server": "^10.9.1",
"@trpc/client": "^10.11.1",
"@trpc/next": "^10.11.1",
"@trpc/react-query": "^10.11.1",
"@trpc/server": "^10.11.1",
"argon2": "^0.29.1",
"clsx": "^1.1.1",
"express": "^4.17.3",
@ -33,8 +36,9 @@
"graphql-tag": "^2.12.6",
"isomorphic-fetch": "^3.0.0",
"jsonwebtoken": "^9.0.0",
"next": "13.1.1",
"next": "13.1.6",
"node-cron": "^3.0.1",
"node-fetch": "^3.3.0",
"pg": "^8.7.3",
"react": "18.2.0",
"react-dom": "18.2.0",
@ -80,7 +84,7 @@
"@typescript-eslint/eslint-plugin": "^5.47.1",
"@typescript-eslint/parser": "^5.47.1",
"dotenv-cli": "^6.0.0",
"esbuild": "^0.16.6",
"esbuild": "^0.16.17",
"eslint": "8.30.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.0.0",
@ -96,7 +100,6 @@
"jest-environment-jsdom": "^29.3.1",
"msw": "^1.0.0",
"next-router-mock": "^0.8.0",
"nodemon": "^2.0.15",
"prettier": "^2.8.4",
"prisma": "^4.8.0",
"ts-jest": "^29.0.3",

File diff suppressed because it is too large Load diff

View file

@ -1,17 +1,31 @@
/* eslint-disable consistent-return */
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable global-require */
import express from 'express';
import { parse } from 'url';
import next from 'next';
import { EventDispatcher } from './src/server/core/EventDispatcher';
import { getConfig, setConfig } from './src/server/core/TipiConfig';
import { Logger } from './src/server/core/Logger';
import type { NextServer } from 'next/dist/server/next';
import { EventDispatcher } from './core/EventDispatcher';
import { getConfig, setConfig } from './core/TipiConfig';
import { Logger } from './core/Logger';
import { runPostgresMigrations } from './run-migration';
import { AppServiceClass } from './src/server/services/apps/apps.service';
import { prisma } from './src/server/db/client';
import { AppServiceClass } from './services/apps/apps.service';
import { prisma } from './db/client';
let conf = {};
let nextApp: NextServer;
const port = parseInt(process.env.PORT || '3000', 10);
const dev = process.env.NODE_ENV !== 'production';
const nextApp = next({ dev });
if (!dev) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const NextServer = require('next/dist/server/next-server').default;
conf = require('./.next/required-server-files.json').config;
nextApp = new NextServer({ hostname: 'localhost', dev, port, customServer: true, conf });
} else {
const next = require('next').default;
nextApp = next({ dev });
}
const handle = nextApp.getRequestHandler();
nextApp.prepare().then(async () => {

View file

@ -1,12 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "dist",
"lib": ["es2019"],
"target": "es2019",
"isolatedModules": false,
"noEmit": false
},
"include": ["server.ts"]
}

View file

@ -1,2 +0,0 @@
packages:
- "packages/**"