npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sync-directory

v6.0.5

Published

sync two directories by copying or creating hardlink

Downloads

40,115

Readme

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

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

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