Closed aklinker1 closed 2 months ago
Alright, I have a proof of concept using Vite's runtime API to load entrypoints: https://github.com/wxt-dev/wxt/pull/585
import.meta.glob
So this should cover all the issues people have reported.
HOWEVER... it appears the vite runtime can't import CSS modules, which is kinda important. I've asked a question about it in the vite discord, so we'll se if I get a useful response. https://discord.com/channels/804011606160703521/1236142702785990677/1236142702785990677
Alright, it was an issue on my side. Just needed to start the vite server lol. So it's working now.
I need to clean up my changes before opening a real PR. Probably won't get to it this weekend... we'll see. But I got everything working :)
Last problem to address... Module side effects.
Say you're using storage item in your content script:
// utils/storage.ts
export const isXyzEnabled = storage.defineItem(...);
// entrypoints/content.ts
import { isXyzEnabled } from '~/utils/storage';
export default defineContentScript({
// ...
async main() {
console.log(await isXyzEnabled.getValue());
}
});
In this example, storage.defineItem
actually includes side effects, like checking if the storage item needs migrated. Should a side effect like this run? I don't think so, and I can't think of reason a side effect like this should ever run. That is, unless it's related to an imported variable used in the options.
So I have a decision to make. When importing entrypoints during the build to get their config, do I...
I think... I'm gonna go with option 1, and remove the main function. For performance reasons (importing less code as project grows) as well as avoiding weird edge cases around the node environment these files are loaded into (similar to what I'm currently doing with jiti).
So I have to decide the best way to do that. Removing the main function should be simple... Use magicast or regex. To remove unused imports after that... I'm not sure how to do that. Regex again? Or use magicast to get the imports, and find/replace if they're used. Probably that. I'll just use magicast for everything if possible.
Playing around a bit, removing unused imports isn't a simple task lol. Instead, I'm just going to remove main
function via magicast, then let vite tree-shake out the modules? Not sure how the runtime API handles this... Might need to come back in the future and remove imports properly.
Released v0.18.0 with an experimental flag to enable this feature. If you use PNPM, for some reason it requires setting shamefully-hoist=true
... And there are a couple of other problems when ran outside this monorepo... So this isn't quite ready for use yet.
I don't understand why there are no obvious side effects after importing, and it doesn't work. For example, extracting the configuration file to config.json
and then using it doesn't work.
config.json
{
"list": [
{ "name": "John", "age": 30 },
{ "name": "Jane", "age": 25 },
{ "name": "Jim", "age": 40 }
]
}
background.ts
import { defineBackground } from '~/sandbox';
import config from './config.json';
const list = config.list;
export default defineBackground({
main() {
console.log(list);
},
});
@rxliuli WXT doesn't look at any files to try and decide if there are side-effects or not, it just removes all imports from the top of your entrypoints.
So instead of loading your background as is, it loads it with the following text content:
import { defineBackground } from 'wxt';
const list = config.list;
export default defineBackground({
main() {
console.log(list);
},
});
In this case, auto-imports are disabled, so of course config
is not defined, and config.list
throws an error.
Also, not sure how I didn't think of this until now, but I could use vite-node
to load the entrypoints 🤦
https://github.com/vitest-dev/vitest/tree/main/packages/vite-node#programmatic-usage
Alright, I added an experimental option to let you choose between jiti
, vite-runtime
, and vite-node
(new). Released in v0.18.9.
experimental: {
- viteRuntime: true,
+ entrypointImporter: "vite-node"
}
Gonna go through all the original issues to see if this option fixes them!
Alright, integrated entrypointImporter: "vite-node"
into GitHub Better Line Counts for real world testing, and it crashed... I had to add any modules that import webextension-polyfill
to the ssr.noExternal
vite config, and then it worked like magic:
// wxt.config.ts
vite: () => ({
plugins: [Icons({ compiler: "vue3" }), Vue()],
+ ssr: {
+ noExternal: ["@webext-core/messaging", "@webext-core/proxy-service"],
+ },
}),
You also have to do this for unit tests... I think it's time I implement something to detect these packages and add them to the ssr.noExternal
option.
That, or make everything Edit: Nope, that causes lots of logs, but it did technically work: https://github.com/wxt-dev/wxt/issues/703#issuecomment-2181663412ssr.noExternal: [/.*/]
?
I haven't received any feedback, but vite-node
is working for me, just need to add packages to ssr.noExternal
. I'm going to make the the default, and release it along with other breaking changes in v0.19.0
.
I've also confirmed that all the issues mentioned in the original description have been fixed.
Is the current configuration set to use "vite-node" by default? When I upgrade from "0.18.4" to any later version, I always encounter an error.
WXT 0.19.4 10:53:03
× Command failed after 4.019 s 10:53:07
ERROR Cannot find module '&/modules/messages' 10:53:07
Require stack:
- E:\Projects\bower-bird\src\modules\chrome_api.ts
Require stack:
- src\modules\chrome_api.ts
at Module._resolveFilename (node:internal/modules/cjs/loader:1145:15)
at Function.resolve (node:internal/modules/helpers:190:19)
at _resolve (node_modules\jiti\dist\jiti.js:1:241814)
at jiti (node_modules\jiti\dist\jiti.js:1:244531)
at E:/Projects/bower-bird/src/modules/chrome_api.ts:1:278
at evalModule (node_modules\jiti\dist\jiti.js:1:247313)
at Object.jiti (node_modules\jiti\dist\jiti.js:1:245241)
at resolveConfig (/E:/Projects/bower-bird/node_modules/c12/dist/shared/c12.cab0c9da.mjs:345:26)
at loadConfig (/E:/Projects/bower-bird/node_modules/c12/dist/shared/c12.cab0c9da.mjs:147:29)
at /E:/Projects/bower-bird/node_modules/wxt/dist/core/utils/building/resolve-config.mjs:342:32
I still see jiti in the stack—is this correct?
Here is my configuration file:
import {defineConfig} from "wxt";
import vue from '@vitejs/plugin-vue';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import {ElementPlusResolver} from "unplugin-vue-components/resolvers";
import htmlMinifier from 'vite-plugin-html-minifier';
// noinspection JSUnusedGlobalSymbols
export default defineConfig({
srcDir: 'src',
publicDir: 'public',
entrypointsDir: 'entries',
browser: 'chrome',
manifest: {
name: "Gardener Bird",
minimum_chrome_version: "120",
version: "0.0.0.0",
version_name: "0.0.0",
description: "The description is well-written.",
icons: {
"128": "./icons/icon.png"
},
author: "NXYBW",
host_permissions: [
"<all_urls>"
],
permissions: [
"contextMenus",
"storage",
"tabs",
"offscreen",
"scripting",
"userScripts",
"activeTab",
"unlimitedStorage",
"declarativeNetRequest",
"declarativeNetRequestFeedback",
]
},
alias: {
"&": "src",
"@": "src/entries",
"@OPT": "src/entries/options",
"@POP": "src/entries/popup",
"@OFF": "src/entries/offscreen",
},
vite: () => ({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()]
}),
Components({
resolvers: [ElementPlusResolver()]
}),
htmlMinifier()
],
build: {
target: ['chrome120', 'edge120'],
},
})
});
Since I haven't worked on it for a few months, I'm not sure if the configuration needs to be modified or if this might be a new issue?
I also tried adding
ssr: {
noExternal: ['@webext-core/messaging', '@webext-core/proxy-service'],
},
but it doesn't seem to help :(
@NXY666 Although not yet documented in the directory-structure doc, modules
directory have recently become a meaningful concept. (https://wxt.dev/guide/go-further/reusable-modules.html)
I think there is a namespace conflict with the traditional src/modules
you have. Try customizing modulesDir
in your wxt.config.ts
.
{
srcDir: 'src',
publicDir: 'public',
entrypointsDir: 'entries',
modulesDir: 'wxt-modules', // dir name is example, as you like
...
}
@NXY666 Although not yet documented in the directory-structure doc,
modules
directory have recently become a meaningful concept. (https://wxt.dev/guide/go-further/reusable-modules.html)I think there is a namespace conflict with the traditional
src/modules
you have. Try customizingmodulesDir
in yourwxt.config.ts
.
Thank you very much!
You're right, I saw this new feature in the documentation this morning, but I didn't realize it was caused by a folder naming conflict.
This is an issue for addressing several issues with how entrypoints are imported to get their options.
Will add to this list if other issues come up.