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

tradeship

v0.0.13

Published

Automatically imports missing JS dependencies and removes unused ones.

Downloads

18

Readme

tradeship

Linux Build Windows Build NPM Version

tradeship statically analyzes your JavaScript code for identifiers that aren't defined and finds the appropriate dependencies to import. It also removes imports that aren't used. tradeship is meant to be used as an editor plugin that manages your imports.

tradeship

Features

  • Imports dependencies from node.js standard libraries, npm packages listed in package.json, and other files within your project directory.
  • Infers properties that are exported by dependencies and imports them using destructuring syntax (e.g. const { Component } = require("react");).
  • Knows aliases for dependencies (e.g. $ for jQuery, _ for lodash/underscore, test for ava, etc.) by analyzing more than 100 GB of public JS code on GitHub.
  • Automatically identifies the style of your code and makes the imports match (e.g. single vs. double quotes, semicolons vs. no semicolons, var vs. let vs. const, etc.)
  • Statically analyzes files within your project directory to determine their exports for use in other files.
  • Supports both CommonJS and ES6 modules. Can output require() or import syntax.
  • Supports JSX identifiers and ensures React is in scope when using JSX.

Installation

Install tradeship using npm or yarn. It's recommended to either install tradeship globally or make the local installation available on your path (e.g. by adding export PATH=node_modules/.bin:$PATH to your shell configuration), since editor plugins make use of the tradeship executable.

$ npm install -g tradeship
# or use yarn:
$ yarn global add tradeship

Then, install the editor plugin of your choice:

Each editor plugin has instructions on how to run tradeship on the current file being edited. You can also configure each plugin to run tradeship on save. See the respective links above for more information.

The first time tradeship runs in a project directory with many JavaScript files, it'll take some time to parse and cache dependencies. Future runs will be much faster. If you'd like to use tradeship in a large project, it's recommended to run it once on the command-line, as shown below, so you can see the progress as it populates the cache:

tradeship [path]

Replace [path] with any path to a JavaScript file in your project directory. Note that this won't modify the file in any way; it'll just print the new code to stdout. See the Command Line Interface section for details.

Configuration

tradeship doesn't need any configuration to work out of the box. By design, almost nothing is configurable, as tradeship automatically infers style from your code. There is, however, one configuration option that you may want to tweak: environments.

To correctly find identifiers that aren't defined, tradeship needs to know what global variables are available. It does this through environments, where each environment defines a set of global variables that come with it. tradeship piggybacks on eslint's configuration system to avoid introducing another configuration file and format.

In eslint, you specify the environments you want in your configuration file, generally at the root of your project directory. tradeship searches for an eslint configuration file (either .eslintrc.js, .eslintrc.yaml, .eslintrc.yml, .eslintrc.json, .eslintrc, or an eslintConfig object in package.json) within the code's directory or successive parent directories.

When it finds one, it looks at the env object to determine the active environments. An example configuration object is:

{
  "env": {
    "browser": true,
    "es6": true
  }
}

Each key is an environment name, and the corresponding value is whether that environment is active. See eslint's guide to specifying environments for more details about the available environments.

If there's no configuration file, tradeship assumes the environments browser, node, and es6, bringing in globals from the browser (e.g. window and document), from node.js (e.g. process and __dirname), and from ES6 (e.g. Set and Map).

Note that tradeship makes all the node.js standard libraries available for import if and only if the node environment is active.

Command Line Interface (CLI)

Using an editor plugin (see section above) is the easiest way to get started with tradeship, but you can also use the command line interface (which all editor plugins use internally).

tradeship [options] [path]

Reads the code given at [path]. Outputs new code to stdout, adding missing dependencies and removing unused ones. The [options] are as follows:

  • -s or --stdin: Read contents from stdin as opposed to [path]. [path] is still required so that tradeship can resolve relative imports and find available npm packages, but it need not exist as a file; you can even just provide a directory.

  • -w or --write: Write output back to [path] (be careful!).

  • -h or --help: Print help.

  • -v or --version: Print version.

The full help text is below:

Usage: tradeship [options] [path]
Automatically imports missing JS dependencies and removes unused ones.

Options:
-s, --stdin    read contents from stdin
-w, --write    write output to source file (careful!)
-h, --help     print help
-v, --version  print version

Arguments:
[path]  Relative imports and available npm packages will be determined
        from this path. If not --stdin, input code will be read from this
        path. If --write, new code will be written to this path.

Node.js Interface

tradeship exposes a simple node.js API if you'd like to use it programmatically:

const tradeship = require("tradeship");
tradeship.import(dir, code).then(newCode => {
  // do something with newCode
});

dir is the directory used to resolve relative imports and find available npm packages (generally the directory where the code comes from). code is the actual JavaScript code. tradeship.import() returns a promise that, when resolved, gives the resulting new code.

How it works

tradeship analyzes dependencies from three sources: node.js standard libraries, package.json dependencies, and other files within your project directory.

For each dependency it finds, tradeship:

  • Determines potential import names:

    An import name is a variable name you might see in code that refers to the dependency. For instance, the import name fs would refer to the fs node.js standard library. The import name React would refer to the react npm package.

    For node.js standard libraries and package.json packages, if the library/package name is itself a valid JavaScript identifier, it and its capitalized version are potential import names (e.g. react and React for the react npm package). If the library/package name has non-word characters or underscores, it is split on [\W_]+ and the parts are joined, both in camel and class case, to get two more import names (childProcess and ChildProcess for the child_process node.js standard library).

    There are various package.json packages that are imported under common aliases known by the community (e.g. $ for jQuery, _ for lodash/underscore, test for ava, etc.). By analyzing more than 100 GB of public JS code on GitHub, tradeship knows many such aliases, and will import the associated package.

    For project files, the code is statically analyzed to find an import name. For instance, if you write module.exports = SomeExport;, SomeExport will be an import name. This is one simple case; there are many others that tradeship parses, including those with ES6 export syntax. In addition to the analyzed import name, tradeship also uses the file path's base name as an import name, using the same logic as defined for node.js standard library names above.

  • Determines properties:

    These are JavaScript object properties that are exported by the dependency. For instance, readFile is a property of the fs node.js standard library. Component is a property of the react npm package. The import name of properties is equivalent to the property name.

    For node.js standard libraries and package.json packages, the library is loaded within a separate node.js process, and properties are extracted using Object.keys().

    For project files, the code is statically analyzed to find properties. For instance, if you write exports.someProperty = ...;, someProperty will be a parsed property. This is one simple case; there are many others that tradeship parses, including those with ES6 export syntax.

Then, tradeship analyzes your code for identifiers that aren't defined. Each identifier is a potential import name, and tradeship searches for the corresponding dependency or property. If it finds a match, it adds the appropriate import to the code. If multiple dependencies or properties match a given import name, tradeship prioritizes them as follows:

  1. Project file dependency (highest priority)
  2. Project file property
  3. package.json dependency
  4. package.json property
  5. Node.js standard library dependency
  6. Node.js standard library property (lowest priority)

tradeship groups all node.js and package.json dependencies together, sorted lexicographically. It then adds a blank line and all project file dependencies, also sorted lexicographically.

tradeship finds all imports that aren't used and removes them.

License

MIT

ship vector icon by Vecteezy