Skip to content

Commit

Permalink
Correctly handle exportes when module.exports get's redefined (#1015)
Browse files Browse the repository at this point in the history
This was broken in 3506ee1, but as this mostly happens in browserified
code I didn't catch it as a problem. Now we get the "exports" once
before we run the script - to be used to resolve import cycles, and once
after the script is ran in order to get the exports if exports gets
redifined in the script.

This is probably broken in the case where both exports is redifined and
there is an import cycle, but the fix for this seems to be some magic
that will need to find out that we are actually requiring a new file and
then to "reexport" the exports before the import? or something like
that.
  • Loading branch information
mstoykov authored May 7, 2019
1 parent 1621aad commit 03645ba
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
2 changes: 2 additions & 0 deletions js/initcontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ func (i *InitContext) requireFile(name string) (goja.Value, error) {
if _, err := i.runtime.RunProgram(pgm.pgm); err != nil {
return goja.Undefined(), err
}

pgm.exports = module.Get("exports")
}

return pgm.exports, nil
Expand Down
65 changes: 65 additions & 0 deletions js/module_loading_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,3 +318,68 @@ func TestLoadCycleBinding(t *testing.T) {
})
}
}

func TestBrowserified(t *testing.T) {
fs := afero.NewMemMapFs()
//nolint: lll
require.NoError(t, afero.WriteFile(fs, "/browserified.js", []byte(`
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.npmlibs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
module.exports.A = function () {
return "a";
}
},{}],2:[function(require,module,exports){
exports.B = function() {
return "b";
}
},{}],3:[function(require,module,exports){
exports.alpha = require('./a.js');
exports.bravo = require('./b.js');
},{"./a.js":1,"./b.js":2}]},{},[3])(3)
});
`), os.ModePerm))

r1, err := New(&lib.SourceData{
Filename: "/script.js",
Data: []byte(`
import {alpha, bravo } from "./browserified.js";
export default function(data) {
if (alpha.A === undefined) {
throw new Error("alpha.A is undefined");
}
if (alpha.A() != "a") {
throw new Error("alpha.A() != 'a' (" + alpha.A() + ") != 'a'");
}
if (bravo.B === undefined) {
throw new Error("bravo.B is undefined");
}
if (bravo.B() != "b") {
throw new Error("bravo.B() != 'b' (" + bravo.B() + ") != 'b'");
}
}
`),
}, fs, lib.RuntimeOptions{})
require.NoError(t, err)

arc := r1.MakeArchive()
arc.Files = make(map[string][]byte)
r2, err := NewFromArchive(arc, lib.RuntimeOptions{})
require.NoError(t, err)

runners := map[string]*Runner{"Source": r1, "Archive": r2}
for name, r := range runners {
r := r
t.Run(name, func(t *testing.T) {
ch := make(chan stats.SampleContainer, 100)
defer close(ch)
vu, err := r.NewVU(ch)
require.NoError(t, err)
err = vu.RunOnce(context.Background())
require.NoError(t, err)
})
}
}

0 comments on commit 03645ba

Please sign in to comment.