I am trying to create a websdk using simple JavaScript. When I use Webpack, Babel and Terser for minification and bundling, it is generating bundle.js file but when I use it in my HTML, it’s giving me an error on HTML page load itself
I have tried changing and working with different packages but issues persists. For reproduction of the issue, I’m giving some code snippets here. Hope some expert here guide me on to resolve the issue.
// SDKContract.js
class SDKContract {
constructor() {}
getLocation(callback) {
throw new Error("getLocation method not implemented");
}
}
// GeolocationAdapter.js
class GeolocationAdapter extends SDKContract {
getLocation(callback) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
const location = {
latitude: position.coords.latitude,
longitude: position.coords.longitude
};
callback(location);
}, function (error) {
callback({
error: "Location access denied or unavailable."
});
});
} else {
callback({
error: "Geolocation not supported by this browser."
});
}
}
}
// LocationWrapper.js
class LocationWrapper extends SDKContract {
constructor(adapter) {
super();
this.adapter = adapter;
}
getLocation(callback) {
this.adapter.getLocation(callback);
}
}
//main.js
import GeolocationAdapter from './src/GeolocationAdapter';
import LocationWrapper from './src/LocationWrapper';
// Your application code using the SDK components
const geolocationAdapter = new GeolocationAdapter();
const locationWrapper = new LocationWrapper(geolocationAdapter);
document.getElementById("getLocationButton").addEventListener("click", function () {
locationWrapper.getLocation(function (location) {
if (location.error) {
document.getElementById("locationResult").innerText = "Error: " + location.error;
} else {
document.getElementById("locationResult").innerText = "User Location: " + location.latitude + ", " + location.longitude;
}
});
});
Here’s my HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Location Capture Example</title>
</head>
<body>
<h1>Location Capture Example</h1>
<button id="getLocationButton">Get User Location</button>
<div id="locationResult"></div>
<script src="./dist/bundle.js"></script>
</body>
</html>
Webpack configuration
// webpack.config.js
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
],
},
optimization: {
minimizer: [new TerserPlugin()],
},
};
Package.json
{
"name": "jssdk",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.23.0",
"@babel/preset-env": "^7.23.2",
"babel-loader": "^9.1.3",
"terser-webpack-plugin": "^5.3.9",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4"
}
}
2
Answers
I suspect
t()
in the error msg is the minified/compiled name forgetLocation()
. Looks like it’s looking for the constructor that’s callingsuper()
in the extended class. Instead, it finds the method and then throws the error saying that that method is not a constructor.I think you have to add the constructor that calls super. Extended classes in JS always have to call the
super()
function, even if you don’t pass any properties:Looks like you are calling it in the
LocationWrapper
, but not in theGeolocationAdapter
. So:First you need to confirm if that script works on original source.
Second ensure that the entry point is called correctly.