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

rolli

v0.7.1

Published

A zero-config module bundler.

Downloads

15

Readme

Features

  • Smart automatic bundler
  • Built-in ESM & TS support
  • Allows advanced customization
  • Provides a powerful hooking system
  • Exports fully optimized code
  • Auto-handles node hashbangs
  • Prints useful bundle stats
  • Follows modern practice
  • Super easy to use

Intro

Rolli allows you to easily bundle your projects with zero-config setup by extending the latest Rollup features and powerful plugins.

It automatically detects your options and infers build entries, so all you need is a basic npm package setup.

Also, it's possible to fully customize all aspects of the build setup as needed.

Quick Start

  1. Update your package.json to follow modern npm rules:
{
  "type": "module",
  // Build entries
  "exports": {
    ".": {
      "types": "./dist/types/index.d.ts", // matches the input './src/types/index.ts'
      "import": "./dist/index.mjs", // matches the input './src/index.{js,ts}'
      "require": "./dist/index.cjs", // matches the input './src/index.{js,ts}'
    },
    "./path": {
      "types": "./dist/types/path/index.d.ts", // matches the input './src/types/path/index.ts'
      "import": "./dist/path/index.mjs", // matches the input './src/path/index.{js,ts}'
      "require": "./dist/path/index.cjs", // matches the input './src/path/index.{js,ts}'
    },
    // ...
  },
  // Node hashbangs (optional)
  "bin": {
    "command": "./dist/cli/index.mjs", // matches the input './src/cli/index.{js,ts}'
    // ...
  }
}

[!NOTE]
Output paths from the ./dist dir automatically match input paths from the ./src dir.

  1. When you're ready to build, simply run the command:
npx rolli

That's it!

Customization

Rolli has integrated auto-build setup modes that already covers most cases, but if needed, it can be fully customized to match specific requirements.

Config

By default, Rolli automatically detects custom configuration via the rolli.config.js file or the rolli object inside package.json.

The rolli.config.js file is located at the project's root and can override or extend the bundler's behavior.

// rolli.config.js

import { defineConfig } from 'rolli'

export default defineConfig({
  // ...
})

Config path

Also, it is possible to set a custom config path via the cli command:

npx rolli --config my.config.js

Custom Setup

Sometimes it is necessary to manually set the build entries or include extra files that can't be specified via the auto-build exports or bin modes.

Rolli provides an additional custom-build entries mode that allows you to tweak the settings for each object individually.

This is very powerful and flexible mode since it can be used in combination with the auto-build modes, but also as a fully manual setup.

// rolli.config.js

import { defineConfig } from 'rolli'

export default defineConfig({
  entries: [
    {
      input: './src/index.ts',
      output: './dist/index.mjs',
    },
    {
      input: './src/types/index.ts',
      output: './dist/types.d.ts',
      externals: ['id-1', 'id-2', /regexp/],
    },
    {
      input: './src/cli/index.js',
      output: './dist/cli.cjs',
      format: 'cjs',
      replace: {
        preventAssignment: true,
        __name__: 'custom-name',
        __version__: '1.0.0',
      },
    },
    {
      input: './src/utils/index.ts',
      output: './dist/utils/index.mjs',
      json: true,
      resolve: true,
    },
    // ...
  ],
})

Options

All options are optional, so you only have to specify what you’d like to change.

Also, you can see the current Rolli configuration in the terminal by simply running the CLI command:

npx rolli --print-config

exports

  • Type: object | false
  • Default: enabled

Specifies the auto-build exports mode (node subpath exports).

This is enabled by default so any additional customization is optional.

When enabled, it automatically parses and bundles all entries that are defined via the exports object in the package.json file.

All defined output paths automatically match input .js or .ts paths. The input directory is specified by the srcDir option.

// rolli.config.js

export default defineConfig({
  exports: {
    // all options are optional
    srcDir: 'src',
    externals: ['id-1', 'id-2', /regexp/],
    minify: false,
    tsconfig: 'tsconfig.custom.json',
    // ...
  },
})

matcher

  • Path Syntax: ./[srcDir]/[filename].[js,ts]

The matcher basically parses all output paths and replaces filename with the user's custom value.

export default defineConfig({
  exports: {
    matcher: {
      types: 'dts', // renames all 'types' inputs to 'dts.ts'
      import: 'esm', // renames all 'import' inputs to 'esm.{js,ts}'
      require: 'cjs', // renames all 'require' inputs to 'cjs.{js,ts}'
    },
  },
})

So now all input paths, including recursive ones, will be accordingly matched.

// package.json
{
  "exports": {
    ".": {
      "types": "./dist/types/index.d.ts", // matches the input './src/types/dts.ts'
      "import": "./dist/index.mjs", // matches the input './src/esm.{js,ts}'
      "require": "./dist/index.cjs", // matches the input './src/cjs.{js,ts}'
    },
    "./path": {
      "types": "./dist/types/path/index.d.ts", // matches the input './src/types/path/dts.ts'
      "import": "./dist/path/index.mjs", // matches the input './src/path/esm.{js,ts}'
      "require": "./dist/path/index.cjs", // matches the input './src/path/cjs.{js,ts}'
    },
    // ...
  },
}

plugins

Default plugin system is quite powerful, but if needed, it can be easily extended via the plugins option.

The plugins option accepts an array of plugins.

export default defineConfig({
  exports: {
    plugins: [
      plugin1(),
      plugin2(),
      // ...
    ],
  },
})

Or it can be an object that explicitly defines when user plugins will run, before or after the default ones.

export default defineConfig({
  exports: {
    plugins: {
      start: [plugin1()], // runs 'before' the default plugins
      end: [plugin2()], // runs 'after' the default plugins
    },
  },
})

exclude

It is possible to exclude certain paths from the auto-build mode.

The exclude option accepts an array of strings, which are essentially paths, or an array of objects that can individually control path's types, import or require options.

export default defineConfig({
  exports: {
    exclude: [
      '.', // excludes the entire path
      './path', // excludes the entire path
      { path: './path-2', types: true }, // excludes types only
      { path: './path-3', import: true, require: true }, // excludes esm and cjs
      { path: './path-4', require: true }, // excludes cjs only
      // ...
    ],
  },
})

To disable the mode completely, set it to false.

export default defineConfig({
  exports: false,
})

bin

  • Type: object | false
  • Default: enabled

Specifies the auto-build bin mode (executable files).

This is enabled by default so any additional customization is optional.

When enabled, it automatically parses and bundles all entries that are defined via the bin object in the package.json file.

All defined output paths automatically match input .js or .ts paths. The input directory is specified by the srcDir option.

Each compiled bin file will have a #!/usr/bin/env node inserted at the very beginning.

// rolli.config.js

export default defineConfig({
  bin: {
    // all options are optional
    srcDir: 'src',
    externals: ['id-1', 'id-2', /regexp/],
    minify: false,
    tsconfig: 'tsconfig.custom.json',
    // ...
  },
})

matcher

  • Path Syntax: ./[srcDir]/[filename].[js,ts]

The matcher basically parses all output paths and replaces filename with the user's custom value.

export default defineConfig({
  bin: {
    matcher: 'cli', // renames all inputs to 'cli.{js,ts}'
  },
})

So now all input paths, including recursive ones, will be accordingly matched.

// package.json
{
  "bin": {
    "command": "./dist/cli/index.mjs", // matches the input './src/cli/cli.{js,ts}'
    "command2": "./dist/cli/dir/index.cjs", // matches the input './src/cli/dir/cli.{js,ts}'
    // ...
  }
}

plugins

Default plugin system is quite powerful, but if needed, it can be easily extended via the plugins option.

The plugins option accepts an array of plugins.

export default defineConfig({
  bin: {
    plugins: [
      plugin1(),
      plugin2(),
      // ...
    ],
  },
})

Or it can be an object that explicitly defines when user plugins will run, before or after the default ones.

export default defineConfig({
  bin: {
    plugins: {
      start: [plugin1()], // runs 'before' the default plugins
      end: [plugin2()], // runs 'after' the default plugins
    },
  },
})

exclude

It is possible to exclude certain paths from the auto-build mode.

The exclude option accepts an array of strings, which are essentially command names.

export default defineConfig({
  bin: {
    exclude: [
      'command', // excludes the path by command name
      // ...
    ],
  },
})

To disable the mode completely, set it to false.

export default defineConfig({
  bin: false,
})

entries

  • Type: object[]
  • Default: undefined

Specifies the custom-build entries mode.

It allows you to manually set all build entries and adjust options for each object individually.

Defined entries can be used with auto-build modes or separately, depending on preference. In each object, only input and output are required, all other options are optional.

// rolli.config.js

export default defineConfig({
  entries: [
    {
      // only 'input' and 'output' are required
      input: './src/index.ts',
      output: './dist/index.mjs',
      // ...
    },
    // ...
  ],
})

To use fully custom-build mode, disable auto-build modes and specify the entries as needed:

export default defineConfig({
  // auto-build modes will be ignored
  exports: false,
  bin: false,
  // only custom entries will be compiled
  entries: [
    // ...
  ],
})

plugins

Default plugin system is quite powerful, but if needed, it can be easily extended via the plugins option.

The plugins option accepts an array of plugins.

export default defineConfig({
  entries: [
    {
      input: './src/index.ts',
      output: './dist/index.mjs',
      plugins: [
        plugin1(),
        plugin2(),
        // ...
      ],
    },
  ],
})

Or it can be an object that explicitly defines when user plugins will run, before or after the default ones.

export default defineConfig({
  entries: [
    {
      input: './src/index.ts',
      output: './dist/index.mjs',
      plugins: {
        start: [plugin1()], // runs 'before' the default plugins
        end: [plugin2()], // runs 'after' the default plugins
      },
    },
  ],
})

hooks

  • Type: object
  • Default: undefined

Provides a powerful hooking system to further expand build modes.

List of available hooks:

  • rolli:start
  • rolli:build:start
  • rolli:build:end
  • rolli:end
// rolli.config.js

export default defineConfig({
  hooks: {
    'rolli:start': () => {
      // ...
    },
    'rolli:end': async () => {
      // ...
    },
  },
})

minify

  • Type: boolean
  • Default: undefined

Minifies all bundle assets for production.

// rolli.config.js

export default defineConfig({
  minify: true,
})

It can also be specified via the CLI command:

npx rolli --minify

tsconfig

  • Type: string
  • Default: undefined

Sets a custom TypeScript configuration for the entire bundle.

If not defined, it uses the main tsconfig.json file from the project's root.

// rolli.config.js

export default defineConfig({
  tsconfig: 'tsconfig.custom.json',
})

It can also be specified via the CLI command:

npx rolli --tsconfig tsconfig.custom.json

CLI

Check all available CLI commands:

npx rolli --help

Community

Feel free to use the official discussions for any additional questions.

License

Developed in 🇭🇷 Croatia

Released under the MIT license.

© Ivo Dolenc