I’m thinking about how I can structure my code.
Since some code in Chrome Browser runs in “Isolated Worlds”, little VMs, I have trouble bundling my Javascript without creating a lot of duplicated code.
For my browser extension, I want to add a listener, that has a callback function someFunctionToUnpack
.
// typescript
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'DO_STH') {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
const tab = tabs[0];
if (tab && tab.id !== undefined) {
chrome.scripting.executeScript({
target: { tabId: tab.id as number },
func: someFunctionToUnpack,
});
}
});
}
});
Ideally, it contains code that I can re-use in other places, because I do need this code in other places.
// typescript
import { some } from "anotherFile.ts";
const someFunctionToUnpack = ()=> {
return some.objectContainingFunctions();
}
const doSomthingWithA = (a)=> {
console.log(a);
}
const someFunctionToUnpack() {
const a = anotherFunctionCall()
doSomethingWithA(a);
}
If I did that, my current settings compile in a way that object() of some is not defined.
// In the VM, which has got the callback and
// is now isolated from the rest of the compiled javascript:
(()=>{
const e = (()=>{
const e = {
some.objectContainingFunctions() // breaks here
};
console.log(e);
})()
}
)()
While in a normal environment, we would bundle everything to the absolut minimum, I
require some code to be fully unpack and intentionally be duplicated, so that callback from event listeners in Chrome extensions can have access to their references, while I still avoid writing duplicated code.
Because it breaks in the VM, I’m forced to copy and move code into the someFunctionToUnpack
and create duplicated code.
I’m using Webpack 5
module.exports = {
entry: {
'service-worker': './src/service-worker.ts',
'content': './src/content.ts',
'index': './src/backend/index.ts',
},
output: {
path: path.resolve(__dirname, 'out'),
filename: '[name].js',
clean: true
},
resolve: {
extensions: ['.ts', '.js', '.json']
},
module: {
rules: [
{
test: /.ts$/,
use: 'ts-loader',
exclude: /node_modules/
},
{
test: /.json$/,
type: 'javascript/auto',
loader: 'json-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
chunks: ['index'],
}),
new CopyWebpackPlugin({
patterns: [
{ from: 'src/manifest.json', to: 'manifest.json' },
{ from: 'src/icons', to: 'icons' },
{ from: 'src/styles', to: 'styles' },
]
})
],
optimization: {
minimize: true,
minimizer: [new TerserPlugin({
terserOptions: {
compress: true,
mangle: true
}
})],
},
};