Next.js 앱을 빌드 하기 전에 실행해야 하는 스크립트가 있어야 할 때가 있다
예:
1. robots.txt를 관리 및 빌드 전에 생성하는 스크립트
2. i18n 설정을 위한 locales 값을 외부 API 를 통해 (비동기 처리) 가져오는 스크립트 (내가 겪은 아주 특이한 케이스다)
1번 예시는 상대적으로 쉽게 next.config.js
설정 중 webpack
설정에서 쉽게 처리가 가능하다
step 1 : robots.txt
를 /public/
경로에 생성하는 next-robots.js
스크립트를 만든다
const path = require('path')
const fs = require('fs')
/**
* Generate robots.txt file
*
* https://developers.google.com/search/docs/advanced/robots/robots_txt
*/
const generateRobotsTxt = (baseUrl = '', disallowedRoutes = []) => {
//...
return robotsTxt
}
/**
* Write robots.txt file into public directory
*
* @param {*} content
*/
const writeRobotsTxt = (content = '') => {
const robotsPath = path.join(process.cwd(), 'public/robots.txt')
fs.writeFile(robotsPath, content, (err) => {
if (err) {
throw err
}
})
}
module.exports = {
generateRobotsTxt,
writeRobotsTxt
}
step 2 : next.config/js
const nextConfig = {
...
webpack: (config, options) => {
const { isServer } = options
config.module.rules.push({
if (isServer) {
require('./next-robots')
}
},
...
}
module.exports = nextConfig
isServer
: server-side compilation (서버 사이드 컴파일) 즉 빌드 시점일 땐 true
값을 반환isServer
를 이용하여 빌드 시점에 파일을 생성2번 예시는 1번과 다르게 비동기 처리가 필요함으로 위와 같은 방법을 사용 했을 때 아래 문제가 생겼다
next.config.js
의 i18n
설정은 빌드 시점에 필요isServer
에서 처리하는 함수는 비동기 처리시 에러 발생i18n
설정에 필요한 데이터를 가져오는 것 과 빌드의 확실한 순서 처리가 필요함step1: next-18next.config.js
에 사용될 locales
데이터를 불러오는 generate-locales.js
스크립트 생성
generate-locales.js
/**
* generate locale data
*/
const fs = require('fs')
const fetch = require('node-fetch')
const generateLocales = async () => {
const response = await fetch('/generate-locale-api-url')
return response.data // ['en', 'fr', ...]
}
/**
* write locales.json
*/
const writeLocales = async () => {
const locales = await generateLocales()
// defaultLocales must be included in locales too
const defaultLocale = 'en'
const localesModel = {
locales,
defaultLocale
}
fs.writeFile(`locales.json`,
JSON.stringify(localesModel), (err) => {
if (err) {
throw err
}
})
}
writeLocales()
next-18next.config.js
const localeData = require('./locales.json')
const { locales, defaultLocale } = localeData
const config = {
i18n: {
defaultLocale,
locales,
localeDetection: false,
}
}
module.exports = config
step2: package.json에 빌드 스크립트 업데이트
package.json
{
"scripts": {
"generate-locales": "node generate-locales.js",
"build": "npm run generate-locales && next build"
}
}
&&
를 사용하여 스크립트의 순서를 확실하게 구분한다pre
prefix를 이용하여 prebuild
와 같이 스크립트 이름을 설정하면 알아서 실행되기도 한다prebuild
라는 이름으로 스크립트를 만들면 build
전에 알아서 실행