Home

Paths

This is a follow-up to a brief intro to the file-system.

join: for combinig paths strings

Lets consider a simple directory structure with a few js files to see what the __filename and __dirname globally available vars do:

  • a test dir containing
    • an index.js file
    • a directory called nested, which contains
      • an index.js file
- test (dir)
    - index.js (file)
    - nested (dir)
      - index.js (files)

Here's what the js files will contain:

test/index.js

require('./nested');
const { join } = require('path');

console.log('test index file')

console.log({
  filename: __filename,
  dirname: __dirname,
  joinBackward: join(__dirname, '..'),
  joinFileName: join(__dirname, 'file.txt'),
});

test/nested/index.js:

console.log('nested index file');
const { join } = require('path');

console.log({
  filename: __filename,
  dirname: __dirname,
  joinBackward: join(__dirname, '..'),
  joinFileName: join(__dirname, 'file.txt'),
})

running the above will output:

nested index file
{
  filename: '/Users/<my-username>/Desktop/test/nested/index.js',
  dirname: '/Users/<my-username>/Desktop/test/nested',
  joinBackward: '/Users/<my-username>/Desktop/test',
  joinFileName: '/Users/<my-username>/Desktop/test/nested/file.txt'
}
test index file
{
  filename: '/Users/<my-username>/Desktop/test/index.js',
  dirname: '/Users/<my-username>/Desktop/test',
  joinBackward: '/Users/<my-username>/Desktop',
  joinFileName: '/Users/<my-username>/Desktop/test/file.txt'
}

resolve: for calculating a path from segments

Similar to the join method, the resolve method can be used to get a single path from multiple path segments.
To see how 2 path strings can be "resolved", consider a directory+file combo at /Users/<you>/Desktop/test/index.js that includes code like the following: (note this is a continuation of the example above)

const { join, resolve } = require('path');

console.log('test index file')

console.log({
  filename: __filename,
  dirname: __dirname,
  joinBackward: join(__dirname, '..'),
  joinFileName: join(__dirname, 'file.txt'),
  resolveEmpty: resolve(),
  resolvedRelativePaths: resolve('./first', 'second'),
  resolvedRootPaths: resolve('/first', '/second'),
  resolvedMixed: resolve('/first', 'second'),
  resolvedDoubleDots: resolve('../', 'second'),
});

That will return:

test index file
{
  filename: '/Users/my-user/Desktop/test/index.js',
  dirname: '/Users/my-user/Desktop/test',
  joinBackward: '/Users/my-user/Desktop',
  joinFileName: '/Users/my-user/Desktop/test/file.txt',
  resolveEmpty: '/Users/my-user/Desktop/test',
  resolvedRelativePaths: '/Users/my-user/Desktop/test/first/second',
  resolvedRootPaths: '/second',
  resolvedMixed: '/first/second',
  resolvedDoubleDots: '/Users/my-user/Desktop/second'
}

normalize: for cleaning up funky syntax

building on the previous examples of a file at /Users/<your-username/Desktop/test/index.js, this includes 3 normalize examples:

require('./nested');
const { join, resolve, normalize } = require('path');

console.log('test index file')

console.log({
  filename: __filename,
  dirname: __dirname,
  joinBackward: join(__dirname, '..'),
  joinFileName: join(__dirname, 'file.txt'),
  resolveEmpty: resolve(),
  resolvedRelativePaths: resolve('./first', 'second'),
  resolvedRootPaths: resolve('/first', '/second'),
  resolvedMixed: resolve('/first', 'second'),
  resolvedDoubleDots: resolve('../', 'second'),
  normalizeEmpty: normalize(''),
  normalizeMessy: normalize('/this//looks///bad'),
  normalizeWithRelatives: normalize('root/first/second/third/..'),
});

which returns

test index file
{
  filename: '/Users/my-user/Desktop/test/index.js',
  dirname: '/Users/my-user/Desktop/test',
  joinBackward: '/Users/my-user/Desktop',
  joinFileName: '/Users/my-user/Desktop/test/file.txt',
  resolveEmpty: '/Users/my-user/Desktop/test',
  resolvedRelativePaths: '/Users/my-user/Desktop/test/first/second',
  resolvedRootPaths: '/second',
  resolvedMixed: '/first/second',
  resolvedDoubleDots: '/Users/my-user/Desktop/second',
  normalizeEmpty: '.',
  normalizeMessy: '/this/looks/bad',
  normalizeWithRelatives: 'root/first/second'
}

parse: breaking down a path into parts

a modified version of the previous examples, here including the parse method on __filename. parse converts a path string into an object with keys of root, dir, base, ext, and name:

const { join, resolve, normalize, parse } = require('path');

console.log('test index file')

console.log({
  filename: __filename,
  dirname: __dirname,
  join: {
    backward: join(__dirname, '..'),
    fileName: join(__dirname, 'file.txt'),
  },
  resolve: {
    empty: resolve(),
    relativePaths: resolve('./first', 'second'),
    rootPaths: resolve('/first', '/second'),
    mixed: resolve('/first', 'second'),
    doubleDots: resolve('../', 'second'),
  },
  normalize: {
    empty: normalize(''),
    messy: normalize('/this//looks///bad'),
    withRelatives: normalize('root/first/second/third/..'),
  },
  parse: parse(__filename)
});

returning

test index file
{
  filename: '/Users/my-user/Desktop/test/index.js',
  dirname: '/Users/my-user/Desktop/test',
  join: {
    backward: '/Users/my-user/Desktop',
    fileName: '/Users/my-user/Desktop/test/file.txt'
  },
  resolve: {
    empty: '/Users/my-user/Desktop/test',
    relativePaths: '/Users/my-user/Desktop/test/first/second',
    rootPaths: '/second',
    mixed: '/first/second',
    doubleDots: '/Users/my-user/Desktop/second'
  },
  normalize: {
    empty: '.',
    messy: '/this/looks/bad',
    withRelatives: 'root/first/second'
  },
  parse: {
    root: '/',
    dir: '/Users/my-user/Desktop/test',
    base: 'index.js',
    ext: '.js',
    name: 'index'
  }
}

Check out the node docs for more deets on the path module!

Tags: