Skip to content

vitesse-webext

The article will introduce how to migrate a vitesse-webext project to WebExtend. To see the full list of migration changes, please refer to examples/from-vitesse-webext.

Installing dependencies

Install the dependencies of Webextend, Rsbuild, and Vue and UnoCSS plugins for Rsbuild.

shell
npm add -D @rsbuild/core @web-extend/rsbuild-plugin web-extend
npm add -D @rsbuild/plugin-vue @unocss/postcss
shell
pnpm add -D @rsbuild/core @web-extend/rsbuild-plugin web-extend
pnpm add -D @rsbuild/plugin-vue @unocss/postcss
shell
yarn add -D @rsbuild/core @web-extend/rsbuild-plugin web-extend
yarn add -D @rsbuild/plugin-vue @unocss/postcss

Update the versions of unocss, unplugin-auto-import and unplugin-icons packages, guaranteeing they can be integrated into Rsbuild.

shell
npm add -D unocss@latest @unocss/reset@latest
npm add -D unplugin-auto-import@latest
npm add -D unplugin-icons@latest
shell
pnpm add -D unocss@latest @unocss/reset@latest
pnpm add -D unplugin-auto-import@latest
pnpm add -D unplugin-icons@latest
shell
yarn add -D unocss@latest @unocss/reset@latest
yarn add -D unplugin-auto-import@latest
yarn add -D unplugin-icons@latest

Updating npm scripts

Next, add the "type": "module" field into package.json, and replace the commands in scripts (including dev, build, pack, start, etc.) with the CLI commands of web-extend.

package.json
json
{
  "type": "module", 
  "scripts": {
    "dev": "npm run clear && cross-env NODE_ENV=development run-p dev:*", 
    "dev-firefox": "npm run clear && cross-env NODE_ENV=development EXTENSION=firefox run-p dev:*", 
    "dev:prepare": "esno scripts/prepare.ts", 
    "dev:background": "npm run build:background -- --mode development", 
    "dev:web": "vite", 
    "dev:js": "npm run build:js -- --mode development", 
    "dev": "web-extend rsbuild:dev --open", 
    "dev:firefox": "web-extend rsbuild:dev --open --target firefox-mv2", 

    "build": "cross-env NODE_ENV=production run-s clear build:web build:prepare build:background build:js", 
    "build:prepare": "esno scripts/prepare.ts", 
    "build:background": "vite build --config vite.config.background.mts", 
    "build:web": "vite build", 
    "build:js": "vite build --config vite.config.content.mts", 
    "build": "web-extend rsbuild:build", 
    "build:firefox": "web-extend rsbuild:build --target firefox-mv2", 

    "pack": "cross-env NODE_ENV=production run-p pack:*", 
    "pack:zip": "rimraf extension.zip && jszip-cli add extension/* -o ./extension.zip", 
    "pack:crx": "crx pack extension -o ./extension.crx", 
    "pack:xpi": "cross-env WEB_EXT_ARTIFACTS_DIR=./ web-ext build --source-dir ./extension --filename extension.xpi --overwrite-dest", 
    "zip": "web-extend zip", 
    "zip:firefox": "web-extend zip --target firefox-mv2", 

    "start:chromium": "web-ext run --source-dir ./extension --target=chromium", 
    "start:firefox": "web-ext run --source-dir ./extension --target=firefox-desktop", 
    "preview": "web-extend preview", 
    "preview:firefox": "web-extend preview --target firefox-mv2", 

    "clear": "rimraf --glob extension/dist extension/manifest.json extension.*"
  }
}

Migrate bundler

WebExtend uses Rsbuild under the hood, so you need to migrate the bundler from Vite to Rsbuild. Nevertheless, the migration process is easy, and the main changes are as follows.

  1. Create rsbuild.config.ts in the root.
  2. Add the following plugins.
  3. Migrate the following config.
    • resolve.alias -> resolve.alias
    • define -> source.define
    • set html.mountId: "app". Rsbuild will inject an HTML file for each entry file, so the original HTML files in source are useless.
  4. Support UnoCSS.
    • Create postcss.config.mjs, and import the @unocss/postcss plugin.
    • Adjust the content of unocss.config.ts.
    • Remove import 'uno.css' from JS files, and insert @unocss; into the corresponding CSS files.

The full list of all config are as follows.

rsbuild.config.ts
ts
import { defineConfig } from "@rsbuild/core";
import { pluginWebExtend } from "@web-extend/rsbuild-plugin";
import { pluginVue } from "@rsbuild/plugin-vue";
import Components from "unplugin-vue-components/rspack";
import AutoImport from "unplugin-auto-import/rspack";
import Icons from "unplugin-icons/rspack";
import IconsResolver from "unplugin-icons/resolver";
import { isDev, r } from "./scripts/utils";
import packageJson from "./package.json";
import manifest from "./src/manifest";

export default defineConfig({
  plugins: [
    pluginVue(),
    pluginWebExtend({
      manifest,
    }),
  ],
  html: {
    mountId: "app",
  },
  resolve: {
    alias: {
      "~/": "./src/",
    },
  },
  source: {
    define: {
      __DEV__: isDev,
      __NAME__: JSON.stringify(packageJson.name),
    },
  },
  tools: {
    rspack: {
      plugins: [
        AutoImport({
          imports: [
            "vue",
            {
              "webextension-polyfill": [["=", "browser"]],
            },
          ],
          dts: r("src/auto-imports.d.ts"),
        }),

        Components({
          dirs: [r("src/components")],
          // generate `components.d.ts` for ts support with Volar
          dts: r("src/components.d.ts"),
          resolvers: [
            // auto import icons
            IconsResolver({
              prefix: "",
            }),
          ],
        }),

        Icons(),
      ],
    },
  },
});
postcss.config.mjs
js
import UnoCSS from "@unocss/postcss";

export default {
  plugins: [UnoCSS()],
};
unocss.config.ts
js
import { defineConfig } from "unocss/vite";
import { presetAttributify, presetIcons, presetWind3 } from "unocss";

export default defineConfig({
  content: {
    filesystem: [
      "src/**/*.{html,js,ts,jsx,tsx,vue,svelte,astro}",
      "!src/**/*.d.ts",
    ],
  },
  presets: [presetWind3(), presetAttributify(), presetIcons()],
});

To custom other config in the project, please refer to:

Updating source code

WebExtend uses the file system to parse entry files and generates the corresponding fields for manifest.json. So you don't need to define them explicitly any more. The main changes are as follows.

  • Generate icons: run npx web-extend g icons --template ./extension/assets/icon-512.png to generate icon files under the src/assets directory.
  • Change popup, options and sidepanel: remove index.html and rename main.ts to index.ts respectively.
  • Change content: rename the contentScripts directory to content.
  • Change background: rename main.ts to index.ts, and remove import.meta.hot related content in code.
  • Remove useless code about entries in manifest.ts and retain the permissions, host_permissions, etc, fields.

Validating results

After completing all changes above, congratulations 🎉 ! You have done the basic migration. Now you can run npm run dev or npm run build for having a try.

Note

The extension's artifact directory is dist/[target]-[mode] instead of extension in WebExtend.

If there is any omission or mistake in the above migration process, please point it out. You can submit an issue or a PR directly from the Github page 🤝.

Released under the MIT License.