benjamn / reify

Enable ECMAScript 2015 modules in Node today. No caveats. Full stop.
MIT License
741 stars 29 forks source link

Overriding Rollup/Babel-compiled `export *` causes error #236

Open klaussner opened 4 years ago

klaussner commented 4 years ago

Re-exporting all exports of a module that was compiled with Rollup or Babel and overriding one of the exports causes a TypeError because Reify attempts to set a read-only property in the exports object. Reproduction repository: https://github.com/klaussner/reify-issue-236.

Rollup input:

export * from "fs";

Rollup output (Babel output is similar):

// rollup-output.js

"use strict";

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

var fs = require("fs");

Object.keys(fs).forEach(function(k) {
  if (k !== "default")
    Object.defineProperty(exports, k, {
      enumerable: true,
      get: function() {
        return fs[k];
      }
    });
});

If the output is used like this with Reify, a TypeError is thrown:

export * from "./rollup-output";
export const existsSync = ":)";
TypeError: Cannot set property existsSync of #<Object> which has only a getter
    at Entry.Ep.runGetters (node_modules/reify/lib/runtime/entry.js:165:33)
    at Entry.Ep.runSetters (node_modules/reify/lib/runtime/entry.js:211:8)
    at Module.runSetters (node_modules/reify/lib/runtime/index.js:115:36)
    at Object.extWrap (node_modules/reify/node/compile-hook.js:57:9)
    at Object.extManager (node_modules/reify/node/compile-hook.js:19:12)
    at Object.manager [as .js] (node_modules/reify/node/wrapper.js:108:20)
    at Module.load (internal/modules/cjs/loader.js:628:32)
    at Function.Module._load (internal/modules/cjs/loader.js:555:12)
    at Module.require (internal/modules/cjs/loader.js:666:19)
    at require (internal/modules/cjs/helpers.js:16:16)
benjamn commented 4 years ago

I think we could solve this by also using Object.defineProperty in the runtime code that sets properties on the exports object (potentially only after simple assignment throws).