Issue
I'm working on a chrome extension using Vite with React and Typescript and CRXJS. This is my first project. I have a script that I want to execute on the current tab when a button is clicked in the index.html. I'm using chrome.scripting.executeScript with the files property to select the script, but it's giving me the error could not load file.
I think the problem is when it gets built, script.ts isn't at the root because it gets transpiled to javascript and then bundled so it has a different file path, but I'm not sure how to select the new file path once it's packaged.
My manifest.json
{
"manifest_version": 3,
"version": "1.0.0",
"name": "Spotify Song Extractor",
"action": {
"default_popup": "index.html"
},
"permissions": ["tabs", "scripting", "nativeMessaging", "activeTab"],
"host_permissions": [
"http://open.spotify.com/track/*",
"https://open.spotify.com/track/*"
],
"content_scripts": [
{
"matches": [
"http://open.spotify.com/track/*",
"https://open.spotify.com/track/*"
],
"js": ["src/script.ts"],
"run_at": "document_end"
}
],
"background": {
"service_worker": "src/service-worker.ts",
"type": "module"
}
}
my service-worker.ts that is giving the error:
chrome.runtime.onMessage.addListener((message /*, sender, sendResponse*/) => {
if (message === 'get-details') {
chrome.tabs.query({ active: true, currentWindow: true }, (tab) => {
// Execute content script on the current page
chrome.scripting
.executeScript({
target: {
tabId: tab[0]?.id ?? 0,
},
files: ['script.ts'],
})
.then((result) => console.log('executed script: ', result))
.catch((err) => {
console.log('error running script', err)
})
})
}
})
File structure: file structure
I tried to place it in the public folder which worked, but then it doesn't get transpiled to a js file and stays a ts file, which gave an error since I was defining a type in there. Also, when it gets built it goes into the asset folder but under a generated name, so not sure how to select it.
Solution
To make separated entries in your React and Vite extension, Several changes in your vite.config.ts
are needed. In general, you need to specify the whole built output folder format as well as customized input and output for every single one of your separated entries in you built folder.
Step 1:
First, you need to add outDir to your build options in the vite.config.ts
file, this specifies the output directory, in your case it will output a src
directory in the dist
folder.
export default defineConfig({
plugins: [
....
],
build: {
outDir,
...
}
});
Step 2:
After adding outDir
, you need to specify the separated entries you want after the built process by adding rollupOptions to your Vite build configuration.
import path, { resolve } from "path";
...
/* resolve root path */
const root = resolve(__dirname, "src");
...
export default defineConfig({
resolve: {
/* create alias for src path */
alias: {
"@src": root,
},
},
plugins: [
....
],
build: {
outDir,
rollupOptions: {
...
input: {
...
/* custom entries for dist directory */
injectScript: resolve(root,'script.ts'),
},
}
}
});
After this, you should be able to find the injectScript
folder with a single index.js
file inside it at your dist
built folder. In your manifest file, you just need to replace the js
file path of the content script to src/injectScript/index.js
. Hope this can help!
Answered By - Hùng Trần Phạm Minh
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.