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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jdt-jinke-open/vite-plugin-legacy-lib

v1.0.0

Published

支持库模式的Legacy Jssdk打包输出插件,基于legacy插件改造

Readme

@jdt-jinke-open/vite-plugin-legacy-lib

一个专门为Vite库模式设计的Legacy插件,用于打包输出Jssdk。基于官方的@vitejs/plugin-legacy插件改造,专注于库代码的转换和polyfill处理。

特性

  • 库模式专用:支持vite库模式legacy打包
  • 智能Polyfill检测:自动检测和处理需要的polyfills
  • SystemJs模块格式:更安全的模块格式,使用System.import轻松完成模块加载
  • css隔离:自动隔离css样式,支持组件库前缀替换

安装

pnpm add @jdt-jinke-open/vite-plugin-legacy-lib -D

使用方法

配置vite.config.lib.ts,以下是一个最简化的配置参考:

import vitePluginLegacyLib from '@jdt-jinke-open/vite-plugin-legacy-lib'

export default defineConfig({
  root: __dirname,
  build: {
    lib: {
      // sdk入口
      entry: resolve(__dirname, 'src/sdk-a/index.ts'),
      // sdk文件名
      fileName: 'sdk-a',
    },
  },
  plugins: [
    Vue(),
    vitePluginLegacyLib(),
    // ...
  ],
})

运行时变量

可以从@jdt-jinke-open/vite-plugin-legacy-lib/runtime获得几个关键的运行时变量

import {
  isJSSDKEnv, // 用于判断当前是否Jssdk执行环境
  prefixClass, // css隔离类名,前面带`.`的
  prefixClassName, // css隔离类名,前面不带`.`的
  teleportRootId, // 自动创建的给全局弹框类组件挂载的teleport id,自动添加了css隔离类名
} from '@jdt-jinke-open/vite-plugin-legacy-lib/runtime'

Jssdk管理和调试

推荐使用如下结构管理多个jssdk

可选,在sdk入口js相同的位置,增加index-dev文件支持本地调试功能:

src/jssdk/
  |__some-sdk/
    |__index.ts         # Jssdk的输出入口
    |__index-dev.ts     # 调试Jssdk入口
    |__index-dev.html   # 调试Jssdk的页面入口
  |__other-sdk/
    |__index.ts         # Jssdk的输出入口
    |__index-dev.ts     # 调试Jssdk入口
    |__index-dev.html   # 调试Jssdk的页面入口

在启动服务前,使用插件提供的legacyLibSelect终端选择控件,此时可以移除build.lib配置了:

import { legacyLibSelect } from '@jdt-jinke-open/vite-plugin-legacy-lib'

export default defineConfig(async () => {
  // 终端交互选择启动的jssdk
  const selectInfo = await legacyLibSelect({
    manageDir: resolve(__dirname, 'src/jssdk'),
  })

  // selectInfo.config.theme // 配置的主题可以传给按需引入插件

  return {
    // ...
  }
})

调试页面大致如下

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/some-sdk/index-dev.ts"></script>
  </body>
</html>

存量项目改造

如果你是存量vite+legacy项目,2步配置:

  1. 复制vite.config.tsvite.config.lib.ts,替换legacy插件和增加lib配置即
export default defineConfig({
  // ...其他配置
  build: {
    lib: {
      // sdk入口
      entry: resolve(__dirname, 'src/some-sdk/index.ts'),
      // sdk文件名
      fileName: 'some-sdk',
    },
  },
  plugins: [
    Vue(),
    // legacy({
    //   // ...
    // }),
    // 将legacy 替换为 @jdt-jinke-open/vite-plugin-legacy-lib
    vitePluginLegacyLib(),
  ],
})
  1. 业务项目输出jssdk时,组件多是复用的,如下操作在vite.config.ts中添加运行时支持
export default defineConfig({
  // ...其他配置
  plugins: [
    Vue(),
    legacy({
      // ...
    }),
    // 关闭插件仅提供runtime支持,,这样全局依旧支持`import { prefixClass } from '@jdt-jinke-open/vite-plugin-legacy-lib/runtime'`
    vitePluginLegacyLib({
      enable: false,
    }),
  ],
})

宿主如何接入sdk

先安装必要依赖

pnpm i systemjs @types/systemjs

确保在应用入口(main.ts)引入systemjs模块

// 放到最顶部
import 'systemjs'

使用sdk

System.import('url').then((exports) => {
  /**
   * 假如sdk是这样导出的:
   *
   * export const a = 1
   * export const b = 2
   *
   * exports就是
   * {
   *   a: 1,
   *   b: 2,
   * }
   */
  console.log(exports)
})

组件库前缀替换

使用libPrefixReplace选项开启组件库前缀替换,所有组件名、组件类名等相关的前缀都会被替换为指定的前缀

import { getRandomNameHash } from '@jdt-jinke-open/vite-plugin-legacy-lib'
// 替换组件库前缀,注意resolver、unplugin等插件也需要一致
const customFinMPrefixName = getRandomNameHash()

export default defineConfig({
  plugins: [
    // ...
    vitePluginLegacyLib({
      cssIsolation: {
        libPrefixReplace: {
          // 全局替换FinD Mobile组件前缀
          jdtm: customFinMPrefixName,
        },
      },
    }),
  ]
})

全部配置

/**
 * Jssdk主要配置
 */
export interface LegacyLibOptions extends Pick<CssIsolationOption, 'enable'> {
  /**
   * 打包输出目录,默认输出到相对sdk入口的dist目录
   */
  outDir?: string
  /**
   * 目标浏览器
   * @default ['ie >= 11']
   */
  targets?: string | string[] | Record<string, string>
  /**
   * css隔离配置
   */
  cssIsolation?: Omit<CssIsolationOption, 'enable'>
  /**
   * default: true
   */
  polyfills?: boolean | string[]
  additionalLegacyPolyfills?: string[]
  /**
   * @see https://babeljs.io/docs/assumptions
   *
   * default: {}
   */
  assumptions?: Record<string, boolean>
}

/**
 * 针对Jssdk复用业务代码的场景,为业务代码运行时和类型支持
 */
export interface LegacyLibTypeOptions {
  enable: false
}

/**
 * 插件配置
 */
export type Options = LegacyLibOptions | LegacyLibTypeOptions

css隔离配置

export interface CssIsolationOption {
  /**
   * 是否启用插件功能,在业务`vite.config.ts`中注册这个插件并传`false`以支持任意地方获取css隔离前缀:\
   * ```js
   * `import { prefixClass } from '@jdt-jinke-open/vite-plugin-legacy-lib/runtime'`
   * ```
   * 关闭后,获取到的前缀为空字符串
   * @default true
   */
  enable?: boolean
  /**
   * 组件库前缀替换,完全隔离可能的组件库样式冲突,比如样式覆盖 \
   * 注意这里忽略大小写,所有组件名、组件类名等相关的前缀都会被替换 \
   * 规则是基于`jdtm`定义的,如有遗漏,可通过`values`选项先自定义,内置规则见`genLibPrefixReplaceConfig`
   * @example
   *
   * ```js
   * libPrefixReplace: {
   *   // 将组件库的`jdtm`前缀替换为`abc`
   *   jdtm: 'abc',
   *   // 将组件库的`fin`前缀替换为`cde`,并添加了自定义的替换规则
   *   fin: {
   *     prefix: 'cde',
   *     values: {
   *       'fin--': 'cde--'
   *     }
   *   }
   * }
   * ```
   */
  libPrefixReplace?: {
    [prefix: string]: string | {
      /**
       * 新前缀
       */
      prefix: string
      /**
       * 新增自定义的前缀替换规则
       */
      values?: Record<string, string>
    }
  }
  /**
   * 全局类名前缀,主要隔离对宿主环境样式的影响
   */
  prefix?: string | ((randomHash: string) => string)
  /**
   * 单类名场景,需要排除的类名,设置不影响默认值
   * - 传入string类型时,需完全匹配
   * - 传入正则类型时,注意影响范围,限制开头和结尾
   * @default
   * const defaultExclude: (string | RegExp)[] = [
   *   '.dark', // 业界常用的暗黑主题切换类名
   *   '.van-theme-dark', // vant基础库暗黑主题切换类名
   *   '.van-overflow-hidden', // vant基础库禁止页面滚动
   *   '.el-loading-parent--hidden', // element基础库loading
   *   '.el-popup-parent--hidden', // element基础库禁止页面滚动
   *   '.el-loading-parent--relative', // element基础库loading
   * ]
   */
  exclude?: (string | RegExp)[]
  /**
   * 多类名场景,在匹配的开头类名之后插入前缀,设置不影响默认值
   * @default
   * const defaultInsertAfter = [
   *    ...defaultExclude, // 默认排除的类名
   *    'html',
   *    'body',
   * ]
   * @example
   * // before
   * `.dark .some-class`
   * // after
   * `.dark .prefixClass .some-class`
   *
   * // before
   * `body .some-class`
   * // after
   * `body .prefixClass .some-class`
   */
  insertAfter?: (string | RegExp)[]
  /**
   * 添加自定义逻辑,返回类名则覆盖默认逻辑,否则继续执行默认逻辑
   */
  transform?: (prefix: string, selector: string, prefixedSelector: string, filePath: string, rule: import('postcss').Rule) => string | void
  /**
   * 忽略的文件
   */
  ignoreFiles?: (string | RegExp)[]
  /**
   * 手动指定包含的文件
   */
  includeFiles?: (string | RegExp)[]
}