Export global function using webpack
Asked Answered
S

3

7

I'm trying to write an isomorphic module. The server javascript is going to run inside of JINT. I have created a webpack bundle specifically to build the server version of the module. I want to expose a single function that I can get JINT to call. I am using the scriptEngine.Invoke function from JINT however this is looking for a function on the global object. I don't know how to get a function onto the global object. I have tried using the expose-loader but this seems to export the entire module and I can't get it to just expose a single function.

Here is my entry point:

require("expose?FormValidator!./formValidator.js");

Here is my formValidator.js:

export default function validate () {
    return 'HelloWorld';
}

When I load up the resulting bundle and examine the FormValidator global it is an object with a validate function. Is there a way I can get the validate function to be directly assigned to FormValidator?

Sunward answered 13/6, 2016 at 15:2 Comment(0)
O
7

I am in the same situation as you do.Here is my code:

webpack.config.js:

module.exports = {
    entry: './src/method/eTrack/index.js',
    output: {
        filename: 'eTrack.js',
        path: path.resolve(__dirname, 'dist'),
        library: 'eTrack',
        libraryTarget: 'umd'
    },
};

./src/method/eTrack/index.js:

import create from './create';
import getAll from './getAll';
import getByName from './getByName';
import remove from './remove';

export function eTrack () {

}
eTrack.trackers = [];
eTrack.create = create;
eTrack.getAll = getAll;
eTrack.getByName = getByName;
eTrack.remove = remove;

Well, after bundled via webpack, I can access eTrack in window but it turn out to be an object.That means I can't call eTrack() directly, but should call like eTrack.eTrack().

And I've tried @Ambroos's solution, change ./src/method/eTrack/index.js into:

module.exports = function eTrack () {

}

This time after bundled, I can't access eTrack in browser window, the eTrack object gone and it throws eTrack is undefined error in the console.

Then I found an article that helps a lot:http://siawyoung.com/coding/javascript/exporting-es6-modules-as-single-scripts-with-webpack.html

And change my index.js into:

function eTrack () {

}
module.exports = eTrack;

Then everything works as expected!I can call eTrack() directly in <script> tag.Though I don't know the difference between @Ambroos's answer and this solution.

Obligee answered 2/6, 2017 at 9:20 Comment(3)
In webpack 2 you can't mix ES6 imports and CommonJS exports. If you use module.exports you should also use require, and if you use import you should use export paired with it.Innoxious
@Innoxious actually I am using webpack 2, and it worked fine.Obligee
See also: https://mcmap.net/q/127371/-define-global-variable-with-webpackZilla
I
2

Instead of using the ES6 export syntax, try simply using module.exports = function validate() {}, which should work.

Babel is probably why things don't work the way you expect them too right now. Exporting with Babel does the following:

export default function testDefault() {}
export function testNamed() {}

Turns into

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = testDefault;
exports.testNamed = testNamed;
function testDefault() {}
function testNamed() {}

In this case, your exported object would have a default() and testNamed().

Update for webpack 2: In webpack 2 you can't mix ES6 imports and CommonJS exports. If you use module.exports you should also use require, and if you use import you should use export paired with it.

In webpack 2, you cannot use ES6 default exports to make a global available. The most-used solution right now is to make a small entry point that simply does the following:

// assuming myLibraryEntry is the default export in the required file.
const myLibraryEntry = require('./real-entry-point-in-es6.js').default;

// This makes myLibraryEntry available as whatever you set libraryName to in your config.
module.exports = myLibraryEntry;
Innoxious answered 14/6, 2016 at 12:53 Comment(3)
No, it doesn't work.Using module.exports leads to library become undefined in the window.Obligee
But it's not totally wrong, with a little modification we can make it work.Could you please check my answer and correct it if there is any mistake?Obligee
Do you have the typescript version of the webpack 2 solution?Malka
T
1

You can also just register your function on the window object when the module executes. In the index.js file, simply add code like this:

if (!window.myFunction) {
    window.myFunction = () => { alert('Hello My Function'); }
}

That way around, there is no need for extra configuration of webpack.

Tref answered 26/4, 2023 at 12:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.