snapshot of https://github.com/ueberdosis/tiptap.git (main, 2026-09-15; blobs > 131072B omitted)
Some checks failed
Verify / Install node dependencies (push) Failing after 2s
Verify / Build packages (push) Has been skipped
Verify / Check linting & formatting (push) Has been skipped
Verify / Run unit tests (push) Has been skipped
Verify / Run e2e tests (shard 1/4) (push) Has been skipped
Verify / Run e2e tests (shard 2/4) (push) Has been skipped
Verify / Run e2e tests (shard 3/4) (push) Has been skipped
Verify / Run e2e tests (shard 4/4) (push) Has been skipped
Publish / Resolve publish config (push) Failing after 2s
Publish / Send notification to Slack (push) Has been skipped
Publish / Send failure notification to Slack (push) Failing after 8s
Verify / Merge e2e reports (push) Has been skipped
Publish / Build (push) Has been skipped
Publish / Bump Versions OR Release to Registry (push) Has been skipped
Some checks failed
Verify / Install node dependencies (push) Failing after 2s
Verify / Build packages (push) Has been skipped
Verify / Check linting & formatting (push) Has been skipped
Verify / Run unit tests (push) Has been skipped
Verify / Run e2e tests (shard 1/4) (push) Has been skipped
Verify / Run e2e tests (shard 2/4) (push) Has been skipped
Verify / Run e2e tests (shard 3/4) (push) Has been skipped
Verify / Run e2e tests (shard 4/4) (push) Has been skipped
Publish / Resolve publish config (push) Failing after 2s
Publish / Send notification to Slack (push) Has been skipped
Publish / Send failure notification to Slack (push) Failing after 8s
Verify / Merge e2e reports (push) Has been skipped
Publish / Build (push) Has been skipped
Publish / Bump Versions OR Release to Registry (push) Has been skipped
This commit is contained in:
2420
packages/extension-mention/CHANGELOG.md
Normal file
2420
packages/extension-mention/CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
18
packages/extension-mention/README.md
Normal file
18
packages/extension-mention/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# @tiptap/extension-mention
|
||||
|
||||
[](https://www.npmjs.com/package/@tiptap/extension-mention)
|
||||
[](https://npmcharts.com/compare/tiptap?minimal=true)
|
||||
[](https://www.npmjs.com/package/@tiptap/extension-mention)
|
||||
[](https://github.com/sponsors/ueberdosis)
|
||||
|
||||
## Introduction
|
||||
|
||||
Tiptap is a headless wrapper around [ProseMirror](https://ProseMirror.net) – a toolkit for building rich text WYSIWYG editors, which is already in use at many well-known companies such as _New York Times_, _The Guardian_ or _Atlassian_.
|
||||
|
||||
## Official Documentation
|
||||
|
||||
Documentation can be found on the [Tiptap website](https://tiptap.dev).
|
||||
|
||||
## License
|
||||
|
||||
Tiptap is open sourced software licensed under the [MIT license](https://github.com/ueberdosis/tiptap/blob/main/LICENSE.md).
|
||||
54
packages/extension-mention/package.json
Normal file
54
packages/extension-mention/package.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "@tiptap/extension-mention",
|
||||
"version": "3.30.3",
|
||||
"description": "mention extension for tiptap",
|
||||
"keywords": [
|
||||
"tiptap",
|
||||
"tiptap extension"
|
||||
],
|
||||
"homepage": "https://tiptap.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/ueberdosis/tiptap/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ueberdosis/tiptap",
|
||||
"directory": "packages/extension-mention"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"dist"
|
||||
],
|
||||
"type": "module",
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": {
|
||||
"import": "./dist/index.d.ts",
|
||||
"require": "./dist/index.d.cts"
|
||||
},
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.cjs"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "vp pack"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tiptap/core": "workspace:^",
|
||||
"@tiptap/pm": "workspace:^",
|
||||
"@tiptap/suggestion": "workspace:^"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "workspace:*",
|
||||
"@tiptap/pm": "workspace:*",
|
||||
"@tiptap/suggestion": "workspace:*"
|
||||
}
|
||||
}
|
||||
5
packages/extension-mention/src/index.ts
Normal file
5
packages/extension-mention/src/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { Mention } from './mention.js'
|
||||
|
||||
export * from './mention.js'
|
||||
|
||||
export default Mention
|
||||
48
packages/extension-mention/src/mention.test.ts
Normal file
48
packages/extension-mention/src/mention.test.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Mention } from './mention.js'
|
||||
import { describe, expect, it } from 'vite-plus/test'
|
||||
|
||||
describe('mention Markdown', () => {
|
||||
it('parses mapped attributes', () => {
|
||||
const tokenizer = Mention.config.markdownTokenizer
|
||||
expect(tokenizer).toBeDefined()
|
||||
|
||||
const token = tokenizer?.tokenize('[@ id="feature" char="#"]', [], null as any)
|
||||
|
||||
expect(token).toMatchObject({
|
||||
attributes: {
|
||||
id: 'feature',
|
||||
mentionSuggestionChar: '#',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('parses malformed attributes in linear time', () => {
|
||||
const tokenizer = Mention.config.markdownTokenizer
|
||||
expect(tokenizer).toBeDefined()
|
||||
|
||||
const measure = (attributes: string) => {
|
||||
const startedAt = performance.now()
|
||||
tokenizer?.tokenize(`[@ ${attributes}]`, [], null as any)
|
||||
return performance.now() - startedAt
|
||||
}
|
||||
|
||||
measure('warmup="true"')
|
||||
const sizes = [12_288, 24_576]
|
||||
sizes.forEach(size => {
|
||||
const attack = '0'.repeat(size)
|
||||
const control = '-'.repeat(attack.length)
|
||||
const controlDuration = measure(control)
|
||||
const attackDuration = measure(attack)
|
||||
|
||||
expect(attackDuration).toBeLessThan(controlDuration * 20 + 100)
|
||||
})
|
||||
})
|
||||
|
||||
it('only parses attributes at attribute boundaries', () => {
|
||||
const tokenizer = Mention.config.markdownTokenizer
|
||||
|
||||
const token = tokenizer?.tokenize('[@ id="feature" prefix:char="#"]', [], null as any)
|
||||
|
||||
expect(token).toMatchObject({ attributes: { id: 'feature' } })
|
||||
})
|
||||
})
|
||||
367
packages/extension-mention/src/mention.ts
Normal file
367
packages/extension-mention/src/mention.ts
Normal file
@@ -0,0 +1,367 @@
|
||||
import type { Editor } from '@tiptap/core'
|
||||
import { createInlineMarkdownSpec, mergeAttributes, Node } from '@tiptap/core'
|
||||
import type { DOMOutputSpec } from '@tiptap/pm/model'
|
||||
import { Node as PMNode } from '@tiptap/pm/model'
|
||||
import type { SuggestionOptions } from '@tiptap/suggestion'
|
||||
import { Suggestion } from '@tiptap/suggestion'
|
||||
|
||||
import { getSuggestionOptions } from './utils/get-default-suggestion-attributes.js'
|
||||
|
||||
// See `addAttributes` below
|
||||
export interface MentionNodeAttrs {
|
||||
/**
|
||||
* The identifier for the selected item that was mentioned, stored as a `data-id`
|
||||
* attribute.
|
||||
*/
|
||||
id: string | null
|
||||
/**
|
||||
* The label to be rendered by the editor as the displayed text for this mentioned
|
||||
* item, if provided. Stored as a `data-label` attribute. See `renderLabel`.
|
||||
*/
|
||||
label?: string | null
|
||||
/**
|
||||
* The character that triggers the suggestion, stored as
|
||||
* `data-mention-suggestion-char` attribute.
|
||||
*/
|
||||
mentionSuggestionChar?: string
|
||||
}
|
||||
|
||||
export interface MentionOptions<
|
||||
SuggestionItem = any,
|
||||
Attrs extends Record<string, any> = MentionNodeAttrs,
|
||||
> {
|
||||
/**
|
||||
* The HTML attributes for a mention node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>
|
||||
|
||||
/**
|
||||
* A function to render the label of a mention.
|
||||
* @deprecated use renderText and renderHTML instead
|
||||
* @param props The render props
|
||||
* @returns The label
|
||||
* @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`
|
||||
*/
|
||||
renderLabel?: (props: {
|
||||
options: MentionOptions<SuggestionItem, Attrs>
|
||||
node: PMNode
|
||||
suggestion: SuggestionOptions | null
|
||||
}) => string
|
||||
|
||||
/**
|
||||
* A function to render the text of a mention.
|
||||
* @param props The render props
|
||||
* @returns The text
|
||||
* @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`
|
||||
*/
|
||||
renderText: (props: {
|
||||
options: MentionOptions<SuggestionItem, Attrs>
|
||||
node: PMNode
|
||||
suggestion: SuggestionOptions | null
|
||||
}) => string
|
||||
|
||||
/**
|
||||
* A function to render the HTML of a mention.
|
||||
* @param props The render props
|
||||
* @returns The HTML as a ProseMirror DOM Output Spec
|
||||
* @example ({ options, node }) => ['span', { 'data-type': 'mention' }, `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`]
|
||||
*/
|
||||
renderHTML: (props: {
|
||||
options: MentionOptions<SuggestionItem, Attrs>
|
||||
node: PMNode
|
||||
suggestion: SuggestionOptions | null
|
||||
}) => DOMOutputSpec
|
||||
|
||||
/**
|
||||
* Whether to delete the trigger character with backspace.
|
||||
* @default false
|
||||
*/
|
||||
deleteTriggerWithBackspace: boolean
|
||||
|
||||
/**
|
||||
* The suggestion options, when you want to support multiple triggers.
|
||||
*
|
||||
* With this parameter, you can define multiple types of mention. For example, you can use the `@` character
|
||||
* to mention users and the `#` character to mention tags.
|
||||
*
|
||||
* @default [{ char: '@', pluginKey: MentionPluginKey }]
|
||||
* @example [{ char: '@', pluginKey: MentionPluginKey }, { char: '#', pluginKey: new PluginKey('hashtag') }]
|
||||
*/
|
||||
suggestions: Array<Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>>
|
||||
|
||||
/**
|
||||
* The suggestion options, when you want to support only one trigger. To support multiple triggers, use the
|
||||
* `suggestions` parameter instead.
|
||||
*
|
||||
* @default {}
|
||||
* @example { char: '@', pluginKey: MentionPluginKey, command: ({ editor, range, props }) => { ... } }
|
||||
*/
|
||||
suggestion: Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>
|
||||
}
|
||||
|
||||
interface GetSuggestionsOptions {
|
||||
editor?: Editor
|
||||
options: MentionOptions
|
||||
name: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the suggestions for the mention extension.
|
||||
*
|
||||
* @param options The extension options
|
||||
* @returns the suggestions
|
||||
*/
|
||||
function getSuggestions(options: GetSuggestionsOptions) {
|
||||
return (
|
||||
options.options.suggestions.length ? options.options.suggestions : [options.options.suggestion]
|
||||
).map(suggestion =>
|
||||
getSuggestionOptions({
|
||||
// @ts-ignore `editor` can be `undefined` when converting the document to HTML with the HTML utility
|
||||
editor: options.editor,
|
||||
overrideSuggestionOptions: suggestion,
|
||||
extensionName: options.name,
|
||||
char: suggestion.char,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the suggestion options of the mention that has a given character trigger. If not
|
||||
* found, it returns the first suggestion.
|
||||
*
|
||||
* @param options The extension options
|
||||
* @param char The character that triggers the mention
|
||||
* @returns The suggestion options
|
||||
*/
|
||||
function getSuggestionFromChar(options: GetSuggestionsOptions, char: string) {
|
||||
const suggestions = getSuggestions(options)
|
||||
|
||||
const suggestion = suggestions.find(s => s.char === char)
|
||||
if (suggestion) {
|
||||
return suggestion
|
||||
}
|
||||
|
||||
if (suggestions.length) {
|
||||
return suggestions[0]
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* This extension allows you to insert mentions into the editor.
|
||||
* @see https://www.tiptap.dev/api/extensions/mention
|
||||
*/
|
||||
export const Mention = Node.create<MentionOptions>({
|
||||
name: 'mention',
|
||||
|
||||
priority: 101,
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
HTMLAttributes: {},
|
||||
renderText({ node, suggestion }) {
|
||||
return `${suggestion?.char ?? '@'}${node.attrs.label ?? node.attrs.id}`
|
||||
},
|
||||
deleteTriggerWithBackspace: false,
|
||||
renderHTML({ options, node, suggestion }) {
|
||||
return [
|
||||
'span',
|
||||
mergeAttributes(this.HTMLAttributes, options.HTMLAttributes),
|
||||
`${suggestion?.char ?? '@'}${node.attrs.label ?? node.attrs.id}`,
|
||||
]
|
||||
},
|
||||
suggestions: [],
|
||||
suggestion: {},
|
||||
}
|
||||
},
|
||||
|
||||
group: 'inline',
|
||||
|
||||
inline: true,
|
||||
|
||||
selectable: false,
|
||||
|
||||
atom: true,
|
||||
|
||||
addAttributes() {
|
||||
return {
|
||||
id: {
|
||||
default: null,
|
||||
parseHTML: element => element.getAttribute('data-id'),
|
||||
renderHTML: attributes => {
|
||||
if (!attributes.id) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return {
|
||||
'data-id': attributes.id,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
label: {
|
||||
default: null,
|
||||
parseHTML: element => element.getAttribute('data-label'),
|
||||
renderHTML: attributes => {
|
||||
if (!attributes.label) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return {
|
||||
'data-label': attributes.label,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
// When there are multiple types of mentions, this attribute helps distinguish them
|
||||
mentionSuggestionChar: {
|
||||
default: '@',
|
||||
parseHTML: element => element.getAttribute('data-mention-suggestion-char'),
|
||||
renderHTML: attributes => {
|
||||
return {
|
||||
'data-mention-suggestion-char': attributes.mentionSuggestionChar,
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: `span[data-type="${this.name}"]`,
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
renderHTML({ node, HTMLAttributes }) {
|
||||
const suggestion = getSuggestionFromChar(this, node.attrs.mentionSuggestionChar)
|
||||
|
||||
if (this.options.renderLabel !== undefined) {
|
||||
console.warn('renderLabel is deprecated use renderText and renderHTML instead')
|
||||
return [
|
||||
'span',
|
||||
mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
||||
this.options.renderLabel({
|
||||
options: this.options,
|
||||
node,
|
||||
suggestion,
|
||||
}),
|
||||
]
|
||||
}
|
||||
const mergedOptions = { ...this.options }
|
||||
|
||||
mergedOptions.HTMLAttributes = mergeAttributes(
|
||||
{ 'data-type': this.name },
|
||||
this.options.HTMLAttributes,
|
||||
HTMLAttributes,
|
||||
)
|
||||
|
||||
const html = this.options.renderHTML({
|
||||
options: mergedOptions,
|
||||
node,
|
||||
suggestion,
|
||||
})
|
||||
|
||||
if (typeof html === 'string') {
|
||||
return [
|
||||
'span',
|
||||
mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
||||
html,
|
||||
]
|
||||
}
|
||||
return html
|
||||
},
|
||||
|
||||
...createInlineMarkdownSpec({
|
||||
nodeName: 'mention',
|
||||
name: '@',
|
||||
selfClosing: true,
|
||||
allowedAttributes: ['id', 'label', { name: 'mentionSuggestionChar', skipIfDefault: '@' }],
|
||||
parseAttributes: (attrString: string) => {
|
||||
const attrs: Record<string, any> = {}
|
||||
const regex = /(?:^|\s)(\w+)=(?:"([^"]*)"|'([^']*)')/g
|
||||
let match = regex.exec(attrString)
|
||||
|
||||
while (match !== null) {
|
||||
const [, key, doubleQuoted, singleQuoted] = match
|
||||
const value = doubleQuoted ?? singleQuoted
|
||||
attrs[key === 'char' ? 'mentionSuggestionChar' : key] = value
|
||||
match = regex.exec(attrString)
|
||||
}
|
||||
|
||||
return attrs
|
||||
},
|
||||
serializeAttributes: (attrs: Record<string, any>) => {
|
||||
return Object.entries(attrs)
|
||||
.filter(([, value]) => value !== undefined && value !== null)
|
||||
.map(([key, value]) => {
|
||||
const serializedKey = key === 'mentionSuggestionChar' ? 'char' : key
|
||||
return `${serializedKey}="${value}"`
|
||||
})
|
||||
.join(' ')
|
||||
},
|
||||
}),
|
||||
|
||||
renderText({ node }) {
|
||||
const args = {
|
||||
options: this.options,
|
||||
node,
|
||||
suggestion: getSuggestionFromChar(this, node.attrs.mentionSuggestionChar),
|
||||
}
|
||||
if (this.options.renderLabel !== undefined) {
|
||||
console.warn('renderLabel is deprecated use renderText and renderHTML instead')
|
||||
return this.options.renderLabel(args)
|
||||
}
|
||||
|
||||
return this.options.renderText(args)
|
||||
},
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
Backspace: () =>
|
||||
this.editor.commands.command(({ tr, state }) => {
|
||||
let isMention = false
|
||||
const { selection } = state
|
||||
const { empty, anchor } = selection
|
||||
|
||||
if (!empty) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Store node and position for later use
|
||||
let mentionNode = new PMNode()
|
||||
let mentionPos = 0
|
||||
|
||||
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
|
||||
if (node.type.name === this.name) {
|
||||
isMention = true
|
||||
mentionNode = node
|
||||
mentionPos = pos
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
if (isMention) {
|
||||
tr.insertText(
|
||||
this.options.deleteTriggerWithBackspace
|
||||
? ''
|
||||
: mentionNode.attrs.mentionSuggestionChar,
|
||||
mentionPos,
|
||||
mentionPos + mentionNode.nodeSize,
|
||||
)
|
||||
}
|
||||
|
||||
return isMention
|
||||
}),
|
||||
}
|
||||
},
|
||||
|
||||
addProseMirrorPlugins() {
|
||||
// Create a plugin for each suggestion configuration
|
||||
return getSuggestions(this).map(Suggestion)
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,89 @@
|
||||
import type { Editor } from '@tiptap/core'
|
||||
import { PluginKey } from '@tiptap/pm/state'
|
||||
import type { SuggestionOptions } from '@tiptap/suggestion'
|
||||
|
||||
/**
|
||||
* Arguments for the `getSuggestionOptions` function
|
||||
* @see getSuggestionOptions
|
||||
*/
|
||||
export interface GetSuggestionOptionsOptions {
|
||||
/**
|
||||
* The Tiptap editor instance.
|
||||
*/
|
||||
editor: Editor
|
||||
/**
|
||||
* The suggestion options configuration provided to the
|
||||
* `Mention` extension.
|
||||
*/
|
||||
overrideSuggestionOptions: Omit<SuggestionOptions, 'editor'>
|
||||
/**
|
||||
* The name of the Mention extension
|
||||
*/
|
||||
extensionName: string
|
||||
/**
|
||||
* The character that triggers the suggestion.
|
||||
* @default '@'
|
||||
*/
|
||||
char?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the suggestion options for a trigger of the Mention extension. These
|
||||
* options are used to create a `Suggestion` ProseMirror plugin. Each plugin lets
|
||||
* you define a different trigger that opens the Mention menu. For example,
|
||||
* you can define a `@` trigger to mention users and a `#` trigger to mention
|
||||
* tags.
|
||||
*
|
||||
* @param param0 The configured options for the suggestion
|
||||
* @returns
|
||||
*/
|
||||
export function getSuggestionOptions({
|
||||
editor: tiptapEditor,
|
||||
overrideSuggestionOptions,
|
||||
extensionName,
|
||||
char = '@',
|
||||
}: GetSuggestionOptionsOptions): SuggestionOptions {
|
||||
const pluginKey = new PluginKey()
|
||||
|
||||
return {
|
||||
editor: tiptapEditor,
|
||||
char,
|
||||
pluginKey,
|
||||
command: ({ editor, range, props }: { editor: any; range: any; props: any }) => {
|
||||
// increase range.to by one when the next node is of type "text"
|
||||
// and starts with a space character
|
||||
const nodeAfter = editor.view.state.selection.$to.nodeAfter
|
||||
const overrideSpace = nodeAfter?.text?.startsWith(' ')
|
||||
|
||||
if (overrideSpace) {
|
||||
range.to += 1
|
||||
}
|
||||
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.insertContentAt(range, [
|
||||
{
|
||||
type: extensionName,
|
||||
attrs: { ...props, mentionSuggestionChar: char },
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
text: ' ',
|
||||
},
|
||||
])
|
||||
.run()
|
||||
|
||||
// get reference to `window` object from editor element, to support cross-frame JS usage
|
||||
editor.view.dom.ownerDocument.defaultView?.getSelection()?.collapseToEnd()
|
||||
},
|
||||
allow: ({ state, range }: { state: any; range: any }) => {
|
||||
const $from = state.doc.resolve(range.from)
|
||||
const type = state.schema.nodes[extensionName]
|
||||
const allow = !!$from.parent.type.contentMatch.matchType(type)
|
||||
|
||||
return allow
|
||||
},
|
||||
...overrideSuggestionOptions,
|
||||
}
|
||||
}
|
||||
9
packages/extension-mention/vite.config.ts
Normal file
9
packages/extension-mention/vite.config.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { defineConfig } from 'vite-plus'
|
||||
import { basePackConfig } from '../../pack.config.mjs'
|
||||
|
||||
export default defineConfig({
|
||||
pack: {
|
||||
entry: ['src/index.ts'],
|
||||
...basePackConfig(),
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user