English | 简体中文
path-nice
- The elegant and handy alternative to path
, fs
and glob
If sometimes you do not feel nice about the original path
or fs
of Node.js, then just
All existing code still works, while the path
evolves.
Original ver:
import path from 'path';
import fs from 'fs';
const app = await fs.promises.realpath('./app');
const publicDir = path.join(app, 'public');
await fs.promises.writeFile(
path.join(publicDir, 'manifest.json'),
JSON.stringify({ name: 'App' }),
);
nice ver:
import path from 'path-nice';
const app = await path('./app').realpath();
const publicDir = app.join('public');
await publicDir.join('manifest.json')
.writeJSON({ name: 'App' });
Especially when you need to import some predefined paths from other modules, path-nice
is doubly convenient: instead of importing additional path
and fs
modules, just import
the paths you need, type a dot, and all the methods you need are present.
Can bind other filesystem implementations, e.g. memory file system memfs
import path from 'path-nice';
import { fs as memfs } from 'memfs';
const mpath = path
.posix // Use POSIX-style paths (memfs only supports POSIX-style)
.bindFS(memfs); // bind file system
await mpath('/index.ts')
.writeFile('export default 42;');
(Coming soon in version 2.1.0)
npm install path-nice
or
yarn add path-nice
- Requires: Node.js >= v12.0.0
- Provided: CommonJS, ESModule and TypeScript typings
- ESModule version can be used directly in Node.
Please refer to API Reference.
Add a pair of ()
after path
to enter "nice" mode.
import path from 'path-nice'
const dir = path('./src')
dir
is the instance of class PathNice
:
dir instanceof path.PathNice // true
A PathNice
instance is a wrapper of the raw path string, so that the path can be easily
used to generate additional paths or manipulate files.:
dir.raw === './src' // true
Each PathNice
instance is an immutable object, all properties are read-only:
Object.isFrozen(dir) // true
let f = path('path-nice/src')
f = f.join('index.ts') // path('path-nice/src/index.ts')
// For the following 4 methods: 0 args = get, 1 arg = set
f.dirname() // path('path-nice/src')
f.dirname('another-dir') // path('another-dir/index.ts')
f.filename() // 'index.ts'
f.filename('types.ts') // path('path-nice/src/types.ts')
f.ext() // '.ts'
f.ext('.js') // path('path-nice/src/index.js')
f.separaotr() // '/'
f.separaotr('\\') // path('path-nice\\src\\index.ts')
// .parent is an alias for .dirname(), can get the path to the parent directory
f.parent.raw === f.dirname().raw // true
const f2 = f.parent.parent.join('package.json')
f2.raw // 'path-nice/package.json'
f2.isAbsolute() // false
f2.toAbsolute() // path('/work/path-nice/package.json'), suppose cwd is '/work'
// Use .realpath() to get the absolute path and resolve the
// soft links that may exist in the path at the same time.
await f2.realpath() // path('/project/path-nice/package.json')
// suppose cwd is '/work', and '/work' points to '/project'
f2.toRelative('path-nice/docs') // path('../package.json')
f2.prefixFilename('old.') // path('path-nice/old.package.json')
f2.postfixBeforeExt('.old') // path('path-nice/package.old.json')
f2.postfix('.old') // path('path-nice/package.json.old')
For more path-related methods, see docs of PathNice.
It can be noted that, many functions in the fs
module, such as readFile
and writeFile
,
almost always have path
as their first parameter. path-nice
rewrites them as member methods of class PathNice
, and makes it easier to call them by automatically filling this parameter with the current path.
Most of the following methods are asynchronous methods, returning a Promise
. Add the suffix Sync
to the function names to get their synchronous versions.
-
readFile
-
readFileToString
: Same asreadFile
, but guaranteed to return astring
. Default: UTF-8 -
readJSON
: read the file, then parse as json. Default: UTF-8 -
writeFile
-
writeJSON
: Serialize the json object, then write it to the file. Default: UTF-8, 4 spaces as indent -
outputFile
: Same aswriteFile
, automatically create the parent directory if it does not exist -
outputJSON
: Same aswriteJSON
, automatically create the parent directory if it does not exist -
updateFileAsString
Execute a function to quickly update a file.
e.g.
await path('README.md') .updateFileAsString(str => str.replace(/path/g, 'path-nice'))
-
updateJSON
Execute a function to quickly update a JSON file.
e.g.
await path('package.json') .updateJSON(json => { json.version = '1.0.0' })
-
appendFile
-
createReadStream
-
createWriteStream
-
open
Directories containing files can also be copied, moved, or deleted directly. Supports moving files across devices.
copy
move
remove
delete
: Alias ofremove
rename
emptyDir
: Empty the folder, and ensure it exists
Ensure the directory or file exists. If it doesn't, create it automatically.
emptyDir
: Empty the folder, and ensure it existsensureDir
ensureFile
isDir
isEmptyDir
isFile
isSymbolicLink
exists
ls
: ReturnsPromise<{ dirs: PathNiceArr, files: PathNiceArr }>
, directories and files already sorted out, all absolute paths, easier to usereaddir
watchWithChokidar
: use npm packagechokidar
to watch files, API is more friendly and powerfulwatch
watchFile
unwatchFile
fileSize
: Get the file size, including the size inB
,KB
,MB
,GB
, etc.fileMode
: Gets the file modefileOwner
: Get the file ownerchmod
chown
lchown
stat
lstat
When multiple arguments are passed to path()
, or an array, it returns a PathNiceArr
:
import path from 'path-nice';
let arr = path('./README.md', './package.json', './tsconfig.json');
class PathNiceArr
is a subclass of class Array
. The methods of Array
can be called in a normal way:
arr = arr.filter(f => f.ext() === '.json')
// PathNiceArr [
// PathNice { raw: './package.json' },
// PathNice { raw: './tsconfig.json' },
// ]
It also adds some additional methods to holistically manipulate files in the array:
await arr.copyToDir('. /json-config'); // each file in arr is copied to the json-config directory
If arr.base
is set, the files will maintain their directory structure relative to base
when copying or moving files. When not set, files are copied or moved one by one. For example:
/*
Assuming cwd = /work, and ./src contains the following files:
./src
├── lib/
│ ├── jquery.js
│ └── types.ts
└── index.ts
*/
const { dirs, files } = await path('./src').ls(/* recursive */ true);
console.log(files);
// PathNiceArr(3) [
// PathNice { raw: '/work/src/index.ts' },
// PathNice { raw: '/work/src/lib/jquery.js' },
// PathNice { raw: '/work/src/lib/types.ts' },
// base: PathNice { raw: '/work/src' }
// ]
await files.copyToDir('dist');
/*
The directory structure of dist at this point:
./dist
├── lib/
│ ├── jquery.js
│ └── types.ts
└── index.ts
*/
await path('dist').emptyDir(); // empty the dist directory
files.base = undefined; // clear base
await files.copyToDir('dist');
/*
The directory structure of dist at this point:
./dist
├── jquery.js
├── types.ts
└── index.ts
*/
For detailed usage of PathNiceArr
, see docs of PathNiceArr.