Skip to content

NaverPayDev/pite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@naverpay/pite

lang: En | Ko

A Vite bundler configuration package that supports library builds with minimal setup.

Why pite?

vite has become a versatile build tool supporting various frameworks beyond Vue.js, including React. It also provides a Library Mode for bundling libraries, making it a strong alternative to Rollup. With its fast build speed and optimized bundling environment, it is gaining popularity as a package bundler.

However, without prior knowledge of core concepts and configuration methods for library builds, setting up an efficient configuration file can be challenging. To effectively utilize Vite’s Library Mode, multiple factors must be considered.

tsup is an esbuild-based bundler that simplifies bundling TypeScript libraries. It is useful for basic bundling tasks. However, it does not provide automatic polyfill insertion or transpilation based on browserslist, meaning additional tools or configurations may be required for an optimized build in specific environments. Additionally, since it is based on esbuild, it lacks compatibility with Rollup plugins, limiting access to Rollup’s extensive plugin ecosystem.

To address these limitations, pite provides a more intuitive and flexible library build environment. While maintaining the strengths of both vite and tsup, pite offers presets that enable seamless configuration for various environments, allowing stable library builds without complex setup.

Features

Supports Dual Package Builds

  • Supports both ESM and CJS formats, with the option to generate ESM-only builds.
  • Allows specifying subpaths using glob patterns.
  • Enables defining separate output paths for different module systems.

browserslist-based Transpilation

  • Utilizes browserslist-to-esbuild to read .browserslistrc and convert it into an esbuild-compatible target format. This allows automatic optimization based on the .browserslistrc in the consuming project without manually configuring build targets.
  • Performs transpilation based on browserslist, ensuring the output matches the specified browser environment.
  • If no configuration is provided, it defaults to @naverpay/browserslist-config.

📦 @naverpay/browserslist-config

A Shareable Browserslist Config package that reflects Naver Pay’s supported browser range.

Automatic Polyfill Detection & Optimization Based on browserslist

  • If a .browserslistrc file is present, pite automatically detects whether polyfills are required and provides guidance.
  • When polyfills are needed, it injects them using the runtime method to prevent redundant code and optimize package size.
  • Supports core-js-pure (3.39.0) to apply polyfills safely without polluting the global environment.

Best Practices for Library Builds

  • Analyzes the entry path of the library and provides recommendations for an optimal directory structure.
  • Supports preserveModules and preserveDirectives by default:
    • preserveModules: Maintains the original source directory structure when bundling. This allows direct imports of individual modules and enhances tree shaking.
    • preserveDirectives: Preserves directives like 'use client' in the bundling process to ensure expected behavior in specific runtime environments.
  • Automatically excludes external dependencies (dependencies, peerDependencies) in package.json to prevent unnecessary code from being bundled.
    If a package installed in devDependencies is executed within the project, it will not be treated as an external dependency and will be included in the bundle. If a package needs to be included in the bundle, it is appropriate to specify it in dependencies or peerDependencies. Please list only packages that are used exclusively in the development environment under devDependencies.
  • While best practices are provided by default, pite offers flexible build options that can be adjusted to meet project-specific requirements.

Build Validation with publint

  • Runs verifyPackageJSON from @naverpay/publint before the build process to check if critical package.json fields for publishing (e.g., main, files) are correctly defined.
  • Executes the publint API after the build to verify that package.json fields like main and exports are correctly set and that no required files are missing.

📦 publint

publint is an npm package linter that ensures optimal compatibility with Vite, Rollup, and other environments.

📦 @naverpay/publint

A package inspired by publint, designed to enforce best practices specific to Naver Pay’s internal standards.

Setting Up a TypeScript Build Environment Using the Custom vite-tsup-plugin

  • This is a Vite plugin built using the tsup API.
  • Allows projects to set up a build environment without requiring additional tsup configurations.
  • Generates .d.ts declaration files for both ESM and CJS builds, ensuring consistent type information across different environments.
  • Provides a plugin for executing tsup commands to ensure stable type declaration file generation, addressing vite-plugin-dts module resolution issues.
  • Unlike standalone tsup, which does not support Rollup plugins, using pite allows access to the full Rollup plugin ecosystem.
  • This plugin is not published and is intended for internal project use only.

Install

Run the following command to install as a devDependencies:

npm install --save-dev @naverpay/pite

Or, if using pnpm:

pnpm add -D @naverpay/pite

Requirements

node: >=18
vite: >=6.0.10
tsup: >=8.3.5

How to use

1️⃣ Create a Vite Configuration File

Import createViteConfig in vite.config.ts and set up the configuration.

import { createViteConfig } from '@naverpay/pite'

export default createViteConfig({
    cwd: process.cwd(),
    entry: ['src/index.ts'],
    outputs: [
        { format: 'es', dist: 'dist/es' },
        { format: 'cjs', dist: 'dist/cjs' },
    ],
    cssFileName: 'style.css',
    visualize: true,
    publint: {severity: 'error'},
    includeRequiredPolyfill: ['fetch', 'Promise'],
    skipRequiredPolyfillCheck: ['Symbol'],
    options: {
        minify: true,
        sourcemap: true,
    },
})

2️⃣ Build the Library

Run the following command to bundle the library:

vite build

Once the build is complete, the bundled files will be generated in the dist/es and dist/cjs directories.

Options

Option Name Type Description
*entry string | string[] | Record<string, string> Entry file path (supports glob patterns)
cwd string Current working directory (default: '.')
outputs { format: 'es' | 'cjs'; dist: string }[] Specifies module format and output directory
cssFileName string Output CSS file name
visualize boolean | PluginVisualizerOptions Enables rollup-plugin-visualizer
publint { severity?: 'error' | 'warn' | 'off' } Specifies severity for publint checks
(error: exit with code 1, warn: show warnings only, off: disable check)
includeRequiredPolyfill string[] List of required polyfills to be injected
skipRequiredPolyfillCheck string[] List of polyfills to skip injection check
options BuildOptions Additional Vite build options

includeRequiredPolyfill vs skipRequiredPolyfillCheck

By default, pite detects code that requires polyfills based on the project's browserslist and raises an error if necessary. This ensures that the library functions correctly across different environments while preventing unnecessary polyfill injections that may increase build size.

The includeRequiredPolyfill and skipRequiredPolyfillCheck options allow you to adjust the polyfill injection criteria and processing behavior. These options provide flexibility in applying polyfills based on project requirements.

  • includeRequiredPolyfill allows explicit inclusion of polyfills deemed necessary for the library’s functionality. By specifying the required polyfills, they will be automatically included to ensure proper execution. These polyfills are applied at runtime and are not bundled directly within the library. Therefore, [email protected] must be installed as a dependency.
  • skipRequiredPolyfillCheck prevents errors from being raised even if certain polyfills are detected as necessary. This option is useful when the library does not require specific polyfills, despite automated detection indicating otherwise.
    core-js not only detects missing features in target environments, but it also inserts polyfills for proposal-stage features, features with reported bugs in specific browser versions, newly introduced extensions to existing features, and cases where JavaScript’s dynamic nature makes it difficult to accurately determine the presence of prototype methods.
    This behavior may lead to unnecessary polyfills being added, which can differ from a developer’s intent to simply complement browser support. To prevent this, you can use the skipRequiredPolyfillCheck option to exclude certain polyfills. By carefully controlling this option, you can optimize the overall package size.
    However, if a feature genuinely falls outside the supported browser range and requires a polyfill, issues may arise, so use this option with caution.
    (See example packages that use the skipRequiredPolyfillCheck option.)

Example Packages

Check out the configurations and build outputs of example libraries built using pite.

import { createViteConfig } from '@naverpay/pite'

export default createViteConfig({
    cwd: '.',
    entry: ['!./src/**/*.bench.ts', '!./src/**/*.test.ts', './src/**/*.ts'],
    outputs: [
        {
            format: 'cjs',
            dist: 'dist',
        },
        {
            format: 'es',
            dist: 'dist',
        },
    ],
    skipRequiredPolyfillCheck: [
        // https://bugs.chromium.org/p/v8/issues/detail?id=12681
        'es.array.push',
        // https://bugzilla.mozilla.org/show_bug.cgi?id=1767541
        'es.array.includes',
        // https://issues.chromium.org/issues/40672866
        'es.array.reduce',
        // https://github.com/zloirock/core-js/issues/480#issuecomment-457494016 safari bug
        'es.string.trim', 
        // https://github.com/zloirock/core-js/commit/9017066b4cb367c6609e4473d43d6e6dad8031a5#diff-59f90be4cf68f9d13d2dce1818780ae968bf48328da4014b47138adf527ec0fcR1066
        'es.regexp.flags', 
        // https://bugs.webkit.org/show_bug.cgi?id=188794
        'es.array.reverse', 
    ],
})
import { createViteConfig } from '@naverpay/pite'

export default createViteConfig({
    cwd: '.',
    entry: ['./src/index.ts'],
    skipRequiredPolyfillCheck: [
        'esnext.json.parse'
    ],
    options: {
        minify: false,
    },
})

License

MIT License © 2025 NaverPay