sync-directory v6.0.5
Description
sync-directory can sync files from src directory to target directory.
CLI and API are supported.
We have two ways to sync files: hardlink and copy.
If type is copy, sync-directory will copy files from src directory to target directory.
If type is hardlink, sync-directory can create hardlink files in target directory from src directory.
sync-directory uses copy by default for safety. (hardlink will be quicker but some watchers can't trigger change event for target files.)
Cli
npm i sync-directory -gsyncdir <from> <to> [options]Example: syncdir aaa bbb -w
options:
-w, --watchWatch changes.
falseas default.Same as config
watch.--quietDisable unnecessary logs.
--exclude <strings...>Exclude some path. Such as
syncdir a b --exclude node_modules package-lock.json.Same as config
exclude-si, --skipInitialSyncSkip the first time sync actions when it's
true. It's useful when you just want the srcFolder to be watched.falseas default.Same as config
skipInitialSync.-nd, --nodeepJust walk the first level sub files/folders. Avoids deep scanning of big folders.
Same as config
nodeep.-do, --deleteOrphanedDelete orphaned or
excluded(when using API) files/folders in target folder.falseas default.Same as config
deleteOrphaned.-hardlink, --hardlinkSync with type
hardlink,copyas default.Same as config
type: 'hardlink'.-symlink, --symlinksupport symlink while sync running.
falseas default.Same as config
staySymlink.
API (commonjs and esm are supported)
sync
commonjs
const syncDirectory = require('sync-directory');esm
import syncDirectory from 'sync-directory/index.mjs'
syncDirectory(srcDir, targetDir, {
afterEachSync({ eventType, nodeType, relativePath, srcPath, targetPath }) {
},
});async
commonjs
const { async } = require('sync-directory');esm
import { async } from 'sync-directory/index.mjs'
(async () => {
const delay = (time = 2000) => new Promise(r => setTimeout(r, time));
console.log('start'); // time a
// wait several 2s: 2 * file number
await async(srcDir, targetDir, {
async afterEachSync({ eventType, nodeType, relativePath, srcPath, targetPath }) {
await delay(2000); // delay 2s after one file/folder was synced
},
});
console.log('end'); // time a + 2 * (file number)
})()Pick Your API
commonjs
const syncDirectory = require('sync-directory');esm
import syncDirectory from 'sync-directory/index.mjs';
syncDirectory(srcDir, targetDir[, config]);Syntax
| Function | Returns | Syntax | Block the thread? |
|---|---|---|---|
syncDirectory()syncDirectory.sync() | undefined or chokidar watcher | Synchronous | Yes |
syncDirectory.async() | Promise | async / awaitPromise.then() | No |
Returns
const watcher = syncDirectory(A, B);watcher is undefined.
const watcher = syncDirectory(A, B, {
watch: true
});watcher is a chokidar watcher.
Params
Params Overview
| name | description | type | values | default | can be async ? |
|---|---|---|---|---|---|
srcDir | src directory | String | absolute or relative path | - | - |
targetDir | target directory | String | absolute or relative path | - | - |
config.cwd | when srcDir or targetDir is a relative path, they will be formatted to absolute path by path.join(cwd, srcDir | targetDir) | string | - | process.cwd() | - |
config.watch | watch file changes | Boolean | - | false | - |
config.chokidarWatchOptions | watch options (chokidar is used for watching) | Object | - | {} | - |
config.type | way to sync files | String | 'copy' \| 'hardlink' | 'copy' | - |
config.skipInitialSync | skip the first time sync actions when it's true. It's useful when you just want the srcFolder to be watched. | Boolean | true \| false | false | - |
config.deleteOrphaned | delete orphaned or excluded (API using) files/folders in target folder. false as default. | Boolean | - | false | - |
config.afterEachSync | callback function when every file synced | Function | - | blank function | Yes when syncDirectory.async() |
config.staySymlink | if src folder "A/" is a symlink, the target folder "A/" will also be the same symlink. | Boolean | - | false | - |
config.stayHardlink | only worked when type: 'hardlink'. When stayHardlink: true, if src file is "src/a.js", the target file "target/a.js" will be a hardlink of "src/a.js". | Boolean | - | true | - |
config.exclude | Priority: forceSync > exclude. Filter which src files should not be synced. | RegExp / String / Array (item is RegExp / String) | - | null | - |
config.forceSync | Priority: forceSync > exclude. Force sync some files even though they are excluded. | RegExp / String / Array (item is RegExp / String) | - | (file) => { return false } | No |
config.nodeep | Just walk the first level sub files/folders. | Boolean | - | false | - |
config.onError | callback function when something wrong | Function | - | (err) => { throw new Error(err) } | Yes when syncDirectory.async() |
Some confusing params

Params Details
cwdType:
StringDefault:
process.cwd()For: format
srcDir | targetDirto absolute path when they are relative pathssyncDirectory(srcDir, targetDir, { cwd: __dirname });watchType:
true | falseDefault:
falseFor: watch file changes.
syncDirectory(srcDir, targetDir, { watch: true });chokidarWatchOptionsType:
ObjectDefault:
{}For: watch options (chokidar is used for watching).
syncDirectory(srcDir, targetDir, { chokidarWatchOptions: { awaitWriteFinish: { stabilityThreshold: 2000, pollInterval: 100 } }, });afterEachSyncType:
FunctionDefault:
() => {}For: callback function when every file synced.
syncDirectory.sync(srcDir, targetDir, { afterEachSync({ eventType, nodeType, relativePath, srcPath, targetPath }) { } }); await syncDirectory.async(srcDir, targetDir, { async afterEachSync({ eventType, nodeType, relativePath, srcPath, targetPath }) { } });eventType:"init:hardlink"/"init:copy"/"add"/"change"/"unlink"/"unlinkDir"/"addDir"nodeType:"file"/"dir"relativePath: relative file/folder pathsrcPath: absolute or relative src file/folder pathtargetPath: absolute or relative target file/folder path
typeType:
'copy' | 'hardlink'Default:
'copy'For: way to sync files.
copy(default)syncDirectory(srcDir, targetDir);hardlinksyncDirectory(srcDir, targetDir, { type: 'hardlink' });
skipInitialSyncType:
true | falseDefault:
falseFor: enhance the performance
It's for enhancing the sync performance when you just want
srcDirto be watched.syncDirectory(srcDir, targetDir, { skipInitialSync: true, watch: true, })The
srcDirwon't be synced totargetDirwhenskipInitialSync: trueand thesrcDir's file changes will be watched and synced totargetDir.stayHardlinkType:
true | falseDefault:
trueOnly works when
type: 'hardlink'.When
stayHardlink: true, if src file is "src/a.js", the target file "target/a.js" will be a hardlink of "src/a.js".Then when "src/a.js" changed, "target/a.js" will remain a hardlink. Otherwise will be a copied file.
Some watchers will not be able to watch changes of "target/a.js".
nodeepType:
true | falseDefault:
falseJust walk the first level sub files/folders. Avoids deep scanning of big folders.
The reason why
deepwas not used is that cli options is--nodeep. Just keep this two the same.// srcFolder: // a/ a is symlink // 1.js // targetFolder: // a/ syncDirectory(srcDir, targetDir, { nodeep: true, // 1.js will be ignored });deleteOrphanedType:
true | falseDefault:
falseDelete orphaned or
excluded(when using API) files/folders in target folder.falseas default.For instance:
srcDir: dir1/ 1.js 2.js targetDir: dir2/ 1.js 2.js 3.jssyncDirectory(srcDir, targetDir, { deleteOrphaned: true, excluded: [ '2.js' ] }); // dir2/3.js will be removed because dir1/3.js does not exist. // dir2/2.js will be removed because dir1/2.js is excluded.excludeType: Function / RegExp / String / Array (item is RegExp / String)
Priority:
forceSync > exclude.Default:
nullFor: declare files that should not sync to target directory.
Function
syncDirectory(srcDir, targetDir, { exclude(filePath) { return /node_modules/.test(filePath); } });String
syncDirectory(srcDir, targetDir, { exclude: 'node_modules' });RegExp
syncDirectory(srcDir, targetDir, { exclude: /node\_modules/ });Array
syncDirectory(srcDir, targetDir, { exclude: [/node\_modules/] });syncDirectory(srcDir, targetDir, { exclude: ['node_modules'] });
forceSyncType: Function / RegExp / String / Array (item is RegExp / String)
Priority:
forceSync > exclude.Default:
nullFor: some files must be synced even though 'excluded'.
Function
syncDirectory(srcDir, targetDir, { exclude: ['node_modules'], forceSync(filePath) { return /node_modules\/jquery/.test(filePath); } });String
syncDirectory(srcDir, targetDir, { exclude: ['node_modules'], forceSync: 'node_modules/jquery' });RegExp
syncDirectory(srcDir, targetDir, { exclude: ['node_modules'], forceSync: /node_modules\/jquery/ });Array
syncDirectory(srcDir, targetDir, { exclude: ['node_modules'], forceSync: [/node_modules\/jquery/] });syncDirectory(srcDir, targetDir, { exclude: ['node_modules'], forceSync: ['node_modules/jquery'] });
staySymlinkType:
true | falseDefault:
falseIf src folder "A/" is a symlink, the target folder "A/" will also be the same symlink.
// srcFolder: // a/ a is symlink // 1.js // targetFolder: // a/ a is not symlink // 1.js syncDirectory(srcDir, targetDir, { staySymlink: false, });// srcFolder: // a/ a is symlink // 1.js // targetFolder: // a/ a is the same symlink // 1.js syncDirectory(srcDir, targetDir, { staySymlink: true, });onErrorType:
FunctionDefault:
(err) => { throw new Error(err) }For: callback function when something wrong.
syncDirectory(srcDir, targetDir, { onError(err) { console.log(err.message); }, });
LICENSE
MIT
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago