개요
require 블록은 Story-Bakery 코드 스타일의 핵심 축입니다. 외부 패키지, 공용 조상, 내부 모듈을 predictable 하게 불러와야 코드 리뷰가 쉬워지고, alias 충돌이나 잘못된 경로로 인한 런타임 오류를 예방할 수 있습니다. 이 문서는 code-style.md 에서 다루던 require 규칙을 세분화해, 어떤 상황에서도 동일한 패턴을 유지하도록 가이드를 제공합니다.
- 모든
require는 가능한 한 문자열 literal 과 사전에 등록된 alias 를 사용하지만, 모듈 인스턴스를 외부에서 주입받아야 하는 경우에는 해당ModuleScript참조를 그대로require할 수 있습니다. - 블록 간 순서와 빈 줄 규칙을 고정해 diff 잡음과 merge conflict 를 줄입니다.
- Require 직후 등장하는 별칭 블록도 동일한 순서를 따릅니다.
작성 원칙
블록 우선순위
Require 문은 아래 네 가지 묶음으로 나누고, 목록 순서를 반드시 지킵니다. 묶음 내부는 같은 종류일 때만 붙여 쓰며, 묶음이 바뀌면 한 줄을 비워 가독성을 확보합니다.
- 외부/패키지 레벨 의존성
require("@Promise"),require("@DynamicTween")처럼rokit,pesde,roblox_packages등에서 배포된 공용 패키지 alias 를 먼저 적습니다. 같은 패키지 이름이라도 경로가 다르면 사전식으로 정렬합니다. - 공통 조상(common ancestor)
local ItemModules = script.Parent또는local GameModules = ReplicatedStorage.GameModules처럼 현재 스크립트에서 여러 번 참조할 상위 노드를 정의합니다. 이후에 이 조상으로부터 상대 경로를 잡아야 하므로 외부 require 다음에 바로 둡니다. - 조상 내부 하위 모듈
공통 조상으로부터 파생되는 서브 모듈(local FruitDefinition = require(ItemModules.Food.Fruit))을 묶습니다. 디렉터리 구조를 반영해 하위 폴더명 → 모듈명 순으로 사전식 정렬합니다. - 동일 프로젝트의 나머지 모듈
아직 분류되지 않은 내부 모듈을 묶습니다. 서비스 단위(InventoryModules,UIRoot등)로 그룹을 나누고, 그룹 간에는 빈 줄을 한 줄만 둡니다.
특정 모듈 간 의존성 때문에 로드 순서를 강제해야 한다면, 필요한 범위 안에서만 정렬 규칙을 깨고 코드 주석으로 이유를 밝혀 주세요.
경로와 alias 규칙
require호출에는 기본적으로 문자열 literal alias 를 전달하지만, 다른 시스템에서 건네준ModuleScript인스턴스나 미리 정의된 테이블에서 꺼낸 경로 값처럼 정적·신뢰 가능한 참조라면 변수를 넘길 수 있습니다. 이때도 문자열을 즉석에서 이어 붙이거나, 서비스 체인을 바로 넘기는 방식은 금지입니다.- 예:
local moduleScript: ModuleScript = params.ModuleScript처럼 함수 매개변수로 받은 모듈, 혹은local modulePath = DefinitionPathByName[name]처럼 상수 테이블에서 꺼낸 문자열은 그대로require(moduleScript)또는require(modulePath)로 사용 가능합니다. .luaurc에 alias 가 정의되어 있다면 가장 짧은 alias 를 사용합니다. 예:@BakeryModules/Promise대신@Promise가 존재한다면@Promise로 통일합니다.- 같은 패키지 내 하위 모듈은
require("@Package/SubModule")형태로 명시하고, 현재 파일 기준 상대 경로가 더 짧으면require("./SubModule")또는require("../Shared/SubModule")를 사용합니다. - 패키지 내부에서만 이동할 때는
@self/alias 를 사용합니다. 자식·손자 모듈은@self/SubModule,@self/SubFolder/Module처럼 작성합니다 - 부모나 2차 부모까지는
./,../처럼 필요한 만큼..를 연결합니다. 이렇게 하면script.Parent체인을 직접 넘기지 않고도 동일 패키지 내 경로를 고정할 수 있습니다, 그리고 형제 모듈도 마찬가지../Sibling,../Sibling2 - Roblox Instance 체인을 따라가는
require(game.ReplicatedStorage.Modules.Module)패턴, 혹은script.Parent.Parent를 직접 넘기는 패턴은 금지입니다. 항상 문자열 alias 와 조상 변수를 조합해 경로를 고정하세요.
정렬 규칙
- 같은 블록 안에서는 알파벳 순을 기본으로 하며, 폴더 경로가 있을 경우
Folder.Module전체 문자열을 기준으로 비교합니다. - 이 규칙을 깨야 할 정도로 의존 순서가 중요한 경우, 해당 묶음에서만 순서를 바꾸고 이유를 설명하는 한 줄 주석을 붙입니다. 다른 블록에는 영향을 주지 않습니다.
- Require 문 사이에 다른 코드(조건문, 함수 호출 등)를 끼워넣지 않습니다. Require 구역을 모두 끝낸 뒤에 상수, 변수, 함수 선언을 시작합니다.
공통 조상 정의
- 스크립트가 접근해야 할 상위 객체(
script.Parent,ReplicatedStorage.GameModules등)를 변수로 저장할 때는 조상에서 자식으로 내려가는 순서대로 작성합니다. - 조상 변수는 PascalCase 로 이름 짓고, 하위 정적 폴더를 계속 참조해야 한다면 계층마다 변수를 둬서 require 경로에서 사용할 준비를 합니다.
- 조상 변수만으로 경로를 설명할 수 없다면, alias 기반 절대 경로를 우선 고려합니다.
외부 라이브러리 별칭 블록
Require 블록이 끝나면 바로 이어서 별칭 블록을 작성합니다. 목적은 외부 패키지에서 자주 쓰는 객체를 짧게 호출하기 위함이며, 아래 규칙을 따릅니다.
- Require 에서 등장한 모듈 순서를 그대로 따릅니다.
- 같은 모듈에서 꺼낸 별칭끼리는 빈 줄 없이 배치하고, 모듈이 바뀔 때만 한 줄을 비웁니다.
- 클래스를 반환하는 객체나 컴포넌트는 PascalCase 별칭을 먼저 두고, 그다음 함수나 팩토리(lowerCamelCase)를 배치합니다.
- 별칭 블록에서는 새로운 계산을 하지 않습니다. 단순히 프로퍼티를 분해해 로컬 변수로 저장하는 용도로만 사용합니다.
작성 절차
- 필요한 모든 모듈을 목록으로 적어 외부 → 조상 → 내부 순으로 분류합니다.
- 각 묶음 안에서 문자열 경로를 사전식으로 정렬합니다.
- 문자열 literal 경로인지, alias 가 가장 짧은지, 상대 경로가 맞는지 다시 확인합니다.
- Require 블록 뒤에 즉시 별칭 블록을 작성하고, 이후 일반 지역 상수/변수를 선언합니다.
- 새로운 모듈이 추가되면 동일한 규칙에 맞춰 위치를 결정하고, 정렬을 다시 확인합니다.