...
Path 모듈
path 모듈은 운영체제별로 경로 구분자가 달라 생기는 문제를 쉽게 해결하기 위해 등장했다.
문제는 운영체제 별로 달라지는 구분자에 대한 이슈는 다음과 같다.
크게 Windows, POSIX 로 갈리는데, POSIX는 유닉스 기반의 운영체제를 말하고, macOS 와 Linux 가 이에 속해있다.
- Windows: C:\Users\ano 처럼 \ 를 사용해 폴더를 구분한다.
- POSIX: /Users/ano 처럼 / 를 사용해 폴더를 구분한다.
path 모듈을 사용하면 폴더와 파일의 경로를 쉽게 조작할 수 있어 위와 같은 경로 구분자 이슈를 쉽게 해결하고, 이외에 파일명에서 파일명, 확장자를 별도로 때어서 활용할 수 있 수 있다.
path 모듈 method
path 모듈은 내장 모듈이므로 별도 npm 설치없이 아래 처럼 불러와 사용할 수 있다.
const path = require('path');
- path.sep: 경로의 구분자입니다. Windows는 \, POSIX는 /입니다.
- path.delimiter: 환경 변수의 구분자입니다. process.env.PATH를 입력하면 여러 개의 경로가 이 구분자로 구분되어 있습니다. Windows는 세미콜론(;)이고 POSIX는 콜론(:)입니다.
- path.dirname(경로): 파일이 위치한 폴더 경로를 보여줍니다.
- path.extname(경로): 파일의 확장자를 보여줍니다.
- path.basename(경로, 확장자): 파일의 이름(확장자 포함)을 보여줍니다. 파일의 이름만 표시하고 싶다면 basename의 두 번째 인자로 파일의 확장자를 넣어주면 됩니다.
- path.parse(경로): 파일 경로를 root, dir, base, ext, name으로 분리합니다.
- path.format(객체): path.parse()한 객체를 파일 경로로 합칩니다.
- path.normalize(경로): /나 \를 실수로 여러 번 사용했거나 혼용했을 때 정상적인 경로로 변환해줍니다.
- path.isAbsolute(경로): 파일의 경로가 절대경로인지 상대경로인지 true나 false로 알려줍니다.
- path.relative(기준경로, 비교경로): 경로를 두 개 넣으면 첫 번째 경로에서 두 번째 경로로 가는 방법을 알려줍니다.
- path.join(경로, .. .): 여러 인자를 넣으면 하나의 경로로 합쳐줍니다. 상대경로인 ..(부모 디렉터리)과 .(현 위치)도 알아서 처리해줍니다.
- path.resolve(경로, .. .): path.join()과 비슷하지만 차이가 있습니다.
path.resolve([…paths])
여러 인자를 넣으면 경로를 묶어 root 경로를 고려한 새로운 경로를 반환한다.
path.join()과 비슷한데 resolve는 다음과 같은 특징이 있다.
오른쪽 인자 부터 읽어가며 절대경로를 만든다.
// 인자 c 부터 읽어 들인다.
path.resolve('/a', 'b', 'c');
// Returns: /a/b/c
// /a 루트 폴더가 아닌 경우 root folder 까지의 경로를 붙여서 반환함
// 현재 해당 파일을 실행시키는 경로가 User/ano/temp/directory.js 라면
path.resolve('/a', 'b', 'c');
// Returns: User/ano/temp/a 를 반환
오른쪽 인자 부터 읽다가 /folder_nmae 형태의 경로(path)가 등장하면 절대 경로로 인식해서 그 경로(path)를 바로 반환한다.
따라서 절대 경로가 아닌 경우 상대경로 형태의 표기(./folder_name) 를 해서 젇대 경로가 아님을 확실하게 구분해야 한다.
// /b가 절대경로 이므로 /b/c가 반환되고 '/a'는 무시된다.
path.resolve('/a', '/b', 'c');
// Returns: /b/c
// /c 가 절대경로 이므로 '/a', '/b' 는 무시된다
path.resolve('/a', '/b', '/c');
// Returns: /c
전달된 인자의 조합으로 절대경로가 생성되지 않으면 working directory를 추가하여 절대경로를 만든다.
// 전달된 인자에 '/folder_name' 형태의 인자가 없으므로, working directory를 추가하여 절대경로 생성
path.resolve('a', 'b', 'c'); // {current_working_directory}/a/b/c
리턴하는 과정에서 경로 구분자(sperator) 를 운영체제에 맞게 nomalize 한다.
path.resolve('a, b, c');
// Returns:
// WINDOW: 'C:a\b\c'
// POSIX(mac, linux): '/a/b/c'
// /a 를 WINDOW에서 사용하면 경로구분자를 바꿔서 반환해준다.
path.resolve('/a');
// Returns: C:\a
// \a를 POSIX(mac, linux) 에서 사용하면 경로 구분자를 바꿔서 반환해준다.
path.resolve('\a')
// Returns: /a
어떤 인자도 전달하지 않는다면 현재 working directory 를 반환한다.
현재 작업 중인 파일이 /Users/ano/directory.js 라면 Users/ano 를 반환한다.
// User/ano/directory.js 에서 실행된다면 working directory 를 반환
console.log(path.resolve(''));
// Returns: `/User/ano`
결론적으로 path.resolve 는 전달된 인자를 오른쪽에서 왼쪽으로 읽으며 상대로와 절대 경로를 구분하고 절대경로를 만들어 반환한다.
path.join([…paths])
여러 인자를 넣으면 하나의 경로를 합쳐 반환하다.
상대경로를 표시하는 .. 와 현 위치를 표시하는 . 도 반영한 결과를 리턴한다.
path.join('/foo', 'bar', 'baz/asdf', 'quux');
// Returns: '/foo/bar/baz/asdf/quux'
// 마지막 인자의 .. 가 현재 위치보다 한단계 위 상위 폴더를 의미하므로
// '/foo/bar/baz/asdf/quux' 보다 한 단계가 위 폴더의 경로가 반환됨
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// Returns: '/foo/bar/baz/asdf'
// __dirname : User/ano/temp/direcotory
// 상대경로와 절대경로를 인자로 전달한 경우 이를 반영한 결과를 리턴함
// 두 단계 올라간 User/ano 에서 /workspace 폴더로 내려가 다시 /ano 폴더를 찾음
path.join(__dirname, '..', '..','workspace', '.', '/ano');
// Returns: User/ano/workspace/ano
path.sep
경로의 구분자(seperator) 이다.
Windows는 \ , POSIX 는 / 값을 담고 있다.
path.delimiter
환경 변수의 구분자이다.
필자의 로컬환경에서 process.env.PATH 를 조회하면
/Users/ano/.nvm/versions/node/v10.10.0/bin:/usr/local/opt/node@8/bin:/usr/local/opt/php@7.2/sbin:/usr/local/opt/php@7.2/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/opt/fzf/bin
라는 결과를 얻을 수 있는데 여기에 환경 변수를 구분하는 구분자로 :, colon 이 쓰이고 있다.
Windows 는 세미콜론(;)을 사용하고, POSIX 는 콜론(:)을 사용한다.
path.dirname(paths)
현재 파일이 위치한 폴더 경로를 보여준다.
// __filename : '/Users/ano/temp/directory.js'
path.dirname(__filename);
// Returns: '/Users/ano/temp'
path.extname(paths)
파일의 확장자를 보여준다.
// __filename : '/Users/ano/temp/directory.js'
path.extname(__filename);
// Returns: '.js'
path.basenaem(path[, ext])
파일의 이름(확장자 포함)을 보여준다.
파일의 이름만 표시하고 싶다면 basnme 의 두 번째 인자로 파일의 확장자(ext)를 넣어주면 된다.
// __filename : '/Users/ano/temp/directory.js'
path.basename(__filename);
// Returns: 'directory.js'
// path.extname(__filename): '.js'
path.basename(__filename, path.extname(__filename));
// Returns: 'directory'
path.parse()
파일 경로를 인자로 받아, root, dir, base, ext, name으로 분리한 후 해당 내용을 담은 객체값을 리턴한다.
// On Windows:
path.parse('C:\\path\\dir\\file.txt');
// Returns:
// { root: 'C:\\',
// dir: 'C:\\path\\dir',
// base: 'file.txt',
// ext: '.txt',
// name: 'file' }
┌─────────────────────┬────────────┐
│ dir │ base │
├──────┬ ├──────┬─────┤
│ root │ │ name │ ext │
" C:\ path\dir \ file .txt "
└──────┴──────────────┴──────┴─────┘
("" 안에 있는 모든 공백은 무시된다.)
path.format(pathObject)
path.parse() 한 객체를 인자로 받아 합쳐서 경로 문자열(string)을 리턴한다.
// __filename : '/Users/ano/temp/directory.js'
// path.prase(__filename) Returns:
/*
{
root: "/",
dir: "/Users/ano/temp",
base: "directory.js",
ext: ".js",
name: "directory"
}
*/
path.format(path.parse(__filename));
// Returns: '/Users/ano/temp/directory.js'
path.normalize(path)
/ 나 \ 를 실수로 여러번 사용했거나 혼용한 경우 정상적인 경로로 변환해준다.
path.nomalize('\\Users///ano\\\temp/directory.js');
// Returns: '/Users/ano/temp/directory.js'
path.isAbsolute(path)
파일의 경로가 절대경로인지, 상대경로인지 true or false 로 반환해준다.
// '/Users/ano/temp/directory.js'
path.isAbsolute('/Users'); //Returns: true
path.isAbsolute('./ano'); //Returns: false
path.relative(from, to)
두 경로를 인자로 전달하면, 첫번째 경로에서 두번째 경로로 가는 방법을 결과로 리턴한다.
// '/Users/ano/temp/directory.js'
path.relative('/Users/ano/temp/directory.js', '/Users');
// Returns: '../../..'
// 첫번째 경로에서 리턴값이 제시한 대로 경로로 가면 두번째 경로로 가게된다는 뜻.
path.posix, path.win32
종종 Windows 에서 POSIX 스타일을, POSIX 에서 Windows 스타일을 사용할 때가 있다.
- 그런 경우에 Windows 에서는 path.posix.sep, path.posix.join() 같이 사용하면 되고,
- POSIX 에서는 path.win32.sep, path.win32.join() 를 활용하면 된다.
특이사항
Windows 환경에서 \\ 와 \를 같이 사용하는 경우
Windows 환경에서 기본적으로 \ 하나를 써서 경로를 표현한다.
하지만 자바스크립트 문자열에서 \ 가 특수문자이기 때문에 \를 하나 더 붙여 \\ 특수문자가 아닌 경로로 쓰인다는 것을 표기해야 한다.
예를 들어 \n은 자바스크립트에서 줄바꿈이라는 뜻이다.
따라서 C:\node 와 같은 경로에서 의도치 않은 오류가 발생할 수 있으므로 C:\\node로 표시한다.
상대경로와 절대 경로
절대경로는 루트 폴더(Windows의 C:\ 나 POSIX 의 /)나 노드 프로세스가 실행되는 위치가 기준이 된다.
상대경로는 현재 파일이 기준이 된다. 현재 파일과 같은 경로면 점 하나(.) 를 현재 파일보다 한 단계 상위 경로먄 점 두개 (..) 를 사용해 표현한다.
/Users/ano/temp/directory 에서 /Users 로 가고 싶다면 절대경로에서는 그냥 /Users 를 입력하면 된다. 상대 경로에서는 ../../.. 를 해야 3 디렉토리 위로 올라가 /Users 가 된다.
Reference
https://p-iknow.netlify.app/node-js/path-moudle/
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.