Get class functions from webpack module - javascript

I need to call class function, what writed in webpack module from outside script.
There is webpack config:
entry: {
main: ["./src/js/main.js"],
},
performance: {
hints: false,
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist/js"),
},
optimization: optimization(),
module: {
rules: ifBabel(),
},
In main.js i have
import { finishing } from "./modules/forms/finishing";
var fns = new finishing();
fns.init();
I need to call some function of fns from outside script. But webpack compiling script inside his function and i cant access to it..

You have 2 primary options:
Use Webpack's library to define how your Webpack bundle exposes itself to the page when loaded, and have your main.js export functions to be used by your page via the library, like
import { foo } from "./foo";
export { foo };
with the page then able to use LibraryName.foo()
Have main.js explicitly do something like
import { foo } from "./foo";
window.foo = foo;
to manually expose specific functions on the window or some other location.
I would recommend the first approach, but either is fine.

Related

Exporting and bundling a function using webpack and calling it inside html script tag

I have been trying something very simple - export and bundle (and babel transpiling) a function using webpack and then call it in my html page's script tag.
sample.js - which is bundled using webpack
export default function sampleFunctionExported1(){
console.log("sampleFunctionExported1");
}
Webpack config (version = 4.44.1)
module.exports = (env, arguments) => {
entry: {
main: ['./assets/js/sample.js', './assets/css/main.scss'],
entry2: ['./assets/js/entry2.js', './assets/css/entry2.scss']
},
output: {
path: path.join(__dirname, '../public/js'),
filename: '[name].js',
library: 'MyLibrary',
libraryTarget: 'var',
// some additional configs/options that I have tried
// libraryTarget: 'window', // tried with this option, it does not work
// libraryTarget: 'umd', // tried with this option, it does not work
// libraryExport: 'default', // tried with this option, it does not work
}
I though it was as easy as adding the library and libraryTarget targets to webpack config and then I should be able to call my function as MyLibrary.sampleFunctionExported1().
But when I do MyLibrary in my browser console, it displays as below and MyLibrary.sampleFunctionExported1() return ... is not a function error
I have followed suggestions in many of these questions/answers: answer 1, answer 2, answer 3 and various other blog posts but it does not work for me at all.
So after spending so much time, I am posting it here hoping that someone can help me understand what is wrong.
Edit 1:
Here is ithe file generated after webpack bundling: /public/js/sample.js
P.S. - Ignore the entry2.js file as it's an empty file, I just added it to show my config and because I am not sure if having multiple entry points can cause this issue which I am facing currently.
Because of how you're exporting:
export default function sampleFunctionExported1(){
console.log("sampleFunctionExported1");
}
...your MyLibrary variable is going to have the shape:
{
default: function() { ... }
}
If you instead want it to have the shape:
{
sampleFunctionExported1: function() { ... }
}
...you need to do a named export instead of a default export:
export function sampleFunctionExported1() {
console.log("sampleFunctionExported1");
}

Webpack Externals Configuration for a Local Library

I want to setup my Webpack config (v4+) to exclude an import that is referencing a local library. In my app, I import this library like so:
/src/index.js
import foo from '../foo/foo'
console.log(foo);
/foo/foo.js
export default foo = "bar";
webpack.config.js
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
externals: {
"foo": path.resolve(__dirname, "./foo/foo"),
}
};
However, this library is actually already referenced globally in the site where I'm deploying my application. So I do not want this library bundled with my application (I still need to import it so that I can transpile my typescript without errors and use intellisense).
I found out that I can easily exclude a library from being bundled by utilizing the externals property like so:
module.exports = {
externals: {
"jquery": "jQuery"
}
}
I've been unsuccessful at doing the same with the library that I'm importing. How would I go about doing this? I've tried the following and the library is still included in my bundle:
I have been researching documentation and can only seem to find examples related to node modules and nothing specific to my requirements.
Please let me know if you need any additional details. Thanks in advance!
In order for WebPack to treat your import as external, your import declaration must be using the same alias you defined in the WebPack extenals configuration, and NOT a relative path:
import Foo from 'foo';
WebPack:
module.exports = {
externals: {
"foo": path.resolve(__dirname, "./path/to/foo")
}
}

Webpack renaming imported modules in transpiled test files

My test files are written in javascript but external modules are imported using es6 import syntax. However, when I transpile my test files using awesome-typescript-loader, the test files contains the imported module assigned to a different variable.
Hence, when I try to check any spy calls on the imported module's method in my tests, they fail. My guess is that the imported modules and the actual module which is called inside my .ts files are different. Any ideas what's happening?
My webpac.karma.config file used to transpile the test files is:
module.exports = {
module: {
loaders: [{
test: /\.ts$/,
loader: 'awesome-typescript-loader'
}]
},
output: {
path: __dirname + "/unittests/"
},
resolve: {
modules: ["node_modules"],
extensions: [".ts", ".js"]
}
};
My test file (example)...
import { HELLO } from './hello';
describe('check', function(){
it('should call friend method', function() {
spyOn(HELLO, 'friend');
$ctrl.methodThatCallsFriendMethod();
expect(HELLO.friend).toHaveBeenCalled(); // This is not called
});
})
In the transpiled test file inside unittests folder, the module is imported like this:
Object.defineProperty(exports, "__esModule", { value: true });
var hello_1 = __webpack_require__(5); // I fear this hello_1 does not reference to the same module imported in my main.ts file
...
...
describe('should call friend method', function() {
it('should call friend method', function() {
spyOn(hello_1.HELLO, 'friend');
$ctrl.methodThatCallsFriendMethod();
expect(hello_1.HELLO.friend).toHaveBeenCalled(); // This is not called
});
});
My HELLO module is very simple:
export class Hello {
static friend() {
return 'dneirf;
}
}
In my main ts file, I import the HELLO module normally (import {HELLO} from ...) and all works fine. It just doesn't work in test files. Thanks for any suggestions.

Using expose-loader with webpack 2 to load a module

I have jwplayer in my lib/ folder because no node_module exists. I tried to use expose-loader in order to be able to import it. In my webpack, I have the following basic setup in order to get this to work:
const path = require('path');
module.exports = {
// ...
module: {
rules: [{
test: /\.jwplayer\.js$/,
use: {
loader: 'expose-loader',
options: 'jwplayer', // have also tried `options: { name: 'jwplayer' }`
},
}]
},
resolve: {
alias: {
jwplayer: path.join(__dirname, './lib/jwplayer-7.7.4/jwplayer.js'),
}
},
externals: {
window: 'Window',
}
};
The strange thing is, jwplayer is exposed on the window object, but it is not available as a module.
import jwplayer from 'jwplayer';
console.log(jwplayer); // Object {} (not jwplayer)
console.log(window.jwplayer); // function jwplayer() {}
Am I loading it incorrectly? How should I load in jwplayer with webpack 2?
That's not how you use the expose loader. The expose loader tells to webpack to expose something to the global context when the bundle is loaded. My understanding is that you want to use jwplayer inside the bundle itself.
You can use the script-loader, that's how I usually import scripts (analytics, for instance)
Actually you can use
externals: ['jwplayer'],
Because externals is for passing global variables inside the bundle to be able to use them as a dependency and then you can import your library as any other
import jwplayer from 'jwplayer';
webpack documentation

Webpack export function

I have some js files, and each file is a standonlone function with unique name, And I want to pack all this files in one bundle So I do this code
module.exports = {
entry: {
app:[
'./file1.js',
'./file2.js',
'./file3.js',
'./file4.js'
],
},
output: {
path: './dist/',
filename: '[name].bundle.js'
}
};
that's work and I have my bundle file ".dist/app.bundle.js"
Now I have some js code in the HTML body that need to call functions in the bundle,
If I try to call function "functionA" (that is difined in file1.js) I get this message in browser console
Uncaught ReferenceError: functionA is not defined
The question is how can I export my functions from bundle to import it in my HTML code ?
Exporting things from an entry point file does not make them available to the global scope. You have two options - either explicitly add the functions to the window object, like so:
window.functionA = functionA;
Or configure your build to output as a library:
// webpack.config.js - abridged
module.exports = {
output: {
library: "myModule",
libraryTarget: "umd"
}
};
I don't know how the latter interacts with your entry point being set to an array of files - you may have to make a single entry file (main.js or something) that imports all of the functions and then re-exports them contained in an object, or something like that.

Categories

Resources