fix: добавить postbuild.js для копирования статических файлов

- scripts/postbuild.js: новый скрипт для копирования public и .next/static в .next/standalone
- package.json: запуск postbuild.js после npm run build
- scripts/install.sh: использование postbuild.js вместо ручного копирования
- scripts/manage.sh: использование postbuild.js вместо ручного копирования
- next.config.js: убран outputFileTracingRoot (не работает в Next.js 16)

Теперь стили и статические файлы должны корректно работать в продакшене
This commit is contained in:
kilyabin
2026-03-05 14:21:42 +04:00
parent 39cdf692ce
commit c43bed396e
5 changed files with 106 additions and 45 deletions

View File

@@ -4,7 +4,6 @@ const nextConfig = {
output: 'standalone',
generateEtags: false,
allowedDevOrigins: ['192.168.1.10'],
// Не используем outputFileTracingRoot для корректной работы standalone режима
webpack: (config, { isServer }) => {
// Исключаем fs и path из клиентской сборки
if (!isServer) {
@@ -16,7 +15,6 @@ const nextConfig = {
}
return config
},
// Указываем корневую директорию для устранения предупреждения о множественных lockfiles
turbopack: {
root: __dirname,
},

View File

@@ -8,7 +8,7 @@
},
"scripts": {
"dev": "node --disable-warning=DEP0169 ./node_modules/next/dist/bin/next dev --webpack -H 0.0.0.0",
"build": "next build --webpack",
"build": "next build --webpack && node scripts/postbuild.js",
"start": "next start -H 0.0.0.0",
"lint": "next lint"
},

View File

@@ -236,26 +236,15 @@ fi
echo -e "${YELLOW}Building the application...${NC}"
npm run build
# Ensure public directory and static files are accessible in standalone build
echo -e "${YELLOW}Setting up static files...${NC}"
if [ -d "$INSTALL_DIR/.next/standalone" ]; then
# Copy public directory to standalone (always update)
if [ -d "$INSTALL_DIR/public" ]; then
echo -e "${YELLOW}Copying public directory to standalone...${NC}"
rm -rf "$INSTALL_DIR/.next/standalone/public" 2>/dev/null || true
cp -r "$INSTALL_DIR/public" "$INSTALL_DIR/.next/standalone/public" 2>/dev/null || true
fi
# Copy .next/static to standalone/.next/static (always update)
if [ -d "$INSTALL_DIR/.next/static" ]; then
echo -e "${YELLOW}Copying .next/static to standalone...${NC}"
rm -rf "$INSTALL_DIR/.next/standalone/.next/static" 2>/dev/null || true
mkdir -p "$INSTALL_DIR/.next/standalone/.next"
cp -r "$INSTALL_DIR/.next/static" "$INSTALL_DIR/.next/standalone/.next/static" 2>/dev/null || true
# Post-build script already copies public and .next/static to standalone directory
# Just verify the files are in place
echo -e "${YELLOW}Verifying standalone build...${NC}"
if [ -d "$INSTALL_DIR/.next/standalone/public" ] && [ -d "$INSTALL_DIR/.next/standalone/.next/static" ]; then
echo -e "${GREEN}✓ Static files are in place${NC}"
else
echo -e "${RED}Warning: .next/static directory not found!${NC}"
fi
else
echo -e "${RED}Warning: .next/standalone directory not found!${NC}"
echo -e "${RED}Warning: Static files may be missing from standalone directory${NC}"
echo -e "${YELLOW}Running post-build script manually...${NC}"
node scripts/postbuild.js || true
fi
# Check if service user exists, create if not

View File

@@ -192,29 +192,15 @@ case "$1" in
exit 1
fi
# Ensure public directory and static files are accessible in standalone build
echo -e "${YELLOW}Setting up static files...${NC}"
if [ -d "$INSTALL_DIR/.next/standalone" ]; then
# Copy public directory to standalone (always update)
if [ -d "$INSTALL_DIR/public" ]; then
echo -e "${YELLOW}Copying public directory to standalone...${NC}"
rm -rf "$INSTALL_DIR/.next/standalone/public" 2>/dev/null || true
cp -r "$INSTALL_DIR/public" "$INSTALL_DIR/.next/standalone/public" 2>/dev/null || true
fi
# Copy .next/static to standalone/.next/static (always update)
if [ -d "$INSTALL_DIR/.next/static" ]; then
echo -e "${YELLOW}Copying .next/static to standalone...${NC}"
rm -rf "$INSTALL_DIR/.next/standalone/.next/static" 2>/dev/null || true
mkdir -p "$INSTALL_DIR/.next/standalone/.next"
cp -r "$INSTALL_DIR/.next/static" "$INSTALL_DIR/.next/standalone/.next/static" 2>/dev/null || true
# Post-build script already copies public and .next/static to standalone directory
# Just verify the files are in place
echo -e "${YELLOW}Verifying standalone build...${NC}"
if [ -d "$INSTALL_DIR/.next/standalone/public" ] && [ -d "$INSTALL_DIR/.next/standalone/.next/static" ]; then
echo -e "${GREEN}✓ Static files are in place${NC}"
else
echo -e "${RED}Warning: .next/static directory not found!${NC}"
fi
else
echo -e "${RED}Error: .next/standalone directory not found!${NC}"
echo -e "${RED}This usually means the build failed or output: 'standalone' is not configured correctly.${NC}"
echo -e "${RED}Please check next.config.js and ensure the build completed successfully.${NC}"
exit 1
echo -e "${RED}Warning: Static files may be missing from standalone directory${NC}"
echo -e "${YELLOW}Running post-build script manually...${NC}"
node scripts/postbuild.js || true
fi
# Set ownership

88
scripts/postbuild.js Normal file
View File

@@ -0,0 +1,88 @@
#!/usr/bin/env node
/**
* Post-build script for Next.js standalone mode
* Copies public and .next/static files to .next/standalone directory
*/
const fs = require('fs');
const path = require('path');
const ROOT_DIR = process.cwd();
const STANDALONE_DIR = path.join(ROOT_DIR, '.next', 'standalone');
const PUBLIC_DIR = path.join(ROOT_DIR, 'public');
const NEXT_STATIC_DIR = path.join(ROOT_DIR, '.next', 'static');
const STANDALONE_PUBLIC_DIR = path.join(STANDALONE_DIR, 'public');
const STANDALONE_NEXT_STATIC_DIR = path.join(STANDALONE_DIR, '.next', 'static');
// Helper function to copy directory recursively
function copyDir(src, dest) {
if (!fs.existsSync(src)) {
console.error(`Source directory does not exist: ${src}`);
return false;
}
if (!fs.existsSync(dest)) {
fs.mkdirSync(dest, { recursive: true });
}
const entries = fs.readdirSync(src, { withFileTypes: true });
for (const entry of entries) {
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
if (entry.isDirectory()) {
copyDir(srcPath, destPath);
} else {
fs.copyFileSync(srcPath, destPath);
}
}
return true;
}
// Helper function to remove directory recursively
function removeDir(dir) {
if (fs.existsSync(dir)) {
fs.rmSync(dir, { recursive: true, force: true });
}
}
console.log('Post-build: Setting up standalone directory...');
// Check if standalone directory exists
if (!fs.existsSync(STANDALONE_DIR)) {
console.error('Error: .next/standalone directory not found!');
console.error('Make sure output: "standalone" is set in next.config.js');
process.exit(1);
}
// Copy public directory
if (fs.existsSync(PUBLIC_DIR)) {
console.log(`Copying ${PUBLIC_DIR} to ${STANDALONE_PUBLIC_DIR}...`);
removeDir(STANDALONE_PUBLIC_DIR);
if (copyDir(PUBLIC_DIR, STANDALONE_PUBLIC_DIR)) {
console.log('✓ Public directory copied');
} else {
console.error('✗ Failed to copy public directory');
}
} else {
console.warn('Warning: public directory not found');
}
// Copy .next/static directory
if (fs.existsSync(NEXT_STATIC_DIR)) {
console.log(`Copying ${NEXT_STATIC_DIR} to ${STANDALONE_NEXT_STATIC_DIR}...`);
removeDir(STANDALONE_NEXT_STATIC_DIR);
if (copyDir(NEXT_STATIC_DIR, STANDALONE_NEXT_STATIC_DIR)) {
console.log('✓ .next/static directory copied');
} else {
console.error('✗ Failed to copy .next/static directory');
}
} else {
console.error('Error: .next/static directory not found!');
process.exit(1);
}
console.log('Post-build: Done!');