Prepack: exports is not defined

Created on 4 May 2017  路  8Comments  路  Source: facebook/prepack

I'm running prepack, as a npm script:

"scripts": {
   "prepack": "prepack dist/pareto.cjs.js"
}

in a commonjs file, but I'm getting:

exports is not defined

I'm sorry if this is a stupid question, but I didn't read about anything related in the DOCs.

question

All 8 comments

Prepack is still in development and only has definitions for basic objects described in ECMAScript.
exports is a Node-specific thing which is not specified anywhere in the language spec. Prepack assumes that everything unknown is undefined because reasons, therefore exports.foo is trying to access a property of an undefined global variable.

I've been trying to come up with a hack until we have CommonJS support, but it seems like there's a bug. I'm typing this into the repl:

__assumeDataProperty(global, "exports", {})
exports.foo = 5;

And I'm getting this weird result:

(function () {
  var _0 = this;

  if (_0.exports !== {
    foo: 5
  }) {
    throw new Error("Prepack model invariant violation: " + _0.exports);
  }
}).call(this);

Why is it checking if the exports contents match the stuff I'm assigning later in this file? That doesn't seem right.

If I use __abstract("object") instead of {} in the __assumeDataProperty() arguments, I get this error:

This operation is not yet supported on ::global.exports at foo
__IntrospectionError
    at repl:2:15

What are we missing?

Also, how do we stop Prepack from wrapping the whole file into an IIFE and translating exports into this.exports?

Is this the same reason why I'm getting this error:

'import' and 'export' may appear only with 'sourceType: module' (112:0)
Syntax Error

when trying to prepack a ES module file?

Is this the same reason why I'm getting this error:

It' a different issue. Prepack parses files as scripts, which are not allowed to have import or export statements.

Related to #451.

which are not allowed to have import or export statements

I think its just not implemented yet. Hacked into sourceType argument, it is a hard-coded script string, but clearly an open space for module comes in eventually. There is already type declarations its missing an evaluator.

Workaround for now seams to be calling __residual:

input
const foo = 'foo'
__residual('object', e => module.exports = e, {foo})
output (repl)
(function () {
  function _0(e) {
    return module.exports = e;
  }

  var _1 = {
    foo: "foo"
  };

  var _$0 = _0(_1);

  if (typeof _$0 !== "object" && typeof _$0 !== "function" || _$0 === null) {
    throw new Error("Prepack model invariant violation: " + _$0);
  }
})();
test
const { foo } = require('./foo.js')
console.log(foo) // foo

鈿狅笍 Just a hacky way to play around, you shouldn't be using Prepack right now.

@leocavalcante
That works, but it also outputs way more code than the original module.exports = 'foo'.

@deltaidea Yeah, definitely do not worth it for such small code like exporting a string.
IMHO, Prepack is only specially suited for bundles, because it can't predict what will be called from the public API of a module if it not gets the clients using this module. But, of couse, probably in the near future it would be able to static analyse import/require calls from a entry point (and maybe already generate the bundle? Good bye Webpack?) Let's see.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NTillmann picture NTillmann  路  3Comments

kamranahmedse picture kamranahmedse  路  7Comments

kabirbaidhya picture kabirbaidhya  路  6Comments

sandipp picture sandipp  路  4Comments

jtenner picture jtenner  路  5Comments