fix!: Remove url: import feature (#2456)

Co-authored-by: Aaron <aaronklinker1@gmail.com>
This commit is contained in:
Gliches
2026-07-26 08:38:27 +05:30
committed by Aaron
parent b7bdb11a15
commit 13151509b6
13 changed files with 1 additions and 110 deletions
-1
View File
@@ -53,7 +53,6 @@ Or see the [installation guide](https://wxt.dev/guide/installation.html) to get
- 📦 [Module system](https://wxt.dev/guide/essentials/wxt-modules.html#overview) for reusing code between extensions
- 🖍️ Quickly bootstrap a new project
- 📏 Bundle analysis
- ⬇️ Download and bundle remote URL imports
## Sponsors
-31
View File
@@ -1,31 +0,0 @@
# Remote Code
WXT will automatically download and bundle imports with the `url:` prefix so the extension does not depend on remote code, [a requirement from Google for MV3](https://developer.chrome.com/docs/extensions/migrating/improve-security/#remove-remote-code).
## Google Analytics
For example, you can import Google Analytics:
```ts
// utils/google-analytics.ts
import 'url:https://www.googletagmanager.com/gtag/js?id=G-XXXXXX';
window.dataLayer = window.dataLayer || [];
// NOTE: This line is different from Google's documentation
window.gtag = function () {
dataLayer.push(arguments);
};
gtag('js', new Date());
gtag('config', 'G-XXXXXX');
```
Then you can import this in your HTML files to enable Google Analytics:
```ts
// popup/main.ts
import '~/utils/google-analytics';
gtag('event', 'event_name', {
key: 'value',
});
```
-1
View File
@@ -21,7 +21,6 @@ This plugin does several things:
- Polyfills the extension API, `browser`, with an in-memory implementation using [`@webext-core/fake-browser`](https://webext-core.aklinker1.io/fake-browser/installation)
- Adds all vite config or plugins in `wxt.config.ts`
- Configures auto-imports (if enabled)
- Applies internal WXT vite plugins for things like [bundling remote code](/guide/essentials/remote-code)
- Sets up global variables provided by WXT (`import.meta.env.BROWSER`, `import.meta.env.MANIFEST_VERSION`, `import.meta.env.IS_CHROME`, etc)
- Configures aliases (`@/*`, `@@/*`, etc) so imports can be resolved
-1
View File
@@ -24,7 +24,6 @@ Lets compare the features of WXT vs [Plasmo](https://docs.plasmo.com/framework)
| Supports all frontend frameworks | ✅ | 🟡 [^c] | ✅ |
| Framework specific entrypoints (like `Popup.tsx`) | 🟡 [^d] | ✅ [^e] | ❌ |
| Automated publishing | ✅ | ✅ | ❌ |
| Remote Code Bundling (Google Analytics) | ✅ | ✅ | ❌ |
| Unlisted HTML Pages | ✅ | ✅ | ✅ |
| Unlisted Scripts | ✅ | ❌ | ❌ |
| ESM Content Scripts | ❌ [^l] | ❌ | ✅ |
+1 -1
View File
@@ -51,7 +51,7 @@ Here's specific steps for other popular frameworks/build tools.
3. Move public `assets/*` into the `public/` directory
4. If you use CSUI, migrate to WXT's `createContentScriptUi`
5. Convert Plasmo's custom import resolutions to Vite's
6. If importing remote code via a URL, add a `url:` prefix so it works with WXT
6. Importing remote code via a URL is not supported in WXT, see [this issue](https://github.com/wxt-dev/wxt/issues/2262) for alternatives
7. Replace your [Plasmo tags](https://docs.plasmo.com/framework/workflows/build#with-a-custom-tag) (`--tag`) with [WXT build modes](/guide/essentials/config/build-mode) (`--mode`)
8. ⚠️ Compare the old production manifest to `.output/*/manifest.json`. They should have the same content as before. If not, tweak your entrypoints and config until they are the same.
-5
View File
@@ -66,11 +66,6 @@ features:
- icon: 📏
title: Bundle Analysis
details: Tools for analyzing the final extension bundle and minimizing your extension's size.
- icon: ⬇️
title: Bundle Remote Code
details: Downloads and bundles remote code imported from URLs.
link: /guide/essentials/remote-code
linkText: Read docs
---
## Sponsors
@@ -1,6 +1,3 @@
// @ts-expect-error: URL imports not typed
import 'url:https://code.jquery.com/jquery-3.7.1.slim.min.js';
console.log(browser.runtime.id);
logId();
console.log(2);
-1
View File
@@ -54,7 +54,6 @@ Or see the [installation guide](https://wxt.dev/guide/installation.html) to get
- 📦 [Module system](https://wxt.dev/guide/essentials/wxt-modules.html#overview) for reusing code between extensions
- 🖍️ Quickly bootstrap a new project
- 📏 Bundle analysis
- ⬇️ Download and bundle remote URL imports
## Sponsors
@@ -1,26 +0,0 @@
import { describe, it, expect } from 'vitest';
import { TestProject } from '../utils';
describe('Remote Code', () => {
it('should download "url:*" modules and include them in the final bundle', async () => {
const url = 'https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js';
const project = new TestProject();
project.addFile(
'entrypoints/popup.ts',
`import "url:${url}"
export default defineUnlistedScript(() => {})`,
);
await project.build();
const output = await project.serializeFile('.output/chrome-mv3/popup.js');
expect(output).toContain(
// Some text that will hopefully be in future versions of this script
'__lodash_placeholder__',
);
expect(output).not.toContain(url);
expect(
await project.pathExists(`.wxt/cache/${encodeURIComponent(url)}`),
).toBe(true);
});
});
@@ -94,7 +94,6 @@ export async function createViteBuilder(
config.plugins ??= [];
config.plugins.push(
wxtPlugins.download(wxtConfig),
wxtPlugins.devHtmlPrerender(wxtConfig, server),
wxtPlugins.resolveVirtualModules(wxtConfig),
wxtPlugins.devServerGlobals(wxtConfig, server),
@@ -1,36 +0,0 @@
import type { Plugin } from 'vite';
import type { ResolvedConfig } from '../../../../types';
import { fetchCached } from '../../../utils/network';
/**
* Downloads any URL imports, like Google Analytics, into virtual modules so
* they are bundled with the extension instead of depending on remote code at
* runtime.
*
* @example
* import 'url:https://google-tagmanager.com/gtag?id=XYZ';
*/
export function download(config: ResolvedConfig): Plugin {
return {
name: 'wxt:download',
enforce: 'pre',
resolveId: {
filter: {
id: /^url:/,
},
handler(id) {
return `\0${id}`;
},
},
load: {
filter: {
//eslint-disable-next-line no-control-regex
id: /^\x00url:/,
},
handler(id) {
const url = id.replace('\0url:', '');
return fetchCached(url, config);
},
},
};
}
@@ -1,6 +1,5 @@
export * from './devHtmlPrerender';
export * from './devServerGlobals';
export * from './download';
export * from './resolveVirtualModules';
export * from './tsconfigPaths';
export * from './noopBackground';
@@ -7,7 +7,6 @@
import type * as vite from 'vite';
import {
download,
tsconfigPaths,
globals,
extensionApiMock,
@@ -41,7 +40,6 @@ export async function WxtVitest(
const plugins: vite.PluginOption[] = [
globals(wxt.config),
download(wxt.config),
tsconfigPaths(wxt.config),
resolveAppConfig(wxt.config),
extensionApiMock(wxt.config),