6.0.5 • Published 6 months ago

sync-directory v6.0.5

Weekly downloads
8,108
License
ISC
Repository
github
Last release
6 months ago

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 -g
syncdir <from> <to> [options]

Example: syncdir aaa bbb -w

options:

  • -w, --watch

    Watch changes. false as default.

    Same as config watch.

  • --quiet

    Disable unnecessary logs.

  • --exclude <strings...>

    Exclude some path. Such as syncdir a b --exclude node_modules package-lock.json.

    Same as config exclude

  • -si, --skipInitialSync

    Skip the first time sync actions when it's true. It's useful when you just want the srcFolder to be watched. false as default.

    Same as config skipInitialSync.

  • -nd, --nodeep

    Just walk the first level sub files/folders. Avoids deep scanning of big folders.

    Same as config nodeep.

  • -do, --deleteOrphaned

    Delete orphaned or excluded (when using API) files/folders in target folder. false as default.

    Same as config deleteOrphaned.

  • -hardlink, --hardlink

    Sync with type hardlink, copy as default.

    Same as config type: 'hardlink'.

  • -symlink, --symlink

    support symlink while sync running. false as 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

FunctionReturnsSyntaxBlock the thread?
syncDirectory()syncDirectory.sync()undefined or chokidar watcherSynchronousYes
syncDirectory.async()Promiseasync / 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

namedescriptiontypevaluesdefaultcan be async ?
srcDirsrc directoryStringabsolute or relative path--
targetDirtarget directoryStringabsolute or relative path--
config.cwdwhen srcDir or targetDir is a relative path, they will be formatted to absolute path by path.join(cwd, srcDir | targetDir)string-process.cwd()-
config.watchwatch file changesBoolean-false-
config.chokidarWatchOptionswatch options (chokidar is used for watching)Object-{}-
config.typeway to sync filesString'copy' \| 'hardlink''copy'-
config.skipInitialSyncskip the first time sync actions when it's true. It's useful when you just want the srcFolder to be watched.Booleantrue \| falsefalse-
config.deleteOrphaneddelete orphaned or excluded (API using) files/folders in target folder. false as default.Boolean-false-
config.afterEachSynccallback function when every file syncedFunction-blank functionYes when syncDirectory.async()
config.staySymlinkif src folder "A/" is a symlink, the target folder "A/" will also be the same symlink.Boolean-false-
config.stayHardlinkonly 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.excludePriority: forceSync > exclude. Filter which src files should not be synced.RegExp / String / Array (item is RegExp / String)-null-
config.forceSyncPriority: forceSync > exclude. Force sync some files even though they are excluded.RegExp / String / Array (item is RegExp / String)-(file) => { return false }No
config.nodeepJust walk the first level sub files/folders.Boolean-false-
config.onErrorcallback function when something wrongFunction-(err) => { throw new Error(err) }Yes when syncDirectory.async()

Some confusing params

image

Params Details

  • cwd

    Type: String

    Default: process.cwd()

    For: format srcDir | targetDir to absolute path when they are relative paths

    syncDirectory(srcDir, targetDir, {
        cwd: __dirname
    });
  • watch

    Type: true | false

    Default: false

    For: watch file changes.

    syncDirectory(srcDir, targetDir, {
        watch: true
    });
  • chokidarWatchOptions

    Type: Object

    Default: {}

    For: watch options (chokidar is used for watching).

    syncDirectory(srcDir, targetDir, {
        chokidarWatchOptions: {
            awaitWriteFinish: {
                stabilityThreshold: 2000,
                pollInterval: 100
            }
        },
    });
  • afterEachSync

    Type: Function

    Default: () => {}

    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 path
    • srcPath: absolute or relative src file/folder path
    • targetPath: absolute or relative target file/folder path
  • type

    Type: 'copy' | 'hardlink'

    Default: 'copy'

    For: way to sync files.

    • copy (default)

      syncDirectory(srcDir, targetDir);
    • hardlink

      syncDirectory(srcDir, targetDir, {
          type: 'hardlink'
      });
  • skipInitialSync

    Type: true | false

    Default: false

    For: enhance the performance

    It's for enhancing the sync performance when you just want srcDir to be watched.

    syncDirectory(srcDir, targetDir, {
        skipInitialSync: true,
        watch: true,
    })

    The srcDir won't be synced to targetDir when skipInitialSync: true and the srcDir's file changes will be watched and synced to targetDir.

  • stayHardlink

    Type: true | false

    Default: true

    Only 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".

  • nodeep

    Type: true | false

    Default: false

    Just walk the first level sub files/folders. Avoids deep scanning of big folders.

    The reason why deep was 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
    });
  • deleteOrphaned

    Type: true | false

    Default: false

    Delete orphaned or excluded (when using API) files/folders in target folder. false as default.

    For instance:

    srcDir:
    
    dir1/
        1.js
        2.js
    
    targetDir:
    
    dir2/
        1.js
        2.js
        3.js
    syncDirectory(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.
  • exclude

    Type: Function / RegExp / String / Array (item is RegExp / String)

    Priority: forceSync > exclude.

    Default: null

    For: 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']
      });
  • forceSync

    Type: Function / RegExp / String / Array (item is RegExp / String)

    Priority: forceSync > exclude.

    Default: null

    For: 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']
      });
  • staySymlink

    Type: true | false

    Default: false

    If 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,
    });
  • onError

    Type: Function

    Default: (err) => { throw new Error(err) }

    For: callback function when something wrong.

    syncDirectory(srcDir, targetDir, {
        onError(err) {
            console.log(err.message);
        },
    });

LICENSE

MIT

6.0.5

6 months ago

6.0.1

1 year ago

6.0.0

1 year ago

6.0.3

1 year ago

6.0.2

1 year ago

6.0.4

1 year ago

5.1.9

2 years ago

5.1.8

2 years ago

5.1.5

2 years ago

5.1.4

2 years ago

5.1.3

2 years ago

5.1.2

2 years ago

5.1.1

2 years ago

5.1.0

2 years ago

5.0.8

2 years ago

5.0.7

2 years ago

5.0.6

2 years ago

5.1.7

2 years ago

5.1.6

2 years ago

5.0.5

2 years ago

5.0.4

2 years ago

5.0.3

2 years ago

5.0.2

2 years ago

5.0.1

2 years ago

5.0.0

2 years ago

4.0.14

2 years ago

4.0.13

2 years ago

4.1.0

2 years ago

4.1.2

2 years ago

4.1.1

2 years ago

4.0.10

2 years ago

4.0.12

2 years ago

4.0.11

2 years ago

4.0.9

2 years ago

4.0.8

2 years ago

4.0.7

2 years ago

4.0.6

2 years ago

3.0.4

3 years ago

3.0.3

3 years ago

3.0.2

3 years ago

3.0.1

3 years ago

3.0.6

3 years ago

3.0.5

3 years ago

3.0.0

3 years ago

4.0.5

3 years ago

4.0.4

3 years ago

4.0.1

3 years ago

4.0.0

3 years ago

4.0.3

3 years ago

4.0.2

3 years ago

2.2.23

3 years ago

2.2.18

3 years ago

2.2.19

3 years ago

2.2.22

3 years ago

2.2.20

3 years ago

2.2.21

3 years ago

2.2.17

3 years ago

2.2.16

3 years ago

2.2.15

3 years ago

2.2.14

3 years ago

2.2.13

3 years ago

2.2.11

3 years ago

2.2.12

3 years ago

2.2.10

3 years ago

2.2.9

3 years ago

2.2.8

3 years ago

2.2.7

4 years ago

2.2.5

4 years ago

2.2.4

4 years ago

2.2.6

4 years ago

2.2.3

4 years ago

2.2.1

4 years ago

2.2.2

4 years ago

2.2.0

4 years ago

2.1.2

4 years ago

2.1.1

4 years ago

2.1.0

5 years ago

2.0.9

5 years ago

2.0.8

5 years ago

2.0.7

5 years ago

2.0.6

5 years ago

2.0.5

5 years ago

2.0.4

5 years ago

2.0.3

5 years ago

2.0.1

6 years ago

2.0.0

6 years ago

1.0.9

6 years ago

1.0.8

6 years ago

1.0.7

6 years ago

1.0.6

6 years ago

1.0.5

6 years ago

1.0.4

7 years ago

1.0.3

7 years ago

1.0.2

7 years ago

1.0.1

7 years ago

1.0.0

7 years ago