Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack es5 commonjs module results in empty exports object #25

Open
maybeec opened this issue Jun 22, 2017 · 16 comments
Open

webpack es5 commonjs module results in empty exports object #25

maybeec opened this issue Jun 22, 2017 · 16 comments

Comments

@maybeec
Copy link

maybeec commented Jun 22, 2017

I am trying to call a small library build with webpack2. It is configured to result in a es5, commonjs bundle. I am using nashorn-commonjs-module to import it by evaluating module = require('importModule');.
importModule contains a default export to a function served as the API, which I want to call.

However, module is evaluate to an empty object. There are no exports, nothing... any idea? Did I get something wrong?

@malaporte
Copy link
Owner

Hmm hard to say without seeing any code, but maybe you could step through the loading process in Module and confirm that it's indeed loading the proper file as root, and that this file adds symbols to exports ?

@maybeec
Copy link
Author

maybeec commented Jun 22, 2017

I could not see any gathering of exports during debugging. However, maybe I missed something.
Here is my code: https://github.com/maybeec/ts-merger
Here is the built js file with webpack in non-production mode to not have method names uglified for now:
tsmerger.zip
I wanted to call the default exported merge function utilizing nashorn. However, I am not able to get access. There is nothing in the scope after evaluating merge = require('tsmerger.js'). I have written my own dummy folder to just retrieve the script as a commonjs file: https://github.com/maybeec/nashorn-test-commonjs

@maybeec
Copy link
Author

maybeec commented Jul 10, 2017

I debuged a little further. The commonjs-module returns an object of type jdk.nashorn.api.scripting.ScriptObjectMirror with property sobj of type jdk.nashorn.internal.scripts.JO containing the property mapwith toString()=

0x71956711 = {
	merge                id=0x457758e8 (0x0   ) SpillProperty {o    } [slot=0]
	default              id=0x4b222f17 (0x0   ) SpillProperty {o    } [slot=1]
}

After that, I cannot see any code from NashornScriptEngine to check further binding resolution. But it seems to be a binding issue. How are the properties returned by commonjs-module injected into the jjs environment?

engine.eval("require('ts-merger.js');");
engine.eval("print(JSON.stringify(merge));");

results in Caused by: <eval>:1 ReferenceError: "merge" is not defined.

engine.eval("merge = require('ts-merger.js');");
engine.eval("print(JSON.stringify(merge));");

results in merge to be an empty object {}.

Can you help me to identify how to access the bindings passed by commonjs-module?

@malaporte
Copy link
Owner

I've seen cases before where Nashorn seemed unable to resolve a property of an object that really seems to be there. I'll try to have a look when I have a minute but those are usually tricky. What JVM version are you using? I remember that one previous such issue was fixed by upgrading to a more recent one.

@maybeec
Copy link
Author

maybeec commented Jul 11, 2017

Sounds ugly.
My current JVM is

java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

@malaporte
Copy link
Owner

OK pretty recent then. The one with an issue was much earlier than this (around _3x I think).

Well, I'll try to have a look. Did you try "reducing" the JS file to pinpoint the pattern that is causing an issue? Or maybe creating a dummy library built with webpack that contains almost no code?

@maybeec
Copy link
Author

maybeec commented Jul 11, 2017

I can try to come up with a minimal example.

@maybeec
Copy link
Author

maybeec commented Jul 11, 2017

A minimal example of a webpack generated bundle (commonjs, es5):

(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap
/******/  // The module cache
/******/  var installedModules = {};
/******/
/******/  // The require function
/******/  function __webpack_require__(moduleId) {
/******/
/******/    // Check if module is in cache
/******/    if(installedModules[moduleId]) {
/******/      return installedModules[moduleId].exports;
/******/    }
/******/    // Create a new module (and put it into the cache)
/******/    var module = installedModules[moduleId] = {
/******/      i: moduleId,
/******/      l: false,
/******/      exports: {}
/******/    };
/******/
/******/    // Execute the module function
/******/    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/    // Flag the module as loaded
/******/    module.l = true;
/******/
/******/    // Return the exports of the module
/******/    return module.exports;
/******/  }
/******/
/******/
/******/  // expose the modules object (__webpack_modules__)
/******/  __webpack_require__.m = modules;
/******/
/******/  // expose the module cache
/******/  __webpack_require__.c = installedModules;
/******/
/******/  // define getter function for harmony exports
/******/  __webpack_require__.d = function(exports, name, getter) {
/******/    if(!__webpack_require__.o(exports, name)) {
/******/      Object.defineProperty(exports, name, {
/******/        configurable: false,
/******/        enumerable: true,
/******/        get: getter
/******/      });
/******/    }
/******/  };
/******/
/******/  // getDefaultExport function for compatibility with non-harmony modules
/******/  __webpack_require__.n = function(module) {
/******/    var getter = module && module.__esModule ?
/******/      function getDefault() { return module['default']; } :
/******/      function getModuleExports() { return module; };
/******/    __webpack_require__.d(getter, 'a', getter);
/******/    return getter;
/******/  };
/******/
/******/  // Object.prototype.hasOwnProperty.call
/******/  __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/  // __webpack_public_path__
/******/  __webpack_require__.p = "";
/******/
/******/  // Load entry module and return exports
/******/  return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });

function merge(patchOverrides, baseContents, patchContents, resultFile, encoding) {
    return "RETURNVAL";
}
exports.merge = merge;
exports.default = merge;


/***/ })
/******/ ])));

@maybeec
Copy link
Author

maybeec commented Jul 27, 2017

Any news? ;)
I could not find any more information about this as I could not dig into nashorn code at all due to missing source code. :(

@malaporte
Copy link
Owner

To be honest I didn't had time to look deeper into this... I just bought a new house and for a few weeks every shred of spare time my job & kids leave me has been spent ripping out old wallpaper, patching holes, moving furniture, and other such highly entertaining activities.

Believe me when I say I'd rather be coding 😁

@maybeec
Copy link
Author

maybeec commented Aug 1, 2017

😁 no problem. Have fun!
Maybe I will get it to work in some point in time when I have new ideas how to proceed here.
If so, I will keep you updated.

@maybeec
Copy link
Author

maybeec commented Aug 10, 2017

I finally got it to work. Here is the way of how to call functions within a webpack module using nashorn: https://stackoverflow.com/questions/38623186/how-can-i-invoke-a-method-from-nashorn-with-a-webpack-js-file

@maybeec maybeec closed this as completed Aug 10, 2017
@malaporte
Copy link
Owner

Wait, but it worked in Node right? Just tried your minimal sample above and if I require it I can definitively access the merge function defined inside. This lib should have the same behavior as Node on that regard.

I'm curious, what did you change exactly on your side to get it to work (I'm not familiar with Webpack much)?

I'll keep the issue opened to see if I can implement a proper fix in any case - once I'm done with all three bedrooms.

@malaporte malaporte reopened this Aug 11, 2017
@micmicsuarez
Copy link

micmicsuarez commented Oct 3, 2019

Hi @maybeec,

I followed the solution on the link provided but it doesn't work on my end.

Regards,
Michael

@maybeec
Copy link
Author

maybeec commented Oct 3, 2019

Hi,

This thread is already quite old.
But maybe you can find a helpful tip on my code calling the script here:
https://github.com/devonfw/tools-cobigen/blob/cobigen-tsplugin/v2.1.0/cobigen/cobigen-tsplugin/src/main/java/com/devonfw/cobigen/tsplugin/merger/TypeScriptMerger.java#L92

Best Regards
Malte

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants