Coder Social home page Coder Social logo

aklinker1 / vite-plugin-web-extension Goto Github PK

View Code? Open in Web Editor NEW
497.0 5.0 44.0 1.56 MB

Vite plugin for developing Chrome/Web Extensions

Home Page: https://vite-plugin-web-extension.aklinker1.io/

License: MIT License

TypeScript 86.28% HTML 4.83% JavaScript 3.72% CSS 2.78% SCSS 0.08% Vue 1.54% Shell 0.38% Svelte 0.39%
vite extension

vite-plugin-web-extension's Introduction

Build Status NPM Version NPM Downloads Vite Version

To get started quickly, bootstrap a new project!

npm create vite-plugin-web-extension
pnpm create vite-plugin-web-extension
yarn create vite-plugin-web-extension

Features

  • 🔧 Automatically build inputs listed in your manifest.json
  • 🎉 Open a browser and install the extension during development
  • ⚡ Super fast dev mode
  • 🌐 Supports all browsers
  • 🔥 Full frontend framework support (popup, options, and content scripts)
  • 🤖 Typescript support out of the box!
  • ✅ Manifest validation

Documentation

To get started, checkout the docs:

https://vite-plugin-web-extension.aklinker1.io

Contributing

Special thanks to the contributors!

See the contributing docs to setup the project for development.

vite-plugin-web-extension's People

Contributors

aklinker1 avatar andrewbellucci avatar dm0reau avatar github-actions[bot] avatar jvariance avatar karmaral avatar kentonishi avatar knokmki612 avatar nicolasreibnitz avatar r2dev2 avatar samfundev avatar ssf01 avatar theovgl avatar treora avatar wallw-teal avatar x11x avatar xiz0r avatar yujinlin0224 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

vite-plugin-web-extension's Issues

你好,我想在扩展中添加`new-tab`,从而实现自定义空白页

你好,我想在扩展中添加new-tab,从而实现自定义浏览器新标签的空白页。
但我尝试了在src/menifest.json中添加了:

"chrome_url_overrides": {
  "newtab": "newtab/index.html"
},

并且添加了:src/newtab/index.html
但是当我运行npm run dev(vite build --watch),编译完成后,却弹出无法加载清单。,并且未在dist文件夹中找到newtab/index.html文件,但是dist/menifest.json中的配置是存在 chrome_url_overrides.newtab配置的。

我应该如何配置和操作,希望得到你的帮助,非常感谢

[Bug Report] build module copy the `public` folder incorrectly

Chrome extension may have some special file ( or folder ) in extension root, like _locales folder for i18n, or static assets folder.
However, After add this vite plugin, those files in public folder will not copy to dist folder when execute vite build --watch.
But when execute command vite build without --watch param, those files will copy fined.

Steps to reproduce

  1. Create a normal vite project
yarn create vite
cd bug-report
mkdir public
echo 'test file' > public/test.txt
yarn
yarn build --watch

In this step, we can see the file test.txt corrent copy to the public folder, then exit and rm the dist folder.

  1. Add this vite plugin,
yarn add -D vite-plugin-web-extension

and sort project like the demo/vanilla, the whole filetree are like this

src
│  manifest.json
│
├─assets
│  └─icon
│          128.png
│
├─background
│      index.ts
│
├─options
│      index.html
│      main.ts
│
├─popup
│      index.html
│      main.ts
│
└─public
    └─_locales
        ├─en
        │      messages.json
        │
        └─zh_CN
                messages.json

in manifest.json, I change the key name like:

{
  "name": "__MSG_extName__"
}

and the minimal reproduction can see this repo: https://github.com/Rhilip/bugreport-vite-plugin-web-extension-watchbuild

  1. The run the build command,

    • For vite build --watch , the dist folder is like
    dist
      │  manifest.json
      │  modulepreload-polyfill.js
      │
      ├─assets
      │  └─icon
      │          128.png
      │          16.png
      │          48.png
      │
      ├─background
      │  │  index.js
      │  │
      │  └─_locales   <-  It appeared in background folder
      │      ├─en
      │      │      messages.json
      │      │
      │      └─zh_CN
      │              messages.json
      │
      ├─options
      │      index.html
      │      index.js
      │
      └─popup
              index.html
              index.js
    
    • For vite build, the dist folder is like
    dist
    │  manifest.json
    │  modulepreload-polyfill.js
    │
    ├─ ... other same folder
    │
    └─_locales
        ├─en
        │      messages.json
        │
        └─zh_CN
            messages.json
    
  2. I also test two structure, however still same as step 3

  • move public folder into project root
	  root
	  ├─node_modules
	  ├─public
	  │  └─_locales
	  │      ├─en
	  │      └─zh_CN
	  └─src
	      ├─assets
	      │  └─icon
	      ├─background
	      ├─options
	      └─popup
  • separate old public folder, leave _locales folder inside src folder, and use same assets folder.
	  root
	  ├─node_modules
	  └─src
	      ├─_locales
	       │ ├─en
	       │ └─zh_CN
	      ├─assets
	      │  └─icon
	      ├─background
	      ├─options
	      └─popup

What is actually happening?

When run command vite build , the files in public folder will be copy to dist/background folder and dist folder,
When run command vite build --watch, those files will only be copy to dist/background folder.

What is expected?

When run command vite build or vite build -watch, the public folder will copy as default vite behavior: copy to dist folder.

Environement variables .env

Hi,

Is there a way to get env variables from .env in content_script ?

.env

VITE_CUSTOM = test

vite.config.ts

export default defineConfig((command, mode) => {
  console.log(command, mode);
  // { mode: 'development', command: 'serve' }
  
  console.log(loadEnv(mode, __dirname));
  // { VITE_CUSTOM: 'test' }
  ...

content_script.ts

   console.log(import.meta.env)
//   {"BASE_URL":"/","MODE":"production","DEV":false,"PROD":true}

Thanks

Getting "You must supply options.input to rollup" error when building

Greetings, and thanks for writing this plugin.

I'm getting the following error when running vite build --watch:

You must supply options.input to rollup

Here's my vite.config.ts file:

import fs from "node:fs"
import path from "node:path"
import { defineConfig } from "vite"
import webExtension from "vite-plugin-web-extension"

const manifest = JSON.parse(fs.readFileSync(path.resolve(__dirname, "_src/manifest.json"), "utf8"))

export default defineConfig({
  root: "dist",
  // Configure our outputs - nothing special, this is normal vite config
  build: {
    outDir: path.resolve(__dirname, "build/web-extension"),
    emptyOutDir: true
  },
  // Add the webExtension plugin
  plugins: [
    // @ts-expect-error - TODO: fix module stuff later
    webExtension.default({
      manifest: () => {
        return manifest
      },
      assets: path.resolve(__dirname, "_src/assets")
    })
  ]
})

And the content of manifest.json, if that helps:

{
  "manifest_version": 3,
  "name": "Some WebExtension",
  "version": "1.0",
  "description": "Adds a red border to some webpages.",
  "permissions": ["webRequest", "webRequestBlocking"],
  "host_permissions": ["*://*.example.com/*"],
  "icons": {
    "48": "icons/flower-48.png"
  },
  "background": {
    "service_worker": "background.js",
    "type": "module"
  }
}

I see there's a test snapshot which also contains this error:

You must supply options.input to rollup"

Could it be related to this line in the lib source code?

I'm fairly new to vite and not really seasoned with rollup. Is there anything that I should be tweaking on my side and/or is this something that relates to vite-plugin-web-extension?
I'll be happy to provide more details if that helps.

(Not related: I'm having ES6/TS module issues in vite.config.ts but I haven't bothered fixing them yet #YakShaving.)

Incorrent peer dependency semver

The vite peer dependency on the package.json from npm is listed with version 2.6+, which is an incorrect semver format and will be reported by yarn as an incorrect peer dependency.

It should be set to either ^2.6 to match all versions starting from 2.6 till 3.0, or >=2.6 to match all versions newer or equal to 2.6.

On a side note, is there any particular reason that the package.json for npm is not included in this repo?

Automatically restart browser when save HTML entrypoints in dev mode

Summary

HMR doesn't work when saving changes to an HTML file directly, so these types of files should be added to the list of files that automatically trigger a full reload of the extension (close the browser and reopen).

// Add watch files that trigger a full rebuild
options.watchFilePaths.forEach((file) => this.addWatchFile(file));
if (typeof options.manifest === "string") {
this.addWatchFile(path.resolve(paths.rootDir, options.manifest));
}

Here's where the manifest and watchFilePaths config is added to watched files. Just add all the HTML files using addWatchFile here as well.

Is your feature request related to a bug/issue?

Yes, HMR doesn't work for HTML entrypoints

Alternatives

I tried just reloading the page in place, but that didn't work. I also tried reloading the full extension from the extensions page, but that didn't work either. Ultimately, I had to stop the dev server and rerun the dev command.

It should work if we just close the browser and open a new one, like what happens when we save a change to the manifest.json.

Additional Context

Discovered while working on #88

Investigate Caching Options

Summary

I'd like to investigate some potential options for speeding up builds. With lots of entrypoints, projects can take quite a long time to build.

  • I believe Nuxt caches parts of the build process, perhaps we could learn from them?
  • Parallel builds? v1 did this, but it lead to high memory consumption, so I'd like to stay away from this.
  • I need to profile an extension with a lot of entrypoints to see what steps of the build are taking a long time? Off the top of my head, the transform step seems to take the longest... We don't need to transform the same files and dependencies multiple times, can we cache that somehow?

Is your feature request related to a bug/issue?

No

Additional Context

Spiritual successor to #39

Try to run v2 but got `Error: Render Manifest: Bundle output not found for: popup/index.html at findReplacement`

Since create-vite-plugin-web-extension still in v1, I try to use pnpm create vite-plugin-web-extension with Vue+Typescript to get vite-plugin-web-extension v1 project and migrate to v2 by myself, but when I try to start pnpm dev, I got this error:

error when starting dev server:
Error: Render Manifest: Bundle output not found for: popup/index.html
    at findReplacement (file:///D:/Projects/JavaScript/vue-plugin-project/node_modules/.pnpm/[email protected][email protected]/node_modules/vite-plugin-web-extension/dist/index.js:976:11)
    at replaceEntrypoint (file:///D:/Projects/JavaScript/vue-plugin-project/node_modules/.pnpm/[email protected][email protected]/node_modules/vite-plugin-web-extension/dist/index.js:990:43)
    at renderManifest (file:///D:/Projects/JavaScript/vue-plugin-project/node_modules/.pnpm/[email protected][email protected]/node_modules/vite-plugin-web-extension/dist/index.js:950:3)
    at Context.buildStart (file:///D:/Projects/JavaScript/vue-plugin-project/node_modules/.pnpm/[email protected][email protected]/node_modules/vite-plugin-web-extension/dist/index.js:1109:29)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Promise.all (index 5)
    at async hookParallel (file:///D:/Projects/JavaScript/vue-plugin-project/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-cff57044.js:40728:9)
    at async Object.buildStart (file:///D:/Projects/JavaScript/vue-plugin-project/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-cff57044.js:40995:13)
    at async file:///D:/Projects/JavaScript/vue-plugin-project/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-cff57044.js:62263:13       
    at async httpServer.listen (file:///D:/Projects/JavaScript/vue-plugin-project/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-cff57044.js:62278:17)

Then I found in https://github.com/aklinker1/vite-plugin-web-extension/tree/main/packages/demo-vue has already v2 demo, I also try to run but still got the same error.

Add svelte to the starter template

Hello!
I've been looking for a good cross-browser extension template that uses Vite and TS, and this seems to be the most complete out there.

Summary

It would be nice to have a svelte option for the starter template.

Alternatives

I've added it manually and it works, but would be nice to support it out of the box.


I could make a PR for this, if welcome.

Failed to resolve module from public directory

Overview

V2+ only. For the vue templates, when I tried to reference an image like so, the build failed:

<img src="/icon-with-shadow.svg">

Screen Shot 2023-03-03 at 5 11 24 PM

Since internally, the public directory is disabled for the HTML and script builds, if a plugin relies on it to resolve root level modules, like the vue plugin does for loading modules at a given src, the build can fail.

The solution in this case is easy, use a string literally instead, and it won't be treated as a module:

<img :src="'/icon-with-shadow.svg'">

But you shouldn't have to do that. Child builds should be able to resolve modules in the public directory.

Potentially, we could enable the public directory for child builds. It would result in the files being copied multiple times, but would be a simple solution.

Steps to Reproduce

pnpm create test -t vue-ts
cd test
# Update pages/Popup.vue with <img src="/icon-with-shadow.svg">
pnpm dev

Changes

  • Enable the public directory for all builds
  • Simplify changes to vue starter templates

Images don't load in dev mode

Summary

When running dev mode with vite dev, images don't show up correctly in HTML files. The src attributes need to point to http://localhost:5137/path/to/image, not just /path/to/image. Without the localhost:5137, it's looking for files from the root of the extension, not against the dev server which the URLs are formatted as.

This is only a problem if you have set the vite root to a custom directory.

Environment

  System:
    OS: macOS 12.5
    CPU: (8) arm64 Apple M1 Pro
    Memory: 4.52 GB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.17.0 - ~/.asdf/installs/nodejs/lts/bin/node
    Yarn: 1.22.19 - ~/.asdf/installs/nodejs/lts/.npm/bin/yarn
    npm: 8.15.0 - ~/.asdf/plugins/nodejs/shims/npm
  Browsers:
    Chrome: 110.0.5481.177
    Firefox Developer Edition: 111.0
    Safari: 15.6
  npmPackages:
    vite: 3.1.2 => 3.1.2
    vite-plugin-web-extension: workspace:* => 2.0.2

React Fast Refresh is broken

Summary

I created a simple project from pnpm create vite-plugin-web-extension, and chose react-ts template, and the popup page doesn't work, after right-clicking to inspect the popup, the console shows an error:

Popup.tsx:3 Uncaught Error: React refresh preamble was not loaded. Something is wrong.
    at Popup.tsx:3:33

In Popup.tsx:3:33:

if (!window.$RefreshReg$)
    throw new Error("React refresh preamble was not loaded. Something is wrong.");

That mean window.$RefreshReg$ is missing.

CleanShot 2023-03-12 at 16 30 03@2x

CleanShot 2023-03-12 at 16 31 26@2x

When I open http://localhost:5173/src/popup.html directly in the browser, anything works well.

After diving deep, I found their HTML file has some differences:
In dist/src/popup.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="http://localhost:5173/src/popup.css">
    <title>Popup</title>
  <script src="http://localhost:5173/@vite/client" type="module"></script>  <script type="module" crossorigin src="/src/popup.js"></script>
</head>

  <body></body>

  <script type="module" src="http://localhost:5173/src/pages/Popup.tsx"></script>
</html>

In http://localhost:5173/src/popup.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script type="module">import { injectIntoGlobalHook } from "/@react-refresh";
injectIntoGlobalHook(window);
window.$RefreshReg$ = () => {};
window.$RefreshSig$ = () => (type) => type;</script>

    <script type="module" src="/@vite/client"></script>

    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="./popup.css" />
    <title>Popup</title>
  </head>

  <body></body>

  <script type="module" src="./pages/Popup.tsx"></script>
</html>

Obviously, this part is missing:

<script type="module">import { injectIntoGlobalHook } from "/@react-refresh";
injectIntoGlobalHook(window);
window.$RefreshReg$ = () => {};
window.$RefreshSig$ = () => (type) => type;</script>

That's why it not working in the browser extension.

Reproduction

https://github.com/vimcaw/vite-plugin-web-extension-bug-reproduction

Environment

  System:
    OS: macOS 13.2.1
    CPU: (8) arm64 Apple M1
    Memory: 61.09 MB / 8.00 GB
    Shell: 3.5.0 - /usr/local/bin/fish
  Binaries:
    Node: 19.7.0 - /opt/homebrew/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 9.5.0 - /opt/homebrew/bin/npm
  Browsers:
    Chrome: 111.0.5563.64
    Safari: 16.3
  npmPackages:
    vite: ^4.1.4 => 4.1.4 
    vite-plugin-web-extension: ^3.0.0 => 3.0.0

Generated an empty chunk: "popup", overwrites a previously emitted file of the same name

Hello. This package has been a huge help! However, I am running into an issue right near what I presume is the finish line in getting my extension migrated to vite. Unfortunately, I am having a very difficult time figuring out where the root problem is at.

TL;DR; popup.popup.html is getting built twice. Once at popup.html with expected contents, and once at popup/popup.html with "empty" / placeholder contents. If I flatten the folder structure, the latter / useless one wins.

Directory structure:

- popup/popup.html
- manifest.json

manifest.json

{ 
  "manifest_version": 3,
  "action": {
    "default_popup": "popup/popup.html"
  }
}

(essentially the same as this e2e test... which works for me... but I still cannot get my plugin to):

it("should build a simple popup extension", () =>
expectBuildToMatchSnapshot(
baseConfig({
browser_action: {
default_popup: "page1.html",
},
}),
baseOutputs(["dist/page1.html"])
));

build log

[vite-plugin-web-extension] Building HTML Pages in Multi-Page Mode
✓ 1 modules transformed.
Generated an empty chunk: "popup/popup"
../dist/other/icon.xcf       43.14 KiB
../dist/other/icon_128.png   9.81 KiB
../dist/other/icon_48.png    2.52 KiB
../dist/popup.html           0.23 KiB
../dist/popup/popup.html     0.03 KiB

Note that there are two output popup.html files... one with my actual contents (dist/popup.html) and another (dist/popup/popup.html) with contents: export default "/popup.html".

Unfortunately, the path pointed to by the extension is popup/popup.html, so my extension is not usable. No foray through several iterations of additionalInputs, different file structures, verbose logging, rollup options, etc. have been helpful. Further, if I change or flatten the folder structure, it seems that the blank popup.html is generated last / wins with a message "popup.html" overwrites a previously emitted file of the same name.

I have tried different versions of vite in the 3.0 line, and it seems to affect both 3.1 and 3.2. I have seen some related-ish looking activity on vite lately though - maybe I will try the e2e tests with newer versions of deps.

vitejs/vite#9928

Any ideas how to keep debugging / resolve this "double build" issue?

Sass for content scripts does not get processed

Hi, I'm trying to convert a Parcel-based WebExtension to Vite and I have a small question.

I have a content scripts section that looks like this:

"content_scripts": [
  {
    "matches": [
      "*://tildes.net/*"
    ],
    "run_at": "document_end",
    "css": [
      "scss/scripts.scss"
    ],
    "js": [
      "content-scripts.ts"
    ]
  }
],

And while the TS gets built as expected, the Sass is copied over as-is which wasn't what I expected. I figured out I can change the CSS definition to "generated:style.css" and then add import './scss/scripts.scss'; to my content-scripts.ts file so the Sass does get processed, but it's not exactly ideal.

So my question is, is this how I should be doing it or is there a better way?

[Feature request] Define dimensions of autoLaunch window

I'd like to control the size of the Chrome window that automatically launches when running vite build --watch

I only need a small window to test my extension, but it currently launches as a large window - meaning I have to resize it every time I run the command

Is there already a workaround for this?

Duplicate content in the manifest.json

Use of require() to load manifest file for manipulation, as shown in doc results in duplicated content of manifest.json file under default property as require and it it (at least for some confutations?).

Consider using require("...").default in the samples or even JSON.parse(fs.readFileSync("...").toString()).

Both option worked for me.

Scripts missing when rebuilding HTML on Watch Mode

When using vite build --watch, making changes to HTML files (whether vanilla HTML or via frameworks like Vue) will trigger a rebuild, but only HTML pages are rebuilt, causing all content and background scripts to be missing from the output folder until the command is run again.

This can be reproduced on both the vanilla and vue demos included in the repo.

Vite 2.6.0 uses esbuild by default

I'll start by thanking you for making this, it's a great plugin!

When building without specifying build.minify = 'terser' I get the following warning:

build.terserOptions is specified but build.minify is not set to use Terser. Note Vite now defaults to use esbuild for minification. If you still prefer Terser, set build.minify to "terser".

So the readme should probably mention that you should set build.minify to 'terser'.

Sidenote: I've found that esbuild does a much better job at minifying my code (about 2x smaller), not sure if this is because it mangles names or if it's just better.
I think it's worth figuring out how to support esbuild in this plugin.

aklinker1

import path from "path";
import { defineConfig } from "vite";
import browserExtension, { readJsonFile } from "vite-plugin-web-extension";

function root(...paths: string[]): string {
return path.resolve(__dirname, ...paths);
}

export default defineConfig({
root: "src",
build: {
outDir: root("dist"),
emptyOutDir: true,
},
plugins: [
browserExtension({
manifest: root("src/manifest.json"),
assets: "assets",
additionalInputs: ["content-scripts/script1/index.ts"],
watchFilePaths: [root("src/manifest.json")],
verbose: true,
browser: process.env.TARGET || "chrome",
}),
],
});

Publish a `create-vite-plugin-web-extension` package to bootstrap projects.

I'd like to be able to have a one-liner for configuring a new project:

npm  create vite-plugin-web-extension [template]
yarn create vite-plugin-web-extension [template]
pnpm create vite-plugin-web-extension [template]

There can be a couple of different templates to get started with:

Javascript Typescript
vanilla vanilla-ts
vue vue-ts
react react-ts

Custom JSON validation formats for manifest

Right now, some fields are not validated, any fields that reference these types just accept any string:

  • match-pattern
  • glob-pattern
  • content-security-policy
  • mime-type
  • permission

Here's the schema for V3: https://json.schemastore.org/chrome-manifest

They should perform actual validation checks, not just checking if they're a string.

Here's where we're setting these formats to accept any string.

// Some formats are not listed in the schema, so accept anything when they are seen.
ajv.addFormat("permission", /.*/);
ajv.addFormat("content-security-policy", /.*/);
ajv.addFormat("glob-pattern", /.*/);
ajv.addFormat("match-pattern", /.*/);
ajv.addFormat("mime-type", /.*/);

Vite 4 Support

Discovered while working on v2, Vite 4 does not work with the plugin. Once V2 is merged, look into supporting Vite 4.

Create React Starter Kit Templates

I'd love some help gettin the React templates setup.

I ran into issues with Vite 4 and both the react plugins (@vitejs/plugin-react and @vitejs/plugin-react-swc). See #58 (comment) for more details. I don't have much experience with Vite and React, so maybe I'm just doing something weird? Here's the farthest I got:

https://github.com/aklinker1/vite-plugin-web-extension/tree/07f2eec9aa7b666fad6a3484a9c711812cffbba8/packages/create-vite-plugin-web-extension/templates/react-js

Essentially, I just ran pnpm vite create -t react-js react-js inside packages/create-vite-plugin-web-extension/templates to create a boilerplate vite + react project, then brought over and merged the files/config from the js template.

I'd prefer the template uses SWC, but if we can get it working using the regular plugin, that's fine too.

We need two React templates: react-js and react-ts.

[web-extension:manifest] Entrypoint output for src/popup.html (src/popup.html) not found

Hello,

I'm getting this error out of the sudden

[web-extension:manifest] Entrypoint output for src/popup.html (src/popup.html) not found

and the browser does not start anymore.

does anyone have an idea what is going wrong?

{
  "{{chrome}}.manifest_version": 3,
  "{{firefox}}.manifest_version": 2,
  "icons": {
    "16": "icon/16.png",
    "32": "icon/32.png",
    "48": "icon/48.png",
    "96": "icon/96.png",
    "128": "icon/128.png"
  },
  "{{chrome}}.action": {
    "default_popup": "src/popup.html"
  },
  "{{firefox}}.browser_action": {
    "default_popup": "src/popup.html"
  },
  "background": {
    "service_worker": "src/background.ts"
  },
  "options_page": "src/options.html",
  "permissions": [
    "alarms",
    "storage",
    "identity",
    "activeTab",
    "contextMenus",
    "videoCapture",
    "desktopCapture",
    "notifications",
    "syncFileSystem",
    "{{firefox}}.<all_urls>"
  ]
}

image

image

Extension double reloads in watch mode

When an extension with both HTML pages and scripts is ran in watch mode, if the scripts take more than about half a second to bundle, the extension will reload twice. First because the html pages were output (and web-ext reloads on file change by default), and second because we reload after the scripts are output:

webExtRunner.reloadAllExtensions();

It should only reload once after everything has finished updating.

When compiling `additionalInputs` only the css styles from the last in the `additionalInputs` array is included

Env

Node: 16.17.0
Yarn: 1.22.11
Vue: 3.2.40
Vite: 3.1.4
Vite-plugin-web-extension: 1.4.4

Issue

I have 3 seperate Vue app's/instances, arranged like this:

src/
  assets/
    ...
  auth/
    App.vue
    index.html
    main.ts
  injector/
    App.vue
    index.html
    main.ts
  main/
    App.vue
    index.html
    main.ts
  manifest.json
package.json
tsconfig.json
vite.config.ts

But not all css from the vue components are included, it seems like the only css that is included comes from the last in the additionalInputs array of the vite-plugin-web-extension

vite.config.ts

export default defineConfig({
  root: "src",
  resolve: {
    alias: {
      "@": join(__dirname, "src"),
      "@/injector": join(__dirname, "src/injector"),
      "@/auth": join(__dirname, "src/auth"),
      "@/main": join(__dirname, "src/main"),
    },
  },
  build: {
    outDir: resolve(__dirname, "dist"),
    emptyOutDir: true,
    sourcemap: !!process.env.SOURCEMAP,
    rollupOptions: {
      input: {
        auth: new URL("./src/auth/index.html", import.meta.url).pathname,
        main: new URL("./src/main/index.html", import.meta.url).pathname,
        injector: new URL("./src/injector/index.html", import.meta.url).pathname,
      },
      output: {
        sanitizeFileName,
      },
    },
  },
  plugins: [
    vue(),
    webExtension({
      manifest: "src/manifest.json",
      assets: "assets",
      additionalInputs: ["main/index.html", "injector/index.html"],
    }),
  ],
});

Support `import` in content scripts

Currently, imports don't work in content scripts and background scripts (unless type: "module" for background service_worker)

Seems like an easy fix would be to default manualChunks: undefined in build.rollupOptions.outputs

Build fails when output folder does not exist

Since 1.0.5, build will fail whenever the output folder does not exist. Here's the output when building the vanilla demo:

[vite-plugin-web-extension] Building for browser: chrome
[vite-plugin-web-extension] Building with vite config: {
  "root": "src",
  "build": {
    "outDir": "/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/dist",
    "emptyOutDir": false,
    "terserOptions": {
      "mangle": false
    },
    "rollupOptions": {
      "output": {
        "entryFileNames": "[name].js",
        "chunkFileNames": "[name].js",
        "assetFileNames": "[name].[ext]"
      },
      "input": "/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/src/index.html"
    }
  },
  "plugins": [
    {
      "name": "vite-plugin-web-extension"
    }
  ]
}
[vite-plugin-web-extension] Skipping script builds because of error Error: ENOENT: no such file or directory, stat '/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/dist'
    at Object.statSync (node:fs:1536:3)
    at __node_internal_ (node:internal/fs/utils:793:8)
    at rmdirSync (node:fs:1156:15)
    at Object.buildStart (/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/node_modules/vite-plugin-web-extension/dist/index.js:403:35)
    at /home/rubin/repos/vite-plugin-web-extension/demos/vanilla/node_modules/rollup/dist/shared/rollup.js:22815:37
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Promise.all (index 4)
    at rollupInternal (/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/node_modules/rollup/dist/shared/rollup.js:23557:9)
    at doBuild (/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/node_modules/vite/src/node/build.ts:585:20)
    at build (/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/node_modules/vite/src/node/build.ts:395:12) {
  errno: -2,
  syscall: 'stat',
  code: 'PLUGIN_ERROR',
  path: '/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/dist',
  pluginCode: 'ENOENT',
  plugin: 'vite-plugin-web-extension',
  hook: 'buildStart'
}
✓ 0 modules transformed.
[vite-plugin-web-extension] ENOENT: no such file or directory, stat '/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/dist'
error during build:
Error: ENOENT: no such file or directory, stat '/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/dist'
    at Object.statSync (node:fs:1536:3)
    at __node_internal_ (node:internal/fs/utils:793:8)
    at rmdirSync (node:fs:1156:15)
    at Object.buildStart (/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/node_modules/vite-plugin-web-extension/dist/index.js:403:35)
    at /home/rubin/repos/vite-plugin-web-extension/demos/vanilla/node_modules/rollup/dist/shared/rollup.js:22815:37
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Promise.all (index 4)
    at rollupInternal (/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/node_modules/rollup/dist/shared/rollup.js:23557:9)
    at doBuild (/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/node_modules/vite/src/node/build.ts:585:20)
    at build (/home/rubin/repos/vite-plugin-web-extension/demos/vanilla/node_modules/vite/src/node/build.ts:395:12)

This wasn't the case on 1.0.4. Not particularly detrimental, but it is slightly inconvenient since with emptyOutDir the output folder is removed if the build is cancelled partway.

HMR

Hi,

I see that there's a problem with manifest v3 and this branch: #14

Nonetheless, maybe this could get merged in with just a way to turn it off for v3 for now? And once they fix the underlying bug in chrome it can be fully turned on for v3?

`dev` script renames css into html files

When running npm run dev, the css files will be renamed as html files in the dist folder.
With npm run build there is no problem, all files are compiled correctly.

e.g.:
src/styles.css -> dist/styles.html

When renaming the dist/styles.html to dist/styles.css, everything works as expected.

manifest.json:

{
  "{{chrome}}.manifest_version": 3,
  "{{firefox}}.manifest_version": 2,
  "name": "My extension",
  "version": "0.0.0",
  "description": "My extension",
  "icons": {
    "16": "assets/icon-16.png",
    "32": "assets/icon-32.png",
    "48": "assets/icon-48.png",
    "128": "assets/icon-128.png"
  },
  "chrome_url_overrides": {
    "newtab": "index.html"
  },
  "permissions": ["tabs"]
}

vite.config.ts:

import path from "path";
import { defineConfig } from "vite";
import browserExtension from "vite-plugin-web-extension";

function root(...paths: string[]): string {
  return path.resolve(__dirname, ...paths);
}

export default defineConfig({
  root: "src",
  build: {
    outDir: root("dist"),
    emptyOutDir: true,
  },
  plugins: [
    browserExtension({
      manifest: root("src/manifest.json"),
      assets: "assets",
      additionalInputs: [
        "index.html",
        "styles.css",
        "variables.css",
        "scripts.js",
      ],
      watchFilePaths: [root("src/manifest.json")],
      verbose: false,
      browser: process.env.TARGET || "firefox",
    }),
  ],
});

My files:

src/
  assets/
    logo16.png
    ...
  index.html
  manifest.json
  script.js
  styles.css
  variables.css
package.json
tsconfig.json
vite.config.ts

Hopefully this is enough info, if you need a demo, let me know :)

Loving the plugin so far btw, thank you for creating this! 🔥

Clearer manifest validation error messages

I used vite-plugin-web-extension to build an extension. When I ran vite (in production mode), I got the following error:

no error msg given

The manifest is invalid as there is no version field specified. I investigated the bundle for vite-plugin-web-extension,

debug
err object
plugin code

It seems like the plugin is filtering for non-empty instancePath when showing errors which is why the error is not showing. Can you fix the error logging to handle this scenario. Something like Manifest must have required property 'version' would be a nice error message.

when building chrome extension, there is not popup.js in dist

Hi, i have a problem.
I want to use popup in my extension. I created popup.html and added scrip tag to popup.html but my code in popup.js did not work. I checked dist directory. I didnt see popup.js
why i don't see popup.js in dist ?
How can i solve this problem ?

I use v1.4.8

popup.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    Chrome Extension
    <button type="button" id="closeButton">X</button>
    <script src="./popup.js"></script>
  </body>
</html>

popup.js

console.log('tes1t');

console.log('test popup');

function closePopup() {
  // window.close();
  alert('hello');
}

document.addEventListener('DOMContentLoaded', () => {
  document.querySelector('.closeButton').on('click', () => {
    closePopup();
  });
});

manifest.json

{
  "manifest_version": 3,
  "name": "Resmo Chrome Extension",
  "$schema": "https://json.schemastore.org/chrome-manifest.json",
  "description": "",
  "version": "1.0",
  "background": {
    "service_worker": "only_background.js"
  },
  "icons": {
    "16": "public/images/icon-16.png",
    "32": "public/images/icon-32.png",
    "48": "public/images/icon-48.png",
    "128": "public/images/icon-128.png"
  },
  "action": {
    "default_icon": {
      "16": "public/images/icon-16.png",
      "32": "public/images/icon-32.png"
    },
    "default_title": "Click to view a popup",
    "default_popup": "popup.html"
  },
  "permissions": [
    "alarms",
    "identity",
    "identity.email",
    "scripting",
    "cookies",
    "storage",
    "tabs",
    "webRequest",
    "declarativeNetRequest",
    "declarativeWebRequest",
    "*://*/*"
  ],
  "host_permissions": [
    "http://*/*",
    "https://*/*"
  ],
  "content_scripts": [
    {
      "matches": [
        "http://*/*",
        "https://*/*"
      ],
      "js": [
        "contentScript.js"
      ]
    }
  ],
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self'"
  }
}

dist
image

Vite build sometimes doesn't trigger when saving a file.

Hey!
For some reason, sometimes when I save a file that's part of the extension, it doesn't trigger a build in vite. The only workaround I've found is to then force save another file.
I think this happens only for files set as "additionalInputs". For example right now I have a file that's eventually imported from a file that's in that list, and it refuses to build. But if I go one level up, it for some reason works fine.
Is this known, or is there a fix for this?

This is my project:
https://github.com/gorbit99/wics-extension

Manifest file is missing or unreadable

kondr E:\..\web-ext-test git: master ≢ +2 ~0 -0 ! ❯❯❯ yarn create vite-plugin-web-extension
yarn create v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Installed "[email protected]" with binaries:
      - create-vite-plugin-web-extension
√ Project Name ... aaaa
√ Template » vue-ts
√ Package Manager » Yarn

✔ Prepare Project Directory
✔ Create Project
✔ Install Dependencies

All done! To start the extension, run:

  cd aaaa
  yarn dev

Done in 230.14s.

And this i see after yarn dev :

Failed to load extension from C:\Program Files (x86)\Google\Chrome\Application\109.0.5414.120\dist
Manifest file is missing or unreadable 

image

[Bug Report] generate config `build.lib.formats: ["umd"]` broken vite `import.meta.glob` function

Vite provide a Glob Import feature , however when use this feature function import.meta.glob in script, the build will fail and with this output:

Invalid value "umd" for option "output.format" - UMD and IIFE output formats are not supported for code-splitting builds.
error during build:
Error: Invalid value "umd" for option "output.format" - UMD and IIFE output formats are not supported for code-splitting builds.
    at error (D:\path-to-project\node_modules\.pnpm\[email protected]\node_modules\rollup\dist\shared\rollup.js:159:30)
    at validateOptionsForMultiChunkOutput (D:\path-to-project\node_modules\.pnpm\[email protected]\node_modules\rollup\dist\shared\rollup.js:16134:16)
    at Bundle.generate (D:\path-to-project\node_modules\.pnpm\[email protected]\node_modules\rollup\dist\shared\rollup.js:15968:17)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at handleGenerateWrite (D:\path-to-project\node_modules\.pnpm\[email protected]\node_modules\rollup\dist\shared\rollup.js:23612:23)
    at doBuild (D:\path-to-project\node_modules\.pnpm\[email protected]\node_modules\vite\dist\node\chunks\dep-ff3ab196.js:39134:26)
    at Object.build (D:\path-to-project\node_modules\.pnpm\[email protected]\node_modules\vite\dist\node\chunks\dep-ff3ab196.js:38959:16)
    at buildScript (D:\path-to-project\node_modules\.pnpm\[email protected][email protected]\node_modules\vite-plugin-web-extension\dist\index.js:90:3)
    at Object.closeBundle (D:\path-to-project\node_modules\.pnpm\[email protected][email protected]\node_modules\vite-plugin-web-extension\dist\index.js:524:11)
    at async Promise.all (index 0)
Waiting for the debugger to disconnect...
 ELIFECYCLE  Command failed with exit code 1.

It's ok when use function import.meta.globEager since this function will not splitting code.


Steps to reproduce

  1. clone the last bugreport project https://github.com/Rhilip/bugreport-vite-plugin-web-extension-watchbuild
  2. create two or more files like src/background/module/1.ts and src/background/module/2.ts , each may have simple code like console.log("hello world");
  3. in src/background/index.ts , add line console.log(import.meta.glob("./module/*.ts"));
  4. run command pnpm run build and see error code, no dist/background folder will be built.

Try to fix


  • I also find a related vite issue vitejs/vite#2982 , it pointed out that we can add build.rollupOptions.output.inlineDynamicImports: true to avoid this problem, however it still not work if we change project vite.config.ts file, since build-script always use a empty rollupOptions.

Error: You must supply options.input to rollup

Hi,

I am using vite-plugin-web-extension v1. Firstly i removed this line"default_popup": "popup.html from manifest.json then i run build command and Vite threw error.
Error: You must supply options.input to rollup

if i add popup.html again to manifest.json. There is no problem.

i dont want to use popup. How to remove it ?

how do i fix this problem ?

Error log
image

My manifest

{
  "manifest_version": 3,
  "name": "Resmo Chrome Extension",
  "$schema": "https://json.schemastore.org/chrome-manifest.json",
  "description": "",
  "version": "1.0",
  "background": {
    "service_worker": "only_background.js"
  },
  "icons": {
    "16": "public/images/icon-16.png",
    "32": "public/images/icon-32.png",
    "48": "public/images/icon-48.png",
    "128": "public/images/icon-128.png"
  },
  "action": {
    "default_icon": {
      "16": "public/images/icon-16.png",
      "32": "public/images/icon-32.png"
    },
    "default_title": "Click to view a popup"
  },
  "permissions": [
    "alarms",
    "identity",
    "identity.email",
    "scripting",
    "storage",
    "tabs",
    "webRequest",
    "declarativeNetRequest",
    "declarativeWebRequest",
    "*://*/*"
  ],
  "host_permissions": [
    "http://*/*",
    "https://*/*"
  ],
  "content_scripts": [
    {
      "matches": [
        "http://*/*",
        "https://*/*"
      ],
      "js": [
        "contentScript.js"
      ]
    }
  ],
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self'"
  }
}

context method emitFile() is not supported in serve mode. This plugin is likely not vite-compatible.

Thanks for this great Vite plugin. I'm currently using v2.0.0-alpha5 with Vite v3.1.8
It went well for building packages but in the dev mode, there's a warning in the console at the end of the process like this:
image

[plugin:web-extension:manifest] context method emitFile() is not supported in serve mode. This plugin is likely not vite-compatible.

And the browser (web-ext) wasn't started.

Is this a bug or did I configure something wrong?

Getting infinite loop and 'Invalid substitution ... for placeholder "[name]" in "output.entryFilesNames" pattern' error

I'm trying to migrate an existing extension to vite using this plugin.

However, when I run vite build, I get the following output

Full output

vite v4.0.1 building for production...
[vite-plugin-web-extension] Building for browser: chrome
[vite-plugin-web-extension] Building with vite config: {
  build: {
    outDir: '$PROJECT_DIR/dist',
    emptyOutDir: false,
    rollupOptions: { output: [Object] }
  },
  plugins: [
    [ [Object], [Object], false ],
    {
      name: 'vite-plugin-web-extension',
      config: [Function: config],
      configResolved: [Function: configResolved],
      buildStart: [AsyncFunction: buildStart],
      buildEnd: [AsyncFunction: buildEnd],
      closeBundle: [AsyncFunction: closeBundle]
    }
  ],
  resolve: {
    alias: {
      '~': '$PROJECT_DIR',
      src: '$PROJECT_DIR/src',
      app: '$PROJECT_DIR/src/app',
      shared: '$PROJECT_DIR/src/shared'
    },
    dedupe: [ 'react', 'react-dom' ]
  },
  optimizeDeps: { force: undefined },
  esbuild: {
    logOverride: { 'this-is-undefined-in-esm': 'silent' },
    jsx: 'transform',
    jsxImportSource: undefined,
    jsxSideEffects: false
  },
  server: { port: 3000, hmr: { host: 'localhost' } }
}
[vite-plugin-web-extension] Manifest before browser transform: {
  "name": "__MSG_appName__",
  "version": "1.4.1",
  "manifest_version": 2,
  "description": "__MSG_appDescription__",
  "icons": {
    "16": "icons/icon_16.png",
    "48": "icons/icon_48.png",
    "128": "icons/icon_128.png"
  },
  "minimum_chrome_version": "68.0.0",
  "default_locale": "en",
  "background": {
    "service_worker": "src/background/sw.js"
  },
  "browser_action": {
    "default_icon": {
      "16": "icons/icon_16.png",
      "48": "icons/icon_48.png",
      "128": "icons/icon_128.png"
    },
    "default_title": "__MSG_appName__"
  },
  "content_scripts": [
    {
      "matches": [
        "http://*/*",
        "https://*/*"
      ],
      "exclude_matches": [
        "http://*/*.xml",
        "https://*/*.xml"
      ],
      "js": [
        "src/content/content.js"
      ],
      "run_at": "document_start"
    }
  ],
  "permissions": [
    "cookies",
    "debugger",
    "storage",
    "webNavigation",
    "webRequest",
    "webRequestBlocking",
    "http://*/*",
    "https://*/*"
  ],
  "web_accessible_resources": [
    "src/app/index.html",
    "src/login/login.html"
  ],
  "content_security_policy": "script-src 'self'; object-src 'self'"
}
[vite-plugin-web-extension] Manifest after browser transform: {
  "name": "__MSG_appName__",
  "version": "1.4.1",
  "manifest_version": 2,
  "description": "__MSG_appDescription__",
  "icons": {
    "16": "icons/icon_16.png",
    "48": "icons/icon_48.png",
    "128": "icons/icon_128.png"
  },
  "minimum_chrome_version": "68.0.0",
  "default_locale": "en",
  "background": {
    "service_worker": "src/background/sw.js"
  },
  "browser_action": {
    "default_icon": {
      "16": "icons/icon_16.png",
      "48": "icons/icon_48.png",
      "128": "icons/icon_128.png"
    },
    "default_title": "__MSG_appName__"
  },
  "content_scripts": [
    {
      "matches": [
        "http://*/*",
        "https://*/*"
      ],
      "exclude_matches": [
        "http://*/*.xml",
        "https://*/*.xml"
      ],
      "js": [
        "src/content/content.js"
      ],
      "run_at": "document_start"
    }
  ],
  "permissions": [
    "cookies",
    "debugger",
    "storage",
    "webNavigation",
    "webRequest",
    "webRequestBlocking",
    "http://*/*",
    "https://*/*"
  ],
  "web_accessible_resources": [
    "src/app/index.html",
    "src/login/login.html"
  ],
  "content_security_policy": "script-src 'self'; object-src 'self'"
}
[vite-plugin-web-extension] Searching for assets in: icons
[vite-plugin-web-extension]   > icons/icon_128.png
[vite-plugin-web-extension]   > icons/icon_16.png
[vite-plugin-web-extension]   > icons/icon_48.png
[vite-plugin-web-extension] Final manifest: {
  "name": "__MSG_appName__",
  "version": "1.4.1",
  "manifest_version": 2,
  "description": "__MSG_appDescription__",
  "icons": {
    "16": "icons/icon_16.png",
    "48": "icons/icon_48.png",
    "128": "icons/icon_128.png"
  },
  "minimum_chrome_version": "68.0.0",
  "default_locale": "en",
  "background": {
    "service_worker": "src/background/sw.js"
  },
  "browser_action": {
    "default_icon": {
      "16": "icons/icon_16.png",
      "48": "icons/icon_48.png",
      "128": "icons/icon_128.png"
    },
    "default_title": "__MSG_appName__"
  },
  "content_scripts": [
    {
      "matches": [
        "http://*/*",
        "https://*/*"
      ],
      "exclude_matches": [
        "http://*/*.xml",
        "https://*/*.xml"
      ],
      "js": [
        "src/content/content.js"
      ],
      "run_at": "document_start"
    }
  ],
  "permissions": [
    "cookies",
    "debugger",
    "storage",
    "webNavigation",
    "webRequest",
    "webRequestBlocking",
    "http://*/*",
    "https://*/*"
  ],
  "web_accessible_resources": [
    "src/app/index.html",
    "src/login/login.html"
  ],
  "content_security_policy": "script-src 'self'; object-src 'self'"
}
[vite-plugin-web-extension] Final rollup inputs: {
  '$PROJECT_DIR/src/app/index': '$PROJECT_DIR/src/app/index.html',
  '$PROJECT_DIR/src/login/login': '$PROJECT_DIR/src/login/login.html'
}

[vite-plugin-web-extension]
Building HTML Pages in Multi-Page Mode:
• src/app/index.html
• src/login/login.html
Building in Lib Mode:
• src/background/sw.js
• src/content/content.js

[vite-plugin-web-extension] Building HTML Pages in Multi-Page Mode
transforming (416) src/app/components/EventsView/Timeline.js[BABEL] Note: The code generator has deoptimised the styling of $PROJECT_DIR/src/shared/metadata.js as it exceeds the max of 500KB.
transforming (4484) node_modules/htmlparser2/node_modules/dom-serializer/node_modUse of eval in "node_modules/store/plugins/lib/json2.js" is strongly discouraged as it poses security risks and may cause issues with minification.
✓ 4532 modules transformed.
Invalid substitution "$PROJECT_DIR/src/app/index" for placeholder "[name]" in "output.entryFileNames" pattern, can be neither absolute nor relative path.

Error

Invalid substitution "$PROJECT_DIR/src/app/index" for placeholder "[name]" in "output.entryFileNames" pattern, can be neither absolute nor relative path.

After that error is printed, the build process starts over again and loops forever until it runs out of heap space.

How can I resolve this error? Any guidance is greatly appreciated.


vite.config.ts

/* eslint-disable import/no-extraneous-dependencies */
import path from "node:path";
import webExtension from "vite-plugin-web-extension";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
  build: {
    outDir: path.resolve(__dirname, "dist"),
    emptyOutDir: true
  },
  plugins: [
    react({
      babel: {
        // babelrc: true
        plugins: [
          [
            "babel-plugin-jsx-pragmatic",
            { export: "jsx", module: "@emotion/core", import: "___EmotionJSX" }
          ],
          [
            "@babel/plugin-transform-react-jsx",
            { pragma: "___EmotionJSX", pragmaFrag: "React.Fragment" }
          ],
          ["emotion"]
        ]
      },
      jsxRuntime: "classic"
    }),
    webExtension({
      manifest: "manifest.json",
      assets: "icons",
      verbose: true,
      additionalInputs: [
        path.resolve(__dirname, "src/app/index.html"),
        path.resolve(__dirname, "src/login/login.html")
      ]
    })
  ],
  resolve: {
    alias: {
      "~": path.resolve(__dirname),
      src: path.resolve(__dirname, "src"),
      app: path.resolve(__dirname, "src/app"),
      shared: path.resolve(__dirname, "src/shared")
    }
  }
});
Project structure

.
├── README-FIREFOX.md
├── README.md
├── _locales
│   └── en
│       └── messages.json
├── extensionArchitecture.png
├── icons
│   ├── icon_128.png
│   ├── icon_16.png
│   └── icon_48.png
├── jest-puppeteer.config.js
├── jsconfig.json
├── karma.conf.js
├── license.txt
├── manifest.chrome.json
├── manifest.firefox.json
├── manifest.json
├── metadata.xlsx
├── node_modules/
├── package-lock.json
├── package.json
├── scripts/
├── src/
│   ├── app/
│   │   ├── App.js
│   │   ├── api/
│   │   ├── components/
│   │   ├── constants.js
│   │   ├── contexts/
│   │   ├── controllers/
│   │   ├── globalStyles.js
│   │   ├── hotReloadInDev.js
│   │   ├── images/
│   │   ├── index.html
│   │   ├── index.js
│   │   ├── networkDetection/
│   │   ├── state/
│   │   ├── staticCss/
│   │   ├── store.js
│   │   └── utils/
│   ├── background/
│   │   └── sw.js
│   ├── content/
│   │   ├── content.js
│   │   ├── embedCodeInjection.js
│   │   ├── injectedScripts/
│   │   ├── persistValidationToken.js
│   │   ├── scriptTagDetection.js
│   │   └── storage/
│   ├── login/
│   │   ├── LoginApp.js
│   │   ├── ims.js
│   │   ├── login.html
│   │   ├── loginPopup.js
│   │   └── loginStore.js
│   └── shared/
│       ├── appWindow.js
│       ├── browserApi
│       ├── constants.js
│       ├── errorReporter.js
│       ├── metadata.js
│       ├── queue.js
│       └── util
├── test.html
├── tests/
│   ├── configuration/
│   │   └── preprocess.js
│   ├── integration/
│   ├── secrets.js
│   ├── unit/
│   │   ├── app/
│   │   ├── content/
│   │   ├── helpers/
│   │   └── shared/
│   └── utils.js
└── vite.config.ts

3646 directories, 8907 files

Support UI-less extensions

Right now, you have to have an HTML file to for the plugin to build, otherwise it will complain about not having any entrypoints.

I'd like to add support for these kinds of extensions.

Content Script Reloading

With HMR, at least when using Vue inside content scripts, it's possible to save a .vue file that is used by both an extension page and a content script. When doing so, the page will reload immediately but when the content script finishes building, it will reload the entire extension, closing the extension page and slowing development down. You're then forced to reopen the extension page.

This can also happen with Vue when the file is not used by content scripts, but is in the same folder. Which sucks, really slowing things down.

So instead of reloading the entire extension when a content script changes, we should be able to reload individual content scripts from the background instead.

This would have the added benefit of not having to refresh the page to run the new content script code.

The idea here is to use the scripting APIs to register, unregister, and re-register the content scripts programmatically from the background instead of listing them in the manifest.

In addition to that logic, we will also need to stop the content scripts and silence the "Extension context invalidated" errors. We don't want two of the same content script running.

Cosmiconfig fails to load ES module web-ext config

Was playing around a bit with v2 and while migrating the web-ext config to web-ext-config.js, I found that Cosmiconfig can't load ES modules:

Error [ERR_REQUIRE_ESM]: require() of ES Module web-ext-config.js
from node_modules/.pnpm/[email protected]/node_modules/cosmiconfig/dist/loaders.js not supported.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.