unusual unexpected token in webpack - javascript

I have a file call scripts.js and it merely do var main = require('./main');
and my main.js is at the same level, it has
module.exports = {
console.log("hello");
}
I do webpack in my terminal I got unexpected token?

You can not include function executions into a javascript object (you are exporting an object), you need to export a function to achieve this
module.exports = function() {
console.log("hello");
}
And from your file where you require the export
var main = require('./main')(); // Add () to execute the function that you obtained
UPDATE:
You are executing console.log() in your main.js file, think that you can simply require some script without exporting nothing, and that file should be executed. For example you can put console.log("hello") without all the module.exports thing and the code should be executed, but when you check the value of your main variable (in the file where you do the require), you probably would not find anything useful.
You can also export a function(like in the code i send before) and then execute that function later, there's many ways to aproach this, I recommend you to google a bit about how module export works and how can you use it
You can check more about module.exports here https://www.sitepoint.com/understanding-module-exports-exports-node-js/, you are using it for the browser, but this examples for node should be usefull anyways

Related

How to properly export/import an object in this nodeJS project?

I have a nodeJS project where I have this file GameState.js with this structure:
const GameState = function(socket){
this.socket = socket
//quite a large constructor so I removed most of it
};
//defining all the prototype methods
GameState.prototype.getSocket = function() {
return this.socket
}
module.exports = GameState;
I'm able use this GameScreen constructor in my gamescreen.js file, by having the two scripts in my gamescreen.html file like this:
<script src = "gamestate.js"></script>
<script src = "gamescreen.js"></script>
So for getting GameState into gamescreen.js I actually don't need the module.exports, it's even giving me a (non-breaking) ReferenceError when I use the app, which is quite annoying.
However with my current structure I can't remove this module.exports as I also have a test file (using jest) where I import GameState with require like this:
const GameState = require("../scripts/gamestate.js");
//the tests here...
So my question is: How do I get GameState in both gamescreen.js and gamestate.test.js, without having the ReferenceError? Right now it's all working, but it's not very optimal to get an error in the console when running the app.
EDIT: A better way to formulate this question might be: I have a module GameState defined with module.exports, now how do I get it in gamescreen.js (the client-side), without losing the ability to import it with require(...) in a test file?
I got rid of the error by simply wrapping the module.exports in a try catch block like this:
try {
module.exports = GameState;
} catch(error) {
console.log("didn't work")
}
When I run it in the browser it functions normally and prints: "didn't work" and when I run my tests with npm test, the tests work too.
It might not be the prettiest fix, so any other suggestions would be appreciated.

Export just a function from js file?

I have two modules one written in ts the other one in js. One of the utilities in js module need to be accessed in ts module.
So utility service.js as follows,
module.exports = {
helloFriends: function (message) {
console.log(message);
}
}
console.log('This part should not get invoked');
The called caller.ts as follows,
import { helloFriends } from './../moduleb/service';
helloFriends('Hello');
The output of above tsc caller.ts then node caller.js outputs following,
This part should not get invoked
Hello
I don't want any other code to get invoked from service.js except the function helloFriends, What can I do?
Note: Both modules are separate from each other with their own node dependencies.
Update:1
I handled with a hack, I defined IAM in both the modules .env files.
For service.js .env has IAM=service,
For caller.ts .env has IAM=caller,
So if service.js is called from its own module IAM is service but when it is called from outside e.g. from caller.ts it has IAM value as caller then in service.js I made following changes:
In service.js I made changes as follows:
var iam = process.env.IAM;
module.exports = {
helloFriends: function (message) {
console.log(message);
}
}
if (iam === 'service') {
console.log('This part should not get invoked, When called by external modules other than service');
}
So based on caller configuration I decide whether to execute a particular code section or not.
The plugin used for .env https://www.npmjs.com/package/dotenv
Update:2
Based on learnings I had after this question better approach would be to have functions to serve each purpose/functionality & export them individually.
I think the problem here is hinted at by this question: How does require() in node.js work?. In the question the asker has the following code in a module:
// mod.js
var a = 1;
this.b = 2;
exports.c = 3;
When mod.js is imported, the following properties are set:
// test.js
var mod = require('./mod.js');
console.log(mod.a); // undefined
console.log(mod.b); // 2
console.log(mod.c); // 3
The this/exports difference is interesting by itself, but it also tells us that the whole module is being run when it is required/imported and as it is stated in the answer you can even return part way through the module code.
This means that your console.log('This part should not get invoked'); will unfortunately be invoked unless you have a way of exiting the module code
Update:1
I handled with a hack, I defined IAM in both the modules .env files.
For service.js .env has IAM=service,
For caller.ts .env has IAM=caller,
So if service.js is called from its own module IAM is service but when it is called from outside e.g. from caller.ts it has IAM value as caller then in service.js I made following changes:
In service.js I made changes as follows:
var iam = process.env.IAM;
module.exports = {
helloFriends: function (message) {
console.log(message);
}
}
if (iam === 'service') {
console.log('This part should not get invoked, When called by external modules other than service');
}
So based on caller configuration I decide whether to execute a particular code section or not.
The plugin used for .env https://www.npmjs.com/package/dotenv
Update:2
Based on learnings I had after this question better approach would be to have functions to serve each purpose/functionality & export them individually.

Correct way to export/define functions in Electron's Renderer

I have a JS file that I'm importing into my Electron's "main" (or background process), app.js, using require (eg: const myJS = require("./pathToMyJS/myJS");)
Contents of myJS.js:
module.exports = {
mFunc: function mFunc(param1) {
...
}
};
And I can use mFunc in app.js as myJS.mFunc(param1); & everything's great.
Then, I tried to follow the same process for the "renderer" JS. So my renderer.js now imports const myOtherJS = require("./myJS/myOtherJS"); where this other JS file follows the exact same module.exports logic as myJS.
And the root HTML (app.html) declares the renderer as <script defer src="./renderer/renderer.js"></script>.
But on launch, I get:
Uncaught TypeError: Cannot set property 'exports' of undefined
at renderer.js? [sm]:34
Searching online, I came across this answer that mentions that the AMD way could be used instead of the commonJS way. So I tried the following: (not sure whether this is syntactically correct!)
define(
["renderer"],
function rFunc(param1) {
... }
)
But that fails with:
Uncaught ReferenceError: define is not defined
So what's the correct way to have functions defined for export when using them in the renderer? What I've been doing so far is just to write the functions in their own JS files (eg: function func1() { ...}) & declaring all of these files in the app.html as <script defer src="./funcFile1.js"></script>.
Turns out, I was just exporting incorrectly. modules.export was the point of failure as modules is undefined on the renderer.
Instead, if I do the following to export individual functions:
// ./myJS/myOtherJS.js
export function rFunc() { ...}
And then import into my renderer.js like:
import { rFunc } from './myJS/myOtherJS';
rFunc();
Things work as I originally expected.
This Google Developers Primer on modules was useful in understanding the concepts.
AMD is not provided by node.js by default. It's used by Require.js and other FWs. Here is a link on how you can use it with node:
https://requirejs.org/docs/node.html

where do module.exports export your function and what is the use of it when we still use require to import the code into your module

i Have written the following code in node.js
notes.js
console.log('notes app is running');
app.js
const notes = require('./notes.js');
console.log(notes);
When i import the code and run app.js output is shown as notes app is running
Now i updated the code for notes.js
console.log('notes app is running');
addNote = () =>{
console.log('addNote');
return 'New note';
} ;
Now i want to use the following arrow function in my code so updtaed my
app.js
const notes = require('./notes.js');
var res = notes.addNote();
console.log(res);
console.log(notes);
Now it is Throwing me error
notes.addNote is not a function
1) I know i should use module.exports.addNote
2) But i want to know why we can see a log which we have written in notes.js without using module.exports statment. why can't we use require statment and store total code and call the function from that varable as we do for a instance of a class
3)More preciously where do module.export export your code (i mean to which directrey )
4)Plese correct me if anything is wrong
(#1 and #4 don't need answers, so I've left them off.)
2) But i want to know why we can see a log which we have written in notes.js without using module.exports statment.
With Node.js's style of modules (which is a flavor of CommonJS), a module is loaded and executed when it's first required. Your console.log is in the module's code, so when you require it (the first time), that code gets run.
why can't we use require statment and store total code and call the function from that varable as we do for a instance of a class
You can, if that's what you want to do:
exports = {
// code here as object properties
addNote: () => {
console.log('addNote');
return 'New note';
}
};
and
const mod = require("./notes.js");
mode.addNote();
3)More preciously where do module.export export your code (i mean to which directrey )
To the module cache in memory.
Internally, node caches all modules. In order to do this, it starts at the entry point file (e.g. you app.js file) and recursively searches all require statements (or imports).
As node parses modules, any code at the top level of the file will execute - such as your console.log line
console.log('notes app is running');
However, note, that at this point nothing in the file has been exposed to any other part of your codebase. Instead, node takes any value that is exported via module.exports and adds it to an internal cache. This cache is keyed on the path to the file as appeared in the require statements (converted to an absolute path), so for example, the following require statements:
const module1 = require('../module1.js');
const module2 = require('../module2.js');
will result in cache entries which look like:
<path_to>/../module1.js = ... contents of module1.exports
<path_to>/../module2.js = ... contents of module2.exports
Any time you require one of those modules again, you will get the cached version of the modules, it will NOT re-parse the file. For your example, it means that not matter how many times you require the notes.js file, it will only print your console.log('notes app is running'); statement once.
Because of the way node loads modules in isolation, you can ONLY access the elements which are exported via module.exports. Which means any function you define in the file but do not export cannot be accessed.
So, to directly address your questions:
I know i should use module.exports.addNote
Yes. Though, not you can also assign a new object to module.exports, e.g module.exports = { addNote };
But i want to know why we can see a log which we have written in notes.js without using module.exports statment. why can't we use require statment and store total code and call the function from that varable as we do for a instance of a class
Because node parses all required files while generating it's cache
More preciously where do module.export export your code (i mean to which directrey )
They're not stored in a directory, but rather cached in memory based on the file name and contents of module.exports
Plese correct me if anything is wrong
guess this one doesn't need an answer

How to create function (inside module) that consume relative path of file in NodeJs

What I am trying to do is creating function like NodeJS require. You can do require("./your-file") and require understand that the file ./your-file is sibling of the calling module, without specifying the full path of the file.
My current problem is getting the directory of current executing function (__dirname of the executing function)
I tried things below:
Using module.parent.fileName failed when the calling method wrapped with other function.
By reading from V8 stack trace almost there but failed when run inside test runner (Jest)
It should be an easy solution for this, maybe I'm over complicate it?
May be you should use:
var path = require('path');
//_dirname will give you the current position
using path package you can achieve this. find Documentation here
Both module.parent.fileName and V8 stack trace works fine, but it will failed if you export the module in the index.js
example:
//src/my-lib.js
function myFunction(){
const path = module.parent.fileName
//do stuff
}
then you export the function above in the index.js
//src/index.js
const lib = require("./my-lib")
exports.myFunction = lib.myFunction
in the client code if you import myFunction from index.js the path detected will always /src/index.js

Categories

Resources