Vue3 + Vite: error handling in production - javascript

I used error handler from vue documentation
https://vuejs.org/guide/best-practices/production-deployment.html#tracking-runtime-errors
app.config.errorHandler = (err, instance, info) => {
console.log(err);
}
This works great with dev server, because it shows in which component the error happened and on what line it happened.
ReferenceError: foo is not defined
at ComponentNameWhereErrorHappened.vue:144:15
at callWithErrorHandling (runtime-core.esm-bundler.js:6737:22)
at callWithAsyncErrorHandling (runtime-core.esm-bundler.js:6746:21)
at Array.job (runtime-core.esm-bundler.js:7154:17)
at flushPreFlushCbs (runtime-core.esm-bundler.js:6910:31)
at flushJobs (runtime-core.esm-bundler.js:6951:5)
But when I use this code in production, the code gets bundled (using Vite) and then the error handling is not useful anymore. Because the name of files changes and everything happens on line 1.
ReferenceError: foo is not defined
at ComponentNameButNotWhereErrorHappened.b61810f1.js:1:10588
at Pt (vendor.7753fa93.js:5:656)
at lt (vendor.7753fa93.js:5:735)
at Array._ (vendor.7753fa93.js:5:3255)
at Cl (vendor.7753fa93.js:5:1980)
at pf (vendor.7753fa93.js:5:2249)
Is there a way how to get useful information about runtime errors with production Vue code?

I solved it by adding sourcemap: true to the vite.config.js
export default defineConfig({
build: {
sourcemap: true
}
})

Related

TS2307: error module not found local geojson in Angular

I want to draw a world map using d3-geo-projection. As input file I've thus far used https://enjalot.github.io/wwsd/data/world/world-110m.geojson, but I want to switch to a locally hosted version of that exact file.
Code I'm using that works fine:
const url = "https://enjalot.github.io/wwsd/data/world/world-110m.geojson";
d3.json(url).then(function(geojson) {
svg.append("path").attr("d", path(geojson))
});
Using examples and tutorials, I've added import world110m from './world110m.geojson'; with world110m.geojson in the same folder as the file, and changed const url"..."; to const url = world110m;.
This results in 2 errors in Terminal:
ERROR in ./src/app/02_robinson_projection/world110m.geojson 1:7
Module parse failed: Unexpected token (1:7)
You may need an appropriate loader to handle this file type, currently no loaders
are configured to process this file. See https://webpack.js.org/concepts#loaders
{"type":"Fea...
and
ERROR in src/app/02_robinson_projection/robinson-projection.component.ts(5,23): error TS2307: Cannot find module './world110m.geojson'.
Some googling resulted in having to add:
"compilerOptions": {
"resolveJsonModule": true,
"esModuleInterop": true,
...
}
However, the errors stay and the page in the browser gets a black overlay giving the first error.
I've looked in integrating webpack further in my project (https://webpack.js.org/concepts/loaders/), but when I look for a geojson-loader all I find is the old json-loader, which I've included instead (even though it says it's not necessary any more).
Together with this I also created a webpack.config.js,
module.exports = {
module: {
rules: [
{ test: /\.geojson$/, use: 'json-loader' }
]
}
};
But I'm quite sure this code is incorrect.
I know it's comparing apples to oranges, but why is including a local (geo)json file in Angular such a hassle? When I try above in plain JS with a local geojson it works just fine.

How to import another JS file in a Web Worker?

I've got a WebWorker in which I want to use functions from another existing JavaScript file. I've tried different methods to import the JS file but so far none have worked. The file in question is in another directory, with relate path '../pkg/benchmark.js'.
Is there anyone who knows how to do this?
I've tried the following methods:
Method 1:
import * as myFile from '../pkg/benchmark.js';
which gives the errors:
Uncaught SyntaxError: Unexpected token *
Method 2:
import { myFunc1, myFunc2 } from '../pkg/benchmark.js';
gives the error:
Uncaught SyntaxError: Unexpected token {
Method 3:
Using importScripts()
importScripts('../pkg/benchmark.js');
gives the error:
worker_wasm.js:6 Uncaught DOMException: Failed to execute importScripts' on 'WorkerGlobalScope': The script at http://localhost:8080/pkg/benchmark.js' failed to load.
Method 4:
Using dynamic imports:
import('../pkg/benchmark.js')
.catch(e => console.error(e));
gives the error:
TypeError: Failed to fetch dynamically imported module: http://localhost:8080/pkg/benchmark.js
Since I'm using npm, it should be mentioned that in package.json I've defined the dependency
"dependencies": {
"benchmark": "file:../pkg"
}
so I normally don't have to specify the relative path, and instead just import 'benchmark' directly. This doesn't work either.
Method 5:
Finally, I've tried enabling the chrome flag
--enable-experimental-web-platform-features
and declare my worker as
new Worker("worker.js", { type: "module" });
which doesn't give any errors in the developer console but also doesn't run the imported functions.

ES6 Dynamic Imports using Webpack and Babel

I've been using Webpack for my ES6 JS project and has been going well until I started to play with dynamic imports.
What I had that worked (router.js):
import { navigo } from "Navigo"; // router
import { clients } from "Controllers/clients.js";
const navigo = new Navigo();
navigo_router.on({
'/clients': () => {
clients.init();
}
});
But the more pages/routes I add, the more imports get stacked up in the head of the module. This is a relatively large app and I have a lot of pages/routes to add and therefore I need to load them dynamically to reduce the size of the initial page load.
So, following Webpack's documentation for dynamic imports, I tried the following which loads the controller module only when the relative route is called:
import { navigo } from "Navigo"; // router
const navigo = new Navigo();
navigo_router.on({
'/clients': () => {
import("Controllers/clients.js").then((clients) => {
clients.init();
});
}
});
But saving this in my editor resulted in a Babel transpiling error; SyntaxError: 'import' and 'export' may only appear at the top level, and clients.init() is not being called when tested in browser.
After a bit of reading, I discovered I needed a Babel plugin to transpile dynamic import() to require.ensure. So, I installed the plugin using the following command:
npm install babel-plugin-dynamic-import-webpack --save-dev
And declared the plugin in my babel.rc file
{ "plugins": ["dynamic-import-webpack"] }
After installing the plugin, the transpiling error disappeared and checking my transpiled code I found that the dynamic import()s has in fact been changed to require.ensure as expected. But now I get the following browser errors when testing:
Error: Loading chunk 0 failed.
Stack trace:
u#https://<mydomain.com>/js/app.bundle.js:1:871
SyntaxError: expected expression, got '<' 0.app.bundle.js:1
Error: Loading chunk 0 failed.
I didn't understand why it was referencing 0.app.bundle.js with the 0. prefix, so I checked my output/dist folder and I now have a new file in there called 0.app.bundle.js:
0.app.bundle.js 1,962bytes
app.bundle.js 110,656bytes
I imagine this new bundled file is the dynamically imported module, clients.js.
I only added dynamic importing to that one route and have left all the other routes as they were. So, during testing, I can view all routes except that one /clients route that now throws the above errors.
I'm totally lost at this point and hoped somebody could help push me over the finish line. What is this new file 0.app.bundle.js and how am I supposed to be using it/including it in my application?
I hope I've explained myself clearly enough and look forward to any responses.
I managed to fix my own problem in the end, so I will share what I discovered in an answer.
The reason the chunk file wasn't loading was because Webpack was looking in the wrong directory for it. I noticed in the Network tab of my developer console that the the chunk file/module was being called from my root directory / and not in /js directory where it belongs.
As per Webpack's documentation, I added the following to my Webpack config file:
output: {
path: path.resolve(__dirname, 'dist/js'),
publicPath: "/js/", //<---------------- added this
filename: 'app.bundle.js'
},
From what I understand, path is for Webpack's static modules and publicPath is for dynamic modules.
This made the chunk load correctly but I also had further issues to deal with, as client.init() wasn't being called and yielded the following error:
TypeError: e.init is not a function
To fix this, I also had to change:
import("Controllers/clients.js").then((clients) => {
clients.init();
});
To:
import("Controllers/clients.js").then(({clients}) => {
clients.init();
});
Note the curly braces in the arrow function parameter.
I hope this helps somebody else.
For debugging, you need to do
import("Controllers/clients.js").then((clients) => {
console.log(clients);
});
maybe working
import("Controllers/clients.js").then((clients) => {
clients.default.init();
});

Issues Integrating ACE Editor with Keystonejs App

It says here(http://ace.c9.io/#nav=embedding) just copy one of src* subdirectories somewhere into your project
I have put it in mykeystoneapp/public/js(my default home is mykeystoneapp/public)
Here are the errors I get:
1.Uncaught TypeError: $.cookie is not a function(ui.js:8)
2.Uncaught Error: Missed anonymous define() module: function …(require.js:141)
http://requirejs.org/docs/errors.html#mismatch
Here is my Jade code:
script(src='/js/ace/demo/kitchen-sink/require.js')
script.
require.config({paths: {ace: "/js/ace/build/src"}});
define('testace', ['ace/ace'],
function(ace, langtools) {
console.log("This is the testace module");
var editor = ace.edit("editor_container");
editor.setTheme('eclipse');
editor.session.setMode('javascript');
require(["/js/ace/lib/ace/requirejs/text!src/ace"], function(e){
editor.setValue(e);
})
});
require(['testace']);
Secondly if I put debugger in EventEmitter(https://github.com/ajaxorg/ace-builds/blob/master/src/ace.js#L3300)
I can see it’s properly reaching EventEmitter._dispatchEvent with
eventName=‘changeMode’ but it returns without any operation as there are no !listeners or defaultHandler
editor.session.setMode('javascript'); is wrong, it should be editor.session.setMode('ace/mode/javascript'); instead. Same for theme which is supposed to be ace/theme/eclipse.
error in ui.js is not related to ace, since ace doesn't have a file named ui.

How can I use Require.js and Buster.js together?

I'm trying to get started with Buster.js, and I installed both buster and buster-amd, but even so my use of Require.js is causing problems. My buster.js file looks like this:
var config = module.exports;
config["My tests"] = {
autoRun: false,
environment: "browser", // as opposed to "node"
extensions: [require("buster-amd")],
rootPath: "../",
sources: ['ext/require/require.js'],
tests: ["buster-test/*-test.js"]
};
and my test like this:
define(['buster-test/buster'
], function(buster) {
buster.spec.expose(); // Make some functions global
describe("A Fake Test", function () {
it("can be instantiated", function () {
console.log('test')
});
});
buster.run()
});
But when I try to run the above, I get:
Uncaught exception: ./buster/load-all.js:1 Uncaught ReferenceError: require is not defined
TypeError: uncaughtException listener threw error: Cannot read property 'id' of undefined
at Object.module.exports.uncaughtException (/usr/lib/node_modules/buster/node_modules/buster-test-cli/lib/runners/browser/progress-reporter.js:42:50)
at notifyListener (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/bane/lib/bane.js:49:35)
at Object.object.emit (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/bane/lib/bane.js:127:17)
at Object.module.exports.bane.createEventEmitter.emitCustom (/usr/lib/node_modules/buster/node_modules/buster-test-cli/lib/runners/browser/remote-runner.js:289:14)
at /usr/lib/node_modules/buster/node_modules/buster-test-cli/lib/runners/browser/remote-runner.js:92:16
at PubSubClient.on._handler (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/ramp/lib/pubsub-client.js:73:43)
at Object.Faye.Publisher.trigger (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/ramp/node_modules/faye/node/faye-node.js:385:19)
at Object.Faye.extend.Set.Faye.Class.distributeMessage (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/ramp/node_modules/faye/node/faye-node.js:668:30)
at Object.Faye.Client.Faye.Class._deliverMessage (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/ramp/node_modules/faye/node/faye-node.js:1070:20)
at Object.Faye.Client.Faye.Class.receiveMessage (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/ramp/node_modules/faye/node/faye-node.js:1007:12)
Has anyone seen anything like this before, and if so do you have any suggestions as to what I'm doing wrong?
P.S. If I remove the extensions: line I get a similar error, except that it complains about define instead of require. So it seems like the failure to find require is happening inside the plug-in ... but I have no idea how to provide Require to the plug-in.
Have you tried adding the require.js to libs instead of sources on your buster config? So the config would look like this:
var config = module.exports;
config["My tests"] = {
autoRun: false,
environment: "browser", // as opposed to "node"
libs: [ 'ext/require/require.js' ],
extensions: [require("buster-amd")],
rootPath: "../",
tests: ["buster-test/*-test.js"]
};
I take a different approach. I don't disable autorun, but instead use Buster's async test case format where you define the test case as a function that's passed a run callback. Use the (not well documented) resources: config setting to allow require to load your source code.
config["Browser tests"] = {
environment: "browser",
libs: [ 'test/require_config.js','require.js' ],
rootPath: "../",
resources: ["your_source_code/**/*.js"],
tests: ["buster-test/*-test.js"]
};
Then use require() in your tests, and when you've loaded your code call the run callback with the tests:
buster.testCase("AppCode",function(run) {
require(["appCode"],function(appCode) {
run({
"it works": function() { assert(true) }
})
});
});
I've created an example project showing this method require.js with buster.js. It has a small helper function to do both the testCase and require call simultaneously.

Categories

Resources