Introducing #imports
WXT v0.20 introduced a new way of manually importing its APIs: the #imports
module. This module was introduced to simplify import statements and provide more visibility into all the APIs WXT provides.
import { browser } from 'wxt/browser';
import { createShadowRootUi } from 'wxt/utils/content-script-ui/shadow-root';
import { defineContentScript } from 'wxt/utils/define-content-script';
import { injectScript } from 'wxt/utils/inject-script';
import {
browser, createShadowRootUi, defineContentScript, injectScript
} from '#imports';
The #imports
module is considered a "virtual module", because the file doesn't actually exist. At build-time, imports are split into individual statements for each API:
import { defineContentScript, injectScript } from '#imports';
import { defineContentScript } from 'wxt/utils/define-content-script';
import { injectScript } from 'wxt/utils/inject-script';
Think of #imports
as a convenient way to access all of WXT's APIs from one place, without impacting performance or bundle size.
This enables better tree-shaking compared to v0.19 and below.
Need to lookup the full import path of an API?
Open up your project's .wxt/types/imports-module.d.ts
file.
Mocking
When writing tests, you might need to mock APIs from the #imports
module. While mocking these APIs is very easy, it may not be immediately clear how to accomplish it.
Let's look at an example using Vitest. When configured with wxt/testing
, Vitest sees the same transformed code as the bundler. That means to mock an API from #imports
, you need to call vi.mock
with the real import path, not #imports
:
import { injectScript } from '#imports';
import { vi } from 'vitest';
vi.mock('wxt/utils/inject-script')
const injectScriptMock = vi.mocked(injectScript);
injectScriptMock.mockReturnValueOnce(...);
Conclusion
You don't have to use #imports
if you don't like - you can continue importing APIs from their submodules. However, using #imports
is the recommended approach moving forwards.
- As more APIs are added, you won't have to memorize additional import paths.
- If breaking changes are made to import paths in future major versions,
#imports
won't break.
Happy Coding 😄
P.S. Yes, this is exactly how Nuxt's
#imports
works! We use the exact same library,unimport
.