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

node-norman

v2.0.42

Published

A tool to develop multi-package Node.js apps with ease.

Downloads

83

Readme

What is it?

A tool to develop multi-package Node.js apps with ease.

Why not use npm link instead?

  1. npm link is global. Anything global is bad (although there are exceptions).
  2. In many cases, you cannot have node_modules directory inside a linked package, because the package does not know it was linked somewhere. When the linked package requires another package, it looks for it in its own node_modules, not in node_modules of the package it was linked to. Most of the time it works, but some packages (especially ones using singleton instances) are not happy to be imported that way.
  3. The layout of the application on development machine differs from the layout of your application in production.
  4. Circular linked dependencies is still a pain for many tools.

How to start?

  1. Install: npm i -g node-norman
  2. Create .norman.json config file and list modules you want to develop (see below for format).
  3. Run norman fetch in the directory where .norman.json is located (or give a path to the config with norman --config ~/project/.norman.json fetch).
  4. Norman is going to initialize local modules by cloning source code from repositories, optionally running npm install and build commands.

Now you are able to synchronize local modules. Imagine you develop three packages: app, a and b, where app depends on a and b. Before starting app you need to have actual versions of a and b in app/node_modules. Without norman you could create symlinks in app/node_modules pointing to a and b source directories. But with norman you should synchronize app module before running. Synchronizing app guarantees you have actual versions of all packages listed in norman config in node_modules of app. The layout of app/node_modules after sync matches the one you get by running npm install on production and fetching all dependencies by npm.

To sync a module, run norman sync app, where the last argument is either name of the module as specified in the config, or a path to the module source directory.

You can use a watcher and synchronize a module on-the-fly by adding --watch: norman sync --watch app.

Note that norman does not rebuild local modules in watch mode, it only synchronizes changed files.

But you can rebuild dependent modules on regular sync with --build-deps flag.

To sync all local modules at once, use norman sync-all.

.norman.json file

modulesDirectory (string, required): modules listed in modules are going to be cloned here by default.

defaultBranch (string): default git branch to use when cloning modules if branch is not specified in module config. Default is master.

defaultIgnoreOrg (boolean): if false, module @myorg/repo is going to be cloned (if modulesDirectory is /home/user/my-project) to /home/user/myproject/myorg/repo. If true, sources are going to be cloned to /home/user/my-project/repo. Default is false.

includeModules (string or string[]): path (can be relative to the location of the current config file) to another config file. Modules from included configs are loaded too (taking into account modulesDirectory and other module-affecting options from included config).

defaultNpmIgnore (string or boolean): by default, any files except those in .git, .idea and node_modules directories are synchronized into app's node_modules. If this option is true, norman looks for .npmignore file in each module and only synchronizes files not ignored by this file. If false, no attempt to use .npmignore is done. If it is a string, it specifies path to custom file with ignore rules. Default is true.

defaultNpmInstall (boolean): if true, run npm install in all modules by default. Default is true.

defaultBuildTriggers (string[]): list of glob patterns (parsed by minimatch module). When norman is called with --build-deps flag, a module is going to be rebuilt only on changes in files matching these patterns.

modules: list of modules to clone from git repositories. Each item should be an object, properties of these objects are documented below under module.* keys.

module.name (string): name of the package in npm registry. If not specified, the name is deducted from git url in module.repository. If git url is not specified, an error is raised.

module.repository (string): url to a repository to clone module from. If destination directory already exists, cloning is skipped.

module.path (string): overrides path to the cloned repository for the module (deducted by default from modulesDirectory). Path can be relative to the location of the current config file.

module.ignoreOrg (boolean): overrides value of defaultIgnoreOrg for the module.

module.defaultBranch (string): overrides value of defaultBranch for the module.

module.npmIgnore (string): overrides value of defaultNpmIgnore value for the module.

module.npmInstall (boolean): overrides value of npmInstall for the module.

module.buildCommands (string[]): commands to build the module after cloning it from the repository. Each command should be either a npm script or a shell command. Norman first checks if a npm script with the given name exists in package.json of the local module and if any, runs it. If the script is not found, it tries to run it as a shell command. Ignored if npmInstall for the module is false.

module.buildTriggers' (string[]): overrides value of defaultBuildTriggers` for the module.

Source map support

Norman automatically modifies JS source maps to reference original source locations.

Keeping dependencies up to date

Norman can help you keep dependencies in your project updated. To find outdated dependencies of all modules listed in config, run norman outdated. Run norman outdated --upgrade to upgrade all dependencies to newer versions that still match specified semver ranges. Run norman outdated -upgrade --hard to upgrade all dependencies to latest available versions (overwrites semver ranges in package.json and can easily break things).

By default outdated command does not analyze modules included by includeModules. To include all modules, use --with-included flag.

Example config

{
  "modulesDirectory": "/home/user/development/myproject",
  "defaultBranch": "alpha",
  "defaultIgnoreOrg": true,
  "defaultBuildTriggers": [ "*.ts", "tsconfig.json", "package.json", "webpack.config.js" ],
  "modules": [
    {
      "repository": "[email protected]:zenwarr/norman.git",
      "branch": "alpha"
    }
  ]
}

Troubleshooting

Norman uses local NPM registry server internally that dynamically builds and packs local modules. This server acts as a proxy to original npm registries and caches fetched tarballs. If you have any problems with these cached tarballs, run norman clean cache.

Norman also stores snapshots of local module state in ~/.norman-state directory to determine whether it should repack or rebuild requested local module. You can clean stored state by running norman clean state.

To clean everything including temp files with packed versions of local modules, run norman clean all.