[Next.js] - Pre-build scripts

NoowaH·2023년 6월 1일
1

Next.js

목록 보기
17/17

Next.js 앱을 빌드 하기 전에 실행해야 하는 스크립트가 있어야 할 때가 있다

예:
1. robots.txt를 관리 및 빌드 전에 생성하는 스크립트
2. i18n 설정을 위한 locales 값을 외부 API 를 통해 (비동기 처리) 가져오는 스크립트 (내가 겪은 아주 특이한 케이스다)

1 번 예시

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


2 번 예시

2번 예시는 1번과 다르게 비동기 처리가 필요함으로 위와 같은 방법을 사용 했을 때 아래 문제가 생겼다

  • next.config.jsi18n설정은 빌드 시점에 필요
  • isServer에서 처리하는 함수는 비동기 처리시 에러 발생
    - 빌드 도중 locales를 생성함으로 컴파일 에러 발생
    - 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 전에 알아서 실행
    - 하지만 github actions나 Docker 환경에서 실행이 안되는 경우가 있음 🤯
    - 참고 : https://docs.npmjs.com/cli/v9/using-npm/scripts
profile
조하운

0개의 댓글