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

unimport

v3.14.5

Published

Unified utils for auto importing APIs in modules

Downloads

4,497,724

Readme

unimport

npm version npm downloads Codecov

Unified utils for auto importing APIs in modules, used in nuxt and unplugin-auto-import

Features

  • Auto import register APIs for Vite, Webpack or esbuild powered by unplugin
  • TypeScript declaration file generation
  • Auto import for custom APIs defined under specific directories
  • Auto import for Vue template

Install

# npm
npm install unimport

# yarn
yarn add unimport

# pnpm
pnpm install unimport

Usage

Plugin Usage

Powered by unplugin, unimport provides a plugin interface for bundlers.

Vite / Rollup

// vite.config.js / rollup.config.js
import Unimport from 'unimport/unplugin'

export default {
  plugins: [
    Unimport.vite({ /* plugin options */ })
  ]
}

Webpack

// webpack.config.js
import Unimport from 'unimport/unplugin'

module.exports = {
  plugins: [
    Unimport.webpack({ /* plugin options */ })
  ]
}

Programmatic Usage

// ESM
import { createUnimport } from 'unimport'

// CommonJS
const { createUnimport } = require('unimport')
const { injectImports } = createUnimport({
  imports: [{ name: 'fooBar', from: 'test-id' }]
})

// { code: "import { fooBar } from 'test-id';console.log(fooBar())" }
console.log(injectImports('console.log(fooBar())'))

Configurations

Imports Item

Named import
imports: [
  { name: 'ref', from: 'vue' },
  { name: 'useState', as: 'useSignal', from: 'react' },
]

Will be injected as:

import { useState as useSignal } from 'react'
import { ref } from 'vue'
Default import
imports: [
  { name: 'default', as: '_', from: 'lodash' }
]

Will be injected as:

import _ from 'lodash'
Namespace import
imports: [
  { name: '*', as: '_', from: 'lodash' }
]

Will be injected as:

import * as _ from 'lodash'
Export assignment import

This is a special case for libraries authored with TypeScript's export = syntax. You don't need it the most of the time.

imports: [
  { name: '=', as: 'browser', from: 'webextension-polyfill' }
]

Will be injected as:

import browser from 'webextension-polyfill'

And the type declaration will be added as:

const browser: typeof import('webextension-polyfill')
Custom Presets

Presets are provided as a shorthand for declaring imports from the same package:

presets: [
  {
    from: 'vue',
    imports: [
      'ref',
      'reactive',
      // ...
    ]
  }
]

Will be equivalent as:

imports: [
  { name: 'ref', from: 'vue' },
  { name: 'reactive', from: 'vue' },
  // ...
]
Built-in Presets

unimport also provides some builtin presets for common libraries:

presets: [
  'vue',
  'pinia',
  'vue-i18n',
  // ...
]

You can check out src/presets for all the options available or refer to the type declaration.

Exports Auto Scan

Since unimport v0.7.0, we also support auto scanning the examples from a local installed package, for example:

presets: [
  {
    package: 'h3',
    ignore: ['isStream', /^[A-Z]/, /^[a-z]*$/, r => r.length > 8]
  }
]

This will be expanded into:

imports: [
  {
    from: 'h3',
    name: 'appendHeader',
  },
  {
    from: 'h3',
    name: 'appendHeaders',
  },
  {
    from: 'h3',
    name: 'appendResponseHeader',
  },
  // ...
]

The ignore option is used to filter out the exports, it can be a string, regex or a function that returns a boolean.

By default, the result is strongly cached by the version of the package. You can disable this by setting cache: false.

Type Declarations

Unimport.vite({
  dts: true // or a path to generated file
})

Directory Auto Import

Unimport.vite({
  dirs: [
    './composables/*',
  ]
})

Scan for modules under ./composables and auto-import the named exports.

Nested Directories

Unimport.vite({
  dirs: [
    './composables/**/*',
    {
      glob: './composables/nested/**/*',
      types: false // disable scan the type declarations
    }
  ]
})

Named exports for modules under ./composables/**/* will be registered for auto imports, and filter out the types in ./composables/nested/**/*.

Directory Scan Options

You can also provide custom options for directory scan, for example:

Unimport.vite({
  dirsScanOptions: {
    filePatterns: ['*.ts'], // optional, default `['*.{ts,js,mjs,cjs,mts,cts}']`, glob patterns for matching files
    fileFilter: file => file.endsWith('.ts'), // optional, default `() => true`, filter files
    types: true, // optional, default `true`, enable/disable scan the type declarations
    cwd: process.cwd(), // optional, default `process.cwd()`, custom cwd for directory scan
  },
  dirs: [
    './composables/**/*',
    {
      glob: './composables/nested/**/*',
      types: false
    }
  ]
})

Opt-out Auto Import

You can opt-out auto-import for specific modules by adding a comment:

// @unimport-disable

It can be customized by setting commentsDisable:

Unimport.vite({
  commentsDisable: [
    '@unimport-disable',
    '@custom-imports-disable',
  ]
})

Acorn Parser

By default, unimport uses RegExp to detect unimport entries. In some cases, RegExp might not be able to detect all the entries (false positive & false negative).

We introduced a new AST-based parser powered by acorn, providing a more accurate result. The limitation is when using Acorn, it assumes all input code are valid and vanilla JavaScript code.

Unimport.vite({
  parser: 'acorn'
})

Vue Template Auto Import

In Vue's template, the usage of API is in a different context than plain modules. Thus some custom transformations are required. To enable it, set addons.vueTemplate to true:

Unimport.vite({
  addons: {
    vueTemplate: true
  }
})

Caveats

When auto-import a ref, inline operations won't be auto-unwrapped.

export const counter = ref(0)
<template>
  <!-- this is ok -->
  <div>{{ counter }}</div>

  <!-- counter here is a ref, this won't work, volar will throw -->
  <div>{{ counter + 1 }}</div>

  <!-- use this instead -->
  <div>{{ counter.value + 1 }}</div>
</template>

We recommend using Volar for type checking, which will help you to identify the misusage.

Vue Directives Auto Import and TypeScript Declaration Generation

In Vue's template, the usage of directives is in a different context than plain modules. Thus some custom transformations are required. To enable it, set addons.vueDirectives to true:

Unimport.vite({
  addons: {
    vueDirectives: true
  }
})

Library Authors

When including directives in your presets, you should:

  • provide the corresponding imports with meta.vueDirective set to true, otherwise, unimport will not be able to detect your directives.
  • use named exports for your directives, or use default export and use as in the Import.
  • set dtsDisabled to true if you provide a type declaration for your directives.
import type { InlinePreset } from 'unimport'
import { defineUnimportPreset } from 'unimport'

export const composables = defineUnimportPreset({
  from: 'my-unimport-library/composables',
  /* imports and other options */
})

export const directives = defineUnimportPreset({
  from: 'my-unimport-library/directives',
  // disable dts generation globally
  dtsEnabled: false,
  // you can declare the vue directive globally
  meta: {
    vueDirective: true
  },
  imports: [{
    name: 'ClickOutside',
    // disable dts generation per import
    dtsEnabled: false,
    // you can declare the vue directive per import
    meta: {
      vueDirective: true
    }
  }, {
    name: 'default',
    // you should declare `as` for default exports
    as: 'Focus'
  }]
})

Using Directory Scan and Local Directives

If you add a directory scan for your local directives in the project, you need to:

  • provide isDirective in the vueDirectives: unimport will use it to detect them (will never be called for imports with meta.vueDirective set to true).
  • use always named exports for your directives.
Unimport.vite({
  dirs: ['./directives/**'],
  addons: {
    vueDirectives: {
      isDirective: (normalizedImportFrom, _importEntry) => {
        return normalizedImportFrom.includes('/directives/')
      }
    }
  }
})

💻 Development

  • Clone this repository
  • Enable Corepack using corepack enable (use npm i -g corepack for Node.js < 16.10)
  • Install dependencies using pnpm install
  • Run interactive tests using pnpm dev

License

Made with 💛

Published under MIT License.