diff --git a/package.json b/package.json index 3c5f173..1ddf925 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup-plugin-visualizer", - "version": "5.14.0", + "version": "5.15.0", "main": "./dist/plugin/index.js", "author": "Denis Bardadym ", "license": "MIT", diff --git a/plugin/index.ts b/plugin/index.ts index 3f9a825..991153d 100644 --- a/plugin/index.ts +++ b/plugin/index.ts @@ -113,6 +113,11 @@ export interface PluginVisualizerOptions { * default. Otherwise, an ID must match one or more of the picomatch patterns, and must not match any of the options.exclude patterns. */ exclude?: Filter | Filter[]; + + /** + * filterModel: 'glob' | 'regexp' + */ + filterModel?: 'glob' | 'regexp' } const defaultSizeGetter: SizeGetter = () => Promise.resolve(0); @@ -152,7 +157,7 @@ export const visualizer = ( const template = opts.template ?? "treemap"; const projectRoot = opts.projectRoot ?? process.cwd(); - const filter = createFilter(opts.include, opts.exclude); + const filter = createFilter(opts.include, opts.exclude, opts.filterModel || 'glob'); const gzipSize = !!opts.gzipSize && !opts.sourcemap; const brotliSize = !!opts.brotliSize && !opts.sourcemap; diff --git a/shared/create-filter.test.ts b/shared/create-filter.test.ts index 88deb33..b99a1c8 100644 --- a/shared/create-filter.test.ts +++ b/shared/create-filter.test.ts @@ -1,10 +1,10 @@ import { describe, it, expect } from "vitest"; -import { createFilter } from "./create-filter"; +import { createFilter as _createFilter, Filter } from "./create-filter"; describe("createFilter", () => { + const createFilter = (include: Filter | Filter[] | undefined, exclude: Filter | Filter[] | undefined) => _createFilter(include, exclude, 'glob') it("should return true when input and output is empty", () => { const isIncluded = createFilter([], []); - expect(isIncluded("bundle", "file")).toBe(true); }); @@ -92,7 +92,7 @@ describe("createFilter", () => { ])( "%# should exclude included %j %j bundle %j file %j - %j", (include, exclude, bundle, file, result) => { - const isIncluded = createFilter(include, exclude); + const isIncluded = createFilter(include, exclude,); expect(isIncluded(bundle, file)).toBe(result); } ); diff --git a/shared/create-filter.ts b/shared/create-filter.ts index 0ffc03b..d5e80bc 100644 --- a/shared/create-filter.ts +++ b/shared/create-filter.ts @@ -5,6 +5,8 @@ export type Filter = { file?: string | null | undefined; }; +export type FilterModel = 'glob' | 'regexp' + function isArray(arg: unknown): arg is any[] | readonly any[] { return Array.isArray(arg); } @@ -39,20 +41,23 @@ const testTrue: Testable = { test: () => true, }; -const getMatcher = (filter: Filter) => { +const getMatcher = (filter: Filter, filterModel: FilterModel) => { + const filterMethods = (str: string) => filterModel === 'glob' ? globToTest(str) : new RegExp(str) + const bundleTest = - "bundle" in filter && filter.bundle != null ? globToTest(filter.bundle) : testTrue; - const fileTest = "file" in filter && filter.file != null ? globToTest(filter.file) : testTrue; + "bundle" in filter && filter.bundle != null ? filterMethods(filter.bundle) : testTrue; + const fileTest = "file" in filter && filter.file != null ? filterMethods(filter.file) : testTrue; return { bundleTest, fileTest }; }; export const createFilter = ( include: Filter | Filter[] | undefined, - exclude: Filter | Filter[] | undefined + exclude: Filter | Filter[] | undefined, + filterModel: FilterModel ) => { - const includeMatchers = ensureArray(include).map(getMatcher); - const excludeMatchers = ensureArray(exclude).map(getMatcher); + const includeMatchers = ensureArray(include).map(item => getMatcher(item, filterModel)); + const excludeMatchers = ensureArray(exclude).map(item => getMatcher(item, filterModel)); return (bundleId: string, id: string) => { for (let i = 0; i < excludeMatchers.length; ++i) { diff --git a/src/flamegraph/main.tsx b/src/flamegraph/main.tsx index fc4e7ad..db7a849 100644 --- a/src/flamegraph/main.tsx +++ b/src/flamegraph/main.tsx @@ -19,7 +19,7 @@ export const Main: FunctionalComponent = () => { HierarchyRectangularNode | undefined >(undefined); - const { getModuleFilterMultiplier, setExcludeFilter, setIncludeFilter } = useFilter(); + const { getModuleFilterMultiplier, setExcludeFilter, setIncludeFilter, setFilterModel } = useFilter(); console.time("getNodeSizeMultiplier"); const getNodeSizeMultiplier = useMemo(() => { @@ -87,6 +87,7 @@ export const Main: FunctionalComponent = () => { setSizeProperty={setSizeProperty} onExcludeChange={setExcludeFilter} onIncludeChange={setIncludeFilter} + onFilterModelChange={setFilterModel} /> { const [excludedNodes, setExcludedNodes] = useState([]); const [selectedNode, setSelectedNode] = useState(); - const { getModuleFilterMultiplier, setExcludeFilter, setIncludeFilter } = useFilter(); + const { getModuleFilterMultiplier, setExcludeFilter, setIncludeFilter, setFilterModel } = useFilter(); const getColor = (node: NodeInfo) => { if (selectedNode != null) { @@ -139,6 +139,7 @@ export const Main: FunctionalComponent = () => { setSizeProperty={() => {}} onExcludeChange={setExcludeFilter} onIncludeChange={setIncludeFilter} + onFilterModelChange={setFilterModel} /> void; onExcludeChange: (value: string) => void; onIncludeChange: (value: string) => void; + defaultFilterValue?: string; + onFilterModelChange: (value: FilterModel) => void } const PLACEHOLDER = "*/**/file.js"; @@ -19,6 +22,8 @@ export const SideBar: FunctionalComponent = ({ setSizeProperty, onExcludeChange, onIncludeChange, + defaultFilterValue = 'glob', + onFilterModelChange }) => { const [includeValue, setIncludeValue] = useState(""); const [excludeValue, setExcludeValue] = useState(""); @@ -41,6 +46,11 @@ export const SideBar: FunctionalComponent = ({ onExcludeChange(value); }; + const handleSelectFilterChange = (event: JSX.TargetedEvent) => { + const value = event.currentTarget.value; + onFilterModelChange(value as FilterModel) + } + return ( ); diff --git a/src/sunburst/main.tsx b/src/sunburst/main.tsx index d4e062b..4e52546 100644 --- a/src/sunburst/main.tsx +++ b/src/sunburst/main.tsx @@ -20,7 +20,7 @@ export const Main: FunctionalComponent = () => { HierarchyRectangularNode | undefined >(undefined); - const { getModuleFilterMultiplier, setExcludeFilter, setIncludeFilter } = useFilter(); + const { getModuleFilterMultiplier, setExcludeFilter, setIncludeFilter, setFilterModel } = useFilter(); const getNodeSizeMultiplier = useMemo(() => { if (selectedNode === undefined) { @@ -81,6 +81,7 @@ export const Main: FunctionalComponent = () => { setSizeProperty={setSizeProperty} onExcludeChange={setExcludeFilter} onIncludeChange={setIncludeFilter} + onFilterModelChange={setFilterModel} /> { HierarchyRectangularNode | undefined >(undefined); - const { getModuleFilterMultiplier, setExcludeFilter, setIncludeFilter } = useFilter(); + const { getModuleFilterMultiplier, setExcludeFilter, setIncludeFilter, setFilterModel } = useFilter(); console.time("getNodeSizeMultiplier"); const getNodeSizeMultiplier = useMemo(() => { @@ -88,6 +88,7 @@ export const Main: FunctionalComponent = () => { setSizeProperty={setSizeProperty} onExcludeChange={setExcludeFilter} onIncludeChange={setIncludeFilter} + onFilterModelChange={setFilterModel} /> void; @@ -22,6 +22,8 @@ export type UseFilter = { setIncludeFilter: FilterSetter; setExcludeFilter: FilterSetter; getModuleFilterMultiplier: (bundleId: string, data: { id: string }) => number; + filterModel: string + setFilterModel: (value: FilterModel) => void }; export const prepareFilter = (filt: string) => { @@ -61,15 +63,17 @@ export const prepareFilter = (filt: string) => { ); }; + export const useFilter = (): UseFilter => { const [includeFilter, setIncludeFilter] = useState(""); const [excludeFilter, setExcludeFilter] = useState(""); + const [filterModel, setFilterModel] = useState<'glob' | 'regexp'>('glob') const setIncludeFilterTrottled = useMemo(() => throttleFilter(setIncludeFilter, 200), []); const setExcludeFilterTrottled = useMemo(() => throttleFilter(setExcludeFilter, 200), []); const isIncluded = useMemo( - () => createFilter(prepareFilter(includeFilter), prepareFilter(excludeFilter)), + () => createFilter(prepareFilter(includeFilter), prepareFilter(excludeFilter), filterModel), [includeFilter, excludeFilter], ); @@ -86,5 +90,7 @@ export const useFilter = (): UseFilter => { excludeFilter, setExcludeFilter: setExcludeFilterTrottled, setIncludeFilter: setIncludeFilterTrottled, + filterModel, + setFilterModel }; };