Webpack function import not accessible by JS on page - javascript

First time learning webpack with Laravel 5.5.
I have a helpers.js library which I include into my app.js bunlde like this:
import * as $mh from './helpers.js';
An example function in helpers.js is:
export function valRemoveHighlight(element)
{
$(element).closest('.form-group, .input-group, .has-feedback').removeClass('has-error').addClass('has-success');
}
I can then access this function inside the bundle like this:
$mh.valRemoveHighlight(element);
But I have JS script at the bottom of my page which cannot access the function in the bundle. I have tried different scopes with no success:
window.$mh.valRemoveHighlight(element);
$mh.valRemoveHighlight(element);
valRemoveHighlight(element);
How do I make these exported / imported helper functions accessible in the global scope, so any inline / page script can access them?
Ideally kept within the helpers scope $mh. but accessible from the page / script like:
$mh.valRemoveHighlight(element);
Thanks!

$mh is only available inside of app.js, so you will have to expose that function yourself inside your app.js by doing : window.$mh = $mh

Related

Laravel Vite Can't Use JS Functions Globally

I'm using Laravel with Vite. But I'm having a trouble. I have multiple JS files and including them whenever I want to use. But I cannot use the function I created in one file in another file.
I have an app.js file looks like this:
import jQuery from 'jquery';
window.$ = jQuery;
import './bootstrap';
import './main.js';
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.start();
And I have a function like this in main.js:
function testFunction() {
alert('test');
}
I put Vite definitions to my layout blade like this:
#vite(['resources/css/app.css', 'resources/js/app.js'])
I have another page contains another JS file like this:
#extends('layouts.app')
#section('content')
#endsection
#section('scripts')
#vite(['resources/js/edit-note-page.js'])
#endsection
And in that JS file I want to use the function that I mentioned in the beginning like this:
testFunction();
But I'm getting an Uncaught ReferenceError: testFunction is not defined error in console. I couldn't figure it out. What is the correct way to do it?
I'm using Laravel with Vite. I have multiple JS files and including them whenever I want to use. But I cannot use the function I created in one file in another file.
Each file is going to be wrapped to actually prevent what you are attempting to do, unless explicitly defined on the window object (notice how window.Alpine = Alpine; is set in your app.js). An alternative and more modern way is to use exports. Here is an example using your file structure.
main.js:
function testFunction() {
alert('test');
}
export default testFunction;
edit-note-page.js:
import testFunction from './path/to/file/name';
...code here
The path to the file in the import does not need the extension .js at the end.
Note: After this change, you no longer need import './main.js'; inside of app.js

Referencing vanilla js file in TypeScript getting file is not a module

I'm trying to import a file into TypeScript that's basically just a js file that you'd put into a tag. I've tried a few different things.
// global.d.ts
declare module 'myfile.js'
Inside of the react file:
// component.tsx
import { foo } from '../lib/myFile.js' // This is saying it is not a module
Inside of the js file, it looks like this a few times so not sure how I need to reference the file:
(function( something ) {
something.Foo = function (){}
}(window.something = window.something || {}));
Any thoughts on how I could use this file? Do I need to go through and declare typings for everything in it?
EDIT: I've added allowJS to my tsconfig but it still doesn't work.
You can only import what is exported from the file.
If your file contains only immediately invoked functions, or top level code, you only need to import the file itself like this:
import '../lib/myFile.js'
This is a little weird, however. I would suggest wrapping everything with a function and exporting then importing that function instead.

Can an imported node module call a function which was initialized in the main module?

I wrote a module to contain some of the less interesting bits of a large Javascript codebase I am working on, call it boring.js.
It is imported from a main module that does most of the more interesting work, call it main.js.
There is a class in boring.js called Log, which is exported to main.js and instantiated to a variable log. Calling the function log.save(newLogMsg) saves newLogMsg to file.
log.save(newLogMsg) works fine when called from main.js
When I try to call log.save(newLogMsg) from inside a function that resides in boring.js, I get the error:
ReferenceError: log is not defined
Which is confusing to me, because let log = new Log is initialized in the main module before I call the function in question (from main.js) that resides inside the imported module.
Side Question: Why can I call console.log(newLogMsg) from any module that I choose? How could I go about implementing a similar functionality for my Log class?
An imported module cannot access the namespace of the module that imports it.
Say you have a module named module.js that looks like this:
// module.js
exports.x = 10;
And a script main.js that imports it:
// main.js
const s = "abc";
const m = require('./module');
Here is what happens when running main.js:
Line 1: the string "abc" is mapped to the name s in the main namespace
Line 2: the require function executes the script named module.js and
returns its export object. The script runs in its own scope and doesn't
know anything about the script which is importing it. Therefore it cannot
see the constant s defined in main.js
Line 2: the return value of require (the module's export object) is
assigned to the constant m defined inside main.js
About your side question:
you could pass the log object as a parameter to a function defined
inside module.js
you can define log in a third module and require it both from main.js and from module.js

NodeJS - how can I make my code beautiful / cleaner / better readable

I have generated my app with express --view=pug myapp which created me a folder-tree with the files I need to start over.. I wrote some code which I would like to outsource from the main app.js in maybe a function-file or something like that, to keep the app.js cleaner.
where would I put my custom functions? how would I then require the function-file in nodeJS ?
You can arrange your files as you wish. Wherever you keep your functions, just add the functions you want to use in any other files to module.exports object in that file. Then in your app.js (or any other file where you want to use these functions), import the file using require and you should have access to all the exported properties and functions from the file you import.
For example:
I can put my functions in ./lib/core-lib.js:
function test(){
// do something
}
module.exports = {
test: test
};
And then in my app.js
const lib = require('./lib/core-lib');
lib.test();

Global variables are undefined for imported Javascript functions

Trying to figure out if there is a problem due to the import/export method, or if my architecture just bad....
Previously, I had multiple files of javascript. Just functions, no classes. In one "center/main" JS file, there are global variables. These variables are accessed and used/updated by functions in that same file, as well as other files. Each JS file had to have its own tag within the index.html
The move was then to switch to webpack as a module builder which would remove the need for all those script tags. Instead I just have to import/export the functions.
The problem is that now after using that method, the global variables are undefined to the imported functions Below is the setup dumbed down, but I don't see why it would be a problem. Maybe I'm missing something.
main JS file
import * as SettingsFile from './settings';
var myVariableUsed;
$(document).ready(function() {
myVariableUsed = "test";
SettingsFile.startSettings();
});
secondary JS file (settings.js)
export function startSettings(json) {
console.log(myVariableUsed);
}
Hy, i think you can understant what is happening with this article:
https://medium.com/webpack/brief-introduction-to-scope-hoisting-in-webpack-8435084c171f
To be short, webpack creates a new scope for required files, because of 'use strict' declaration on generated code output.
To pass parĂ¢meters to required modules you need to do do something like this:
// somefile
require("lib.js")(param1, param2)
// lib.js
module.exports = function(param1, param2) { }

Categories