I've been trying to implement translation functionality for my chrome extension using the DeepL node API. I've been getting the following error in chrome://extensions. "Uncaught SyntaxError: Cannot use import statement outside a module"
[Error message] (https://i.stack.imgur.com/gw4cl.png)
This seems to be a relatively common issue but none of the solutions I've found online have worked. I am currently using the module and target ESNext in jsconfig.json. I've tried a number of different config settings aswell as using webpack to bundle my modules. Nothing has worked so far.
Here's some relevant code:
jsconfig.json
{
"compilerOptions": {
"moduleResolution": "Node",
"target": "ESNext",
"module": "ESNext",
/**
* svelte-preprocess cannot figure out whether you have
* a value or a type, so tell TypeScript to enforce using
* `import type` instead of `import` for Types.
*/
"verbatimModuleSyntax": true,
"isolatedModules": true,
"resolveJsonModule": true,
/**
* To have warnings / errors of the Svelte compiler at the
* correct position, enable source maps by default.
*/
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
/**
* Typecheck JS in `.svelte` and `.js` files by default.
* Disable this if you'd like to use dynamic types.
*/
"checkJs": true
},
/**
* Use global.d.ts instead of compilerOptions.types
* to avoid limiting type declarations.
*/
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte", "background.ts"]
}
background.js
import * as deepl from 'deepl-node';
const authKey = "hidden"; // REMEMBER TO HIDE
const translator = new deepl.Translator(authKey);
const chromeTab = {
id: 0,
url: ""
};
chrome.contextMenus.create({
id: "1",
title: "Translate \"%s\"",
contexts: ["selection"],
});
let newTabId = null;
chrome.tabs.onCreated.addListener((tab) => {
newTabId = tab.id;
});
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "1" && tab) {
const toTranslate = info.selectionText || "";
const translatedText = Translate(toTranslate);
chrome.tabs.create({
url: chrome.runtime.getURL("index.html"),
active: true,
}, (newTab) => {
const checkNewTabInterval = setInterval(() => {
if (newTab && newTab.id !== undefined) {
chrome.tabs.sendMessage(newTab.id, { action: "updateTranslation", text: translatedText, taskId: newTab.id }, () => {
console.log("Message sent!");
});
clearInterval(checkNewTabInterval);
}
}, 100);
});
}
});
function Translate(TextToTranslate) {
const translation = translator.translateText(TextToTranslate, null, 'es');
return translation;
}
manifest.json
{
"name": "SweetTranslator",
"description": "This is for TRANSLATING",
"version": "0.0.1",
"manifest_version": 3,
"permissions": ["storage","activeTab", "contextMenus", "action"],
"action": {
"default_popup": "index.html"
},
"icons": {
"128": "icon.png"
},
"background": {
"service_worker": "background.js"
}
}
package.json
{
"name": "vite-project",
"private": true,
"version": "2.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build-vite": "vite build",
"build:android": "vite build --mode android --base /assets/ && node script/after-build.js",
"preview": "vite preview"
},
"devDependencies": {
"@babel/core": "^7.23.3",
"@babel/preset-env": "^7.23.3",
"@sveltejs/vite-plugin-svelte": "^1.0.2",
"@types/chrome": "^0.0.251",
"babel-loader": "^9.1.3",
"svelte": "^3.49.0",
"ts-loader": "^9.5.1",
"vite": "^3.1.0",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-node-externals": "^3.0.0"
},
"dependencies": {
"@unocss/reset": "^0.46.5",
"@unocss/transformer-directives": "^0.46.5",
"@vitejs/plugin-legacy": "^2.1.0",
"deepl-node": "^1.11.0",
"svelte-spa-router": "^3.3.0",
"terser": "^5.15.0",
"unocss": "^0.46.5",
"vite-plugin-pages-svelte": "0.0.1"
}
}
Would very much appreaciate tips, this is my first experience with chrome extensions and JavaScript.