feat(frontend): add build script

The build script prepares the package for a production build, builds the app, places every all needed files in a dist directory and cleans it.

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2023-08-26 14:26:47 +02:00
parent 7b3c217470
commit 4cb332622a
7 changed files with 50 additions and 26 deletions

View file

@ -142,7 +142,7 @@ jobs:
TURBO_TEAM: ${{ vars.TURBO_TEAM }} TURBO_TEAM: ${{ vars.TURBO_TEAM }}
- name: Compress build - name: Compress build
run: tar --exclude='frontend/.next/cache' --exclude='frontend/.next/standalone' --zstd -cf frontend-e2e-build.tar.zst frontend/.next/ run: tar --zstd -cf frontend-e2e-build.tar.zst frontend/dist/
- name: Upload build artifact - name: Upload build artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
@ -186,9 +186,12 @@ jobs:
- name: Run server - name: Run server
working-directory: frontend/ working-directory: frontend/
run: (screen -dmS server -L yarn start:ci) && sleep 3 && (tail -f screenlog.0 &) run: (screen -dmS server -L yarn start) && sleep 3 && (tail -f screenlog.0 &)
env: env:
NODE_ENV: test NODE_ENV: test
HOSTNAME: "127.0.0.1"
HD_BASE_URL: "http://127.0.0.1:3001/"
PORT: 3001
- name: Wait for server - name: Wait for server
run: "curl -L --max-time 120 http://127.0.0.1:3001/" run: "curl -L --max-time 120 http://127.0.0.1:3001/"

34
frontend/build.sh Executable file
View file

@ -0,0 +1,34 @@
#!/bin/sh
#
# SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
#
# SPDX-License-Identifier: AGPL-3.0-only
#
set -e
echo "🦔 Frontend Production Build"
echo "🦔 > Clearing existing builds"
rm -rf dist/
echo "🦔 > Preparing files"
if [ "${1}" = "--keep-mock-api" ]; then
echo "🦔 > Keeping Mock API"
else
rm -rf src/pages/api
fi
echo "🦔 > Building"
next build
echo "🦔 > Bundling"
mv .next/standalone dist
mkdir -p dist/frontend/.next
cp -R .next/static dist/frontend/.next/static
cp next.config.js dist/frontend/next.config.js
cp -R public dist/frontend/public
rm -f dist/frontend/.env
rm -rf dist/frontend/public/public
rm -rf dist/frontend/src
echo "🦔 > Done! You can run the build by going into the dist directory and executing \`node frontend/server.js\`"

View file

@ -26,8 +26,6 @@ ARG TURBO_TEAM
ARG TURBO_API ARG TURBO_API
ARG TURBO_TOKEN ARG TURBO_TOKEN
RUN rm -rf frontend/public/public
RUN rm -rf frontend/src/pages/api
RUN yarn turbo run build --filter=frontend --no-cache --no-daemon RUN yarn turbo run build --filter=frontend --no-cache --no-daemon
# RUNNER # RUNNER
@ -43,10 +41,7 @@ LABEL org.opencontainers.image.licenses='AGPL-3.0'
WORKDIR /usr/src/app WORKDIR /usr/src/app
COPY --from=builder --chown=node:node /usr/src/app/frontend/.next/standalone ./ COPY --from=builder --chown=node:node /usr/src/app/frontend/dist ./
COPY --from=builder --chown=node:node /usr/src/app/frontend/.next/static ./frontend/.next/static
COPY --from=builder /usr/src/app/frontend/next.config.js ./frontend/next.config.js
COPY --from=builder /usr/src/app/frontend/public ./frontend/public
USER node USER node

View file

@ -3,7 +3,7 @@
* *
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
const { isMockMode, isTestMode, isProductionMode, isProfilingMode } = require('./src/utils/test-modes') const { isMockMode, isTestMode, isProfilingMode } = require('./src/utils/test-modes')
const path = require('path') const path = require('path')
const CopyWebpackPlugin = require('copy-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin')
const withBundleAnalyzer = require('@next/bundle-analyzer')({ const withBundleAnalyzer = require('@next/bundle-analyzer')({
@ -90,7 +90,7 @@ const rawNextConfig = {
} }
]) ])
}, },
output: isProductionMode ? 'standalone' : undefined, output: 'standalone',
swcMinify: false, //Otherwise emoji picker is minified incorrectly swcMinify: false, //Otherwise emoji picker is minified incorrectly
experimental: { experimental: {
outputFileTracingRoot: path.join(__dirname, '../') outputFileTracingRoot: path.join(__dirname, '../')

View file

@ -4,16 +4,15 @@
"private": true, "private": true,
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {
"build": "cross-env NODE_ENV=production next build", "build": "cross-env NODE_ENV=production ./build.sh",
"build:mock": "cross-env NEXT_PUBLIC_USE_MOCK_API=true next build", "build:mock": "cross-env NEXT_PUBLIC_USE_MOCK_API=true ./build.sh --keep-mock-api",
"build:test": "cross-env NODE_ENV=test NEXT_PUBLIC_TEST_MODE=true next build", "build:test": "cross-env NODE_ENV=test NEXT_PUBLIC_TEST_MODE=true ./build.sh --keep-mock-api",
"analyze": "cross-env ANALYZE=true yarn build --profile", "analyze": "cross-env ANALYZE=true yarn build --profile",
"format": "prettier -c \"src/**/*.{ts,tsx,js}\" \"cypress/**/*.{ts,tsx}\"", "format": "prettier -c \"src/**/*.{ts,tsx,js}\" \"cypress/**/*.{ts,tsx}\"",
"format:fix": "prettier -w \"src/**/*.{ts,tsx,js}\" \"cypress/**/*.{ts,tsx}\"", "format:fix": "prettier -w \"src/**/*.{ts,tsx,js}\" \"cypress/**/*.{ts,tsx}\"",
"lint": "eslint --max-warnings=0 --ext .ts,.tsx src", "lint": "eslint --max-warnings=0 --ext .ts,.tsx src",
"lint:fix": "eslint --fix --ext .ts,.tsx src", "lint:fix": "eslint --fix --ext .ts,.tsx src",
"start": "cross-env PORT=${HD_FRONTEND_PORT:-3001} next start", "start": "cross-env PORT=${HD_FRONTEND_PORT:-3001} node dist/frontend/server.js",
"start:ci": "cross-env PORT=3001 NODE_ENV=test next start",
"start:dev": "cross-env PORT=${HD_FRONTEND_PORT:-3001} next dev", "start:dev": "cross-env PORT=${HD_FRONTEND_PORT:-3001} next dev",
"start:dev:mock": "cross-env PORT=${HD_FRONTEND_PORT:-3001} NEXT_PUBLIC_USE_MOCK_API=true HD_BASE_URL=\"http://localhost:3001/\" HD_RENDERER_BASE_URL=\"http://127.0.0.1:3001/\" next dev", "start:dev:mock": "cross-env PORT=${HD_FRONTEND_PORT:-3001} NEXT_PUBLIC_USE_MOCK_API=true HD_BASE_URL=\"http://localhost:3001/\" HD_RENDERER_BASE_URL=\"http://127.0.0.1:3001/\" next dev",
"start:dev:test": "cross-env PORT=${HD_FRONTEND_PORT:-3001} NODE_ENV=test NEXT_PUBLIC_TEST_MODE=true next dev", "start:dev:test": "cross-env PORT=${HD_FRONTEND_PORT:-3001} NODE_ENV=test NEXT_PUBLIC_TEST_MODE=true next dev",

View file

@ -37,12 +37,6 @@ const isMockMode = !!process.env.NEXT_PUBLIC_USE_MOCK_API && isPositiveAnswer(pr
*/ */
const isDevMode = process.env.NODE_ENV === 'development' const isDevMode = process.env.NODE_ENV === 'development'
/**
* Defines if the current runtime was built in production mode.
* @type boolean
*/
const isProductionMode = process.env.NODE_ENV === 'production'
/** /**
* Defines if the current runtime contains the bundle analyzer and profiling metrics. * Defines if the current runtime contains the bundle analyzer and profiling metrics.
* @type boolean * @type boolean
@ -53,6 +47,5 @@ module.exports = {
isTestMode, isTestMode,
isMockMode, isMockMode,
isDevMode, isDevMode,
isProductionMode,
isProfilingMode isProfilingMode
} }

View file

@ -31,8 +31,8 @@
"^build" "^build"
], ],
"outputs": [ "outputs": [
".next/**", "dist/**",
"!.next/cache/**" "!.next/**"
], ],
"env": [ "env": [
"NODEJS_VERSION" "NODEJS_VERSION"
@ -56,8 +56,8 @@
"^build" "^build"
], ],
"outputs": [ "outputs": [
".next/**", "dist/**",
"!.next/cache/**" "!.next/**"
], ],
"env": [ "env": [
"NODEJS_VERSION" "NODEJS_VERSION"