-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(vite): add plugin to remove modules from the bundle (#8973)
Co-authored-by: Tobbe Lundberg <[email protected]> Co-authored-by: Daniel Choudhury <[email protected]>
- Loading branch information
1 parent
98dbfaa
commit cb31df9
Showing
4 changed files
with
85 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
packages/vite/src/plugins/__tests__/remove-from-bundle.test.mts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import assert from 'node:assert/strict' | ||
import { describe, it } from 'node:test' | ||
|
||
import * as vitePluginRemoveFromBundle from '../vite-plugin-remove-from-bundle.js' | ||
|
||
// @ts-expect-error We have to write it this way to appease node:test, but TS doesn't seem to like it. | ||
// node:test needs to be configured correctly, I imagine. | ||
const { excludeOnMatch } = vitePluginRemoveFromBundle.default | ||
|
||
describe('excludeModule', () => { | ||
it('should return true if idToExclude matches id', () => { | ||
const loadOutput = excludeOnMatch([{ | ||
id: /router\/dist\/splash-page/, | ||
}], | ||
'/Users/dac09/Experiments/splash-page-null-loader/node_modules/@redwoodjs/router/dist/splash-page.js?commonjs-exports', | ||
) | ||
|
||
assert.notStrictEqual(loadOutput, { | ||
code: 'module.exports = null' | ||
}) | ||
}) | ||
|
||
it("should return false if idToExclude doesn't match id", () => { | ||
const loadOutput = excludeOnMatch([{ | ||
id: /bazinga-page/, | ||
}], | ||
'/Users/dac09/Experiments/splash-page-null-loader/node_modules/@redwoodjs/router/dist/params.js') | ||
|
||
assert.equal(loadOutput, null) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
packages/vite/src/plugins/vite-plugin-remove-from-bundle.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import type { PluginOption } from 'vite' | ||
|
||
type ModulesToExclude = Array<{ id: RegExp }> | ||
|
||
/** | ||
* | ||
* This is a vite plugin to remove modules from the bundle. | ||
* | ||
* Only applies on build, not on dev. | ||
* | ||
*/ | ||
export default function removeFromBundle( | ||
modulesToExclude: ModulesToExclude | ||
): PluginOption { | ||
const isMissingIdToExclude = modulesToExclude.some( | ||
(module) => module.id === undefined | ||
) | ||
|
||
if (isMissingIdToExclude) { | ||
throw new Error('You must specify an id to exclude') | ||
} | ||
|
||
return { | ||
name: 'remove-from-bundle', | ||
apply: 'build', // <-- @MARK important | ||
load: (id) => { | ||
return excludeOnMatch(modulesToExclude, id) | ||
}, | ||
} | ||
} | ||
|
||
// Currently configured for CJS only. | ||
const EMPTY_MODULE = { | ||
code: `module.exports = null`, | ||
} | ||
|
||
export function excludeOnMatch(modulesToExclude: ModulesToExclude, id: string) { | ||
if (modulesToExclude.some((module) => module.id.test(id))) { | ||
// Return an empty module | ||
return EMPTY_MODULE | ||
} | ||
|
||
// Fallback to regular loaders | ||
return null | ||
} |