Wiriting 'JSON.stringify' generates an error when Vue component loads - javascript

I am writing a Vue plugin, but anytime I try to add JSON.stringify to it I get a runtime error in the browser and the page goes blank. Anywhere in the Plugin file I write JSON.stringify I get the error:
Uncaught TypeError: Cannot assign to read only property 'exports' of object '#'
If I write JSON.stringify to a component directly (in the 'created' lifecycle hook, for example), nothing happens.
This is not an error during the webpack compilation, it happens only in the browser inside an eval. The line where the error occurs looks like this:
eval("/* WEBPACK VAR INJECTION */(function(module) {Object.defineProperty(__webpack_exports__ ....")
This is what is written in the plugin file
var MyPlugin = function () {
}
JSON.stringify({})
MyPlugin.secret = 'vue-plugin-secret'
MyPlugin.install = function (Vue, options) {
}
module.exports = MyPlugin
// export default MyPlugin
And this is how I get it in the component:
var MyPlugin = require('./MyPlugin')
If I comment the JSON.stringify line the error stops.
#edit
did what #Saurabh suggested, used 'import' so I had to change the export form of the plugin
//MyPlugin.js
export default MyPlugin
And in the .vue component I did
import MyPlugin from './MyPlugin';
this fixed the error, but what is the reason for this? some webpack configuration? (I'm using the default webpack configuration of vue-cli)

Related

Can't generate Nuxt website with #googlemaps/js-api-loader

I am using #googlemaps/js-api-loader in my Nuxt 3 website. Everything works fine in local development, but when I try to build the project with nuxt generate (no matter if locally or on Vercel) I'm getting following error:
[nuxt] [request error] Named export 'Loader' not found. The requested module 'file:///path/to/website/node_modules/#googlemaps/js-api-loader/dist/index.umd.js' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using:
The important part of loading script looks like this:
import { Loader } from '#googlemaps/js-api-loader';
const loader = new Loader({
apiKey: config.googleMapsApiKey,
version: 'weekly',
});
onMounted(async() => {
await loader
.load()
...
so I tried to import this package differently, e.g.:
import * as gmaps from '#googlemaps/js-api-loader';
const { Loader } = gmaps;
and the previous error disappeared, but now I'm getting
[Vue warn]: Unhandled error during execution of setup function
at <DynamicLocations class="contact__map" locations= [
{
id: 1,
...
[nuxt] [request error] gmaps.Loader is not a constructor
at setup (./.nuxt/prerender/chunks/app/server.mjs:5536:20)
at _sfc_main$t.setup (./.nuxt/prerender/chunks/app/server.mjs:5582:25)
at callWithErrorHandling (./.nuxt/prerender/chunks/renderer.mjs:2654:23)
at setupStatefulComponent (./.nuxt/prerender/chunks/renderer.mjs:9548:30)
at setupComponent (./.nuxt/prerender/chunks/renderer.mjs:9503:12)
at renderComponentVNode (./.nuxt/prerender/chunks/renderer.mjs:12068:17)
at Object.ssrRenderComponent (./.nuxt/prerender/chunks/renderer.mjs:12504:12)
at ./.nuxt/prerender/chunks/app/server.mjs:5628:36
at renderComponentSubTree (./.nuxt/prerender/chunks/renderer.mjs:12149:13)
at renderComponentVNode (./.nuxt/prerender/chunks/renderer.mjs:12084:16)
I also can't import package by default export. Do you have any ideas what's going on and how can I fix this?
I found a documentation page related to this problem and there is the following information:
If you encounter these errors, the issue is almost certainly with the upstream library. They need to fix their library to support being imported by Node.
Although they provide a solution to get rid of errors by adding the package to build.transpile:
build: {
transpile: ['#googlemaps/js-api-loader'],
},
It worked for me

"Cannot use import statement outside a module" and "Uncaught SyntaxError: Unexpected identifier" when importing a class

I'm trying to import a class into my "main.js" file. Here is a minified version of my code.
// "extended.js" file
export default class Test {
constructor() {
this.prop = "Hello"
console.log(this.prop)
}
}
// "main.js" file
window.onload = function () {
import Test from "./extended"
new Test()
}
The main.js file is the frontend JavaScript file for my Express app so it is stored in the "public" folder. When you load the page the initial error that occurs is "Cannot use import statement outside a module". I've done research on my own and multiple people have stated that using
type="module" for the "main.js" script tag will resolve the issue. When I did that the error changed to "Uncaught SyntaxError: Unexpected identifier". Is there something I'm missing about how to use ES6 modules and classes?
You can only import at the top level - it can't be done inside a block. Change
window.onload = function () {
import Test from "./extended"
new Test()
}
to
import Test from "./extended"
window.onload = function () {
new Test()
};
Though, I'd also suggest not creating classes for side-effects - if you just want the class to do something, but not to return something useful, use a plain function instead.
export default () => {
const prop = "Hello";
console.log(prop);
};

JS commonjs exporting a function shows up as undefined

I define a function in app.js like so:
const sendNotif = (userIds, type, content) => {...}
exports.sendNotif = sendNotif;
And I import it in service.controller.js like so:
const { sendNotif } = require("../app");
sendNotif(...)
When I hover over it in vscode I can see the function definition, however, when I run the code I get that sendNotif is not a function, when I log its type using typeof, I get undefined.
EDIT: I'm using nodejs without any bundlers or compilers, I'm also exporting an HTTP server in app.js by doing exports.http = htpp, and then I import that in index.js and use it, then it works fine. I'm able to import things from app.js everywhere else except in this file, I can't import anything.
UPDATE:
I tried do so:
const app = require("../app");
console.log(app);
and I get an empty object
UPDATE: I'm able to import the function from apps within the same level, same directory, but not form files that are a level deeper, (ex ./ vs ../)
ANOTHER UPDATE: I updated my node version to 15.6 from 12.4 and now I get this output in the console:
(node:17052) Warning: Accessing non-existent property 'Symbol(nodejs.util.inspect.custom)' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
(node:17052) Warning: Accessing non-existent property 'constructor' of module exports inside circular dependency
(node:17052) Warning: Accessing non-existent property 'Symbol(Symbol.toStringTag)' of module exports inside circular dependency
(node:17052) Warning: Accessing non-existent property 'Symbol(Symbol.iterator)' of module exports inside circular dependency

How do I call a function in an external js file using typescrpt

We are trying a POC of adding Typescript and Webpack to our Angularjs project.
I am able to get my webpack bundle to generate, however at runtime the program cannot find the various functions in my validator.js. Can you please offer some advice?
login-view.components.ts
declare var findFormNode: any; //function in validator.js
//LogInUser
self.login = function ($event, command) {
if (findFormNode($event.target.id)) {
...
}
}
main.ts is importing the file
import "./../../../CommonStaticFiles/include/js/Validators.js";
bundle.js
eval("/* WEBPACK VAR INJECTION */(function($) {/*\r\n\r\n VALIDATORS\r\n\r\n ... n\n\nfunction findFormNode(
error
ReferenceError: findFormNode is not defined
at LoginController.self.login (login-view.component.ts:28)
at fn (eval at compile (angular.js:NaN), <anonymous>:4:267)
at callback (angular.js:29019)
In order for your functions to be properly imported, there are few things that you have to make sure of.
First, make sure you are exporting your functions correctly. Here's an example of how to export a function from Validator.js:
export const validateFunc1 = ():void => {};
Next, you have to make sure you are using proper import syntax. In order to import the function above, you would do the following:
import {validateFunc1} from "./../../../CommonStaticFiles/include/js/Validators.js";
Alternatively, if you want to import all exported functions at once, then you can use this syntax:
import * as validatorFuncs from "./../../../CommonStaticFiles/include/js/Validators.js";
Lastly, check that the location of Validators.js is correct. It's a common mistake to be looking in the wrong directory. Your code editor can usually help you find the right path to use.

How to import non-module(!) JavaScript into Polymer 3.0

Polymer 3 uses import to load external Javascript. For example
import {GoogleCharts} from 'google-charts';
However, it seems for this to work, the external library should use exports.
I am trying to use mapbox-gl.js library. This library, installed with:
npm install mapbox-gl
does not seem to export anything.
In HTML5, you can use mapbox-gl as follows:
<script src="node_modules/mapbox-gl/dist/mapbox-gl.js"></script>
<link href="node_modules/mapbox-gl/dist/mapbox-gl.css" rel="stylesheet" />
<script>
const options = {...}
const map = new mapboxgl.Map(options);
</script>
I tried to use 'import' to load mapbox-gl:
import {mapboxgl} from './node_modules/mapbox-gl/dist/mapbox-gl.js';
import mapboxgl from './node_modules/mapbox-gl/dist/mapbox-gl.js';
This doesn't work:
Uncaught SyntaxError: The requested module './node_modules/mapbox-gl/dist/mapbox-gl.js' does not provide an export named 'mapboxgl'
Uncaught SyntaxError: The requested module './node_modules/mapbox-gl/dist/mapbox-gl.js' does not provide an export named 'default'
So, then I tried to add the script and css to document.head from inside the module javascript (<script type="module">..</script>):
// load external mapbox-gl.js script
const mapboxgljs = document.createElement('script');
mapboxgljs.setAttribute('src', 'node_modules/mapbox-gl/dist/mapbox-gl.js');
document.head.appendChild(mapboxgljs);
// load external mapbox-gl.css
const mapboxcss = document.createElement('link');
mapboxcss.setAttribute('href', 'node_modules/mapbox-gl/dist/mapbox-gl.css');
mapboxcss.setAttribute('rel', 'stylesheet');
document.head.appendChild(mapboxcss);
This does not seem to work either. If I try to use mapbox as follows:
const map = new mapboxgl.Map(options)
I am getting:
Uncaught ReferenceError: mapboxgl is not defined
Edit:
Commenters #Salketer and #barbsan showed correct import syntax for this kind of library:
import 'node_modules/mapbox-gl/dist/mapbox-gl.js';
or
import * as mapboxgl from 'node_modules/mapbox-gl/dist/mapbox-gl.js';
Both now result in the following error message:
Uncaught TypeError: Cannot set property 'mapboxgl' of undefined
This means the mapbox-gl library now gets loaded and interpreted. However, the mapbox-gl code contains the line:
window.mapboxgl = something;
ES6-module scope does not have access to the browser 'window' object, so the code fails. See also Is there an es6 module-scope equivalent to `window`?.
For now, I am adding the HTML5 <script></script> and <link /> tags (see above) to the index.html of my project. This works, but the idea of components and modules is to load dependencies from inside those components and modules?
You are close.
With your original code to load script:
// load external mapbox-gl.js script
const mapboxgljs = document.createElement('script');
mapboxgljs.setAttribute('src', 'node_modules/mapbox-gl/dist/mapbox-gl.js');
document.head.appendChild(mapboxgljs);
At this moment, if you use the instance provided by the script: const map = new mapboxgl.Map(options)
You will get error: Uncaught ReferenceError: mapboxgl is not defined
Reason: the script isn't loaded yet, so the instance window.mapboxgl is undefined.
Solution: You have to wait until the script finished loading, using event listener. Add this code into your loading script code:
mapboxgljs.addEventListener('load', function() {
// mapboxgl is available here, do whatever you want
const map = new mapboxgl.Map(options)
})
For me the solution was to define the import without mustasch {}:
import mapboxgl from 'mapboxgl'
Just do:
import("node_modules/mapbox-gl/dist/mapbox-gl");
// do my stuff with global dependency
or if import is slower than the code to be execute
import("node_modules/mapbox-gl/dist/mapbox-gl").then(() => {
// do my stuff with global dependency
})

Categories