{"action":"closed","issue":{"url":"https://api.github.com/repos/fable-compiler/fable-electron/issues/4","repository_url":"https://api.github.com/repos/fable-compiler/fable-electron","labels_url":"https://api.github.com/repos/fable-compiler/fable-electron/issues/4/labels{/name}","comments_url":"https://api.github.com/repos/fable-compiler/fable-electron/issues/4/comments","events_url":"https://api.github.com/repos/fable-compiler/fable-electron/issues/4/events","html_url":"https://github.com/fable-compiler/fable-electron/issues/4","id":184593689,"number":4,"title":"Dynamic vs. Foreign Interfaces with Electron","user":{"login":"aolney","id":4432084,"avatar_url":"https://avatars.githubusercontent.com/u/4432084?v=3","gravatar_id":"","url":"https://api.github.com/users/aolney","html_url":"https://github.com/aolney","followers_url":"https://api.github.com/users/aolney/followers","following_url":"https://api.github.com/users/aolney/following{/other_user}","gists_url":"https://api.github.com/users/aolney/gists{/gist_id}","starred_url":"https://api.github.com/users/aolney/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aolney/subscriptions","organizations_url":"https://api.github.com/users/aolney/orgs","repos_url":"https://api.github.com/users/aolney/repos","events_url":"https://api.github.com/users/aolney/events{/privacy}","received_events_url":"https://api.github.com/users/aolney/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2016-10-21T23:56:17Z","updated_at":"2016-10-22T15:00:45Z","closed_at":"2016-10-22T15:00:45Z","body":"In trying to port the webGLTerrain sample to Electron, I find that the dynamic method of interacting with js works but the foreign interface method does not. I wonder if this is a limitation of Fable or if I'm doing something wrong (probably).\r\n\r\nI'm specifically working with the `ImprovedNoise.js` which I've put in `apps/js`. `ImprovedNoise` is a function (`unit -> obj`) that returns an object with a single available function `noise` (`x:float * y:float * z:float -> float`).\r\n\r\nThe [original sample uses requirejs in its `index.html`](https://github.com/fable-compiler/Fable/blob/master/samples/browser/webGLTerrain/index.html) which seems to put things in a global scope.\r\n\r\nMy `index.html` has just one script `<script src=\"js/renderer.js\"></script>`\r\n\r\nI had a problem getting any exported function out of `ImprovedNoise.js`, so I changed the first line from `var ImprovedNoise = function () {` to  `exports.ImprovedNoise = function () {`\r\n\r\nSo with that change, I can get the dynamic approach to work as below.\r\n\r\n**Dynamic (working)**\r\n`renderer.fsx` is\r\n\r\n```\r\n#r \"../node_modules/fable-core/Fable.Core.dll\"\r\n#load \"../node_modules/fable-import-three/Fable.Import.Three.fs\"\r\n\r\nopen Fable.Import\r\nopen System\r\nopen Fable.Core\r\nopen Fable.Core.JsInterop\r\n\r\nlet ImprovedNoise = importMember<unit->obj>(\"../app/js/ImprovedNoise.js\")\r\nlet noise = ImprovedNoise() //call the function; now we have an object containing the function we want\r\nlet output = noise?noise$(1.4,2.3,3.6) //call the function\r\nBrowser.console.log(output);\r\n```\r\n\r\nThe emitted js is \r\n\r\n```\r\n/***/ function(module, exports, __webpack_require__) {\r\n\r\n\t\"use strict\";\r\n\t\r\n\texports.__esModule = true;\r\n\texports.output = exports.noise = exports.t = exports.ImprovedNoise = undefined;\r\n\t\r\n\tvar _ImprovedNoise = __webpack_require__(2);\r\n\t\r\n\tvar ImprovedNoise = exports.ImprovedNoise = _ImprovedNoise.ImprovedNoise;\r\n\tvar t = exports.t = 1 + 1;\r\n\tconsole.log(t);\r\n\tvar noise = exports.noise = ImprovedNoise();\r\n\tconsole.log(t);\r\n\tvar output = exports.output = noise.noise(1.4, 2.3, 3.6);\r\n\tconsole.log(output);\r\n\r\n\r\n/***/ },\r\n/* 1 */,\r\n/* 2 */\r\n/***/ function(module, exports) {\r\n\r\n\t// http://mrl.nyu.edu/~perlin/noise/\r\n\t\r\n\texports.ImprovedNoise = function () {\r\n```\r\nAs can be seen, `_ImprovedNoise.ImprovedNoise;` makes the function accessible.\r\n\r\n**Foreign Interface (not working)**\r\nUsing the same approach as in this sample originally, I found that the `ImprovedNoise.js` code was not being brought in by webpack at all. So I used `importDefault` as below, not binding the result to anything, as was suggested in [this sample](https://github.com/fable-compiler/fable-electron/blob/ee76face7cb4fd9d5a93459eea9e33bda5256d49/samples/react-todomvc/src/renderer.fsx)\r\n\r\nUnfortunately, while it gets the function in the right place in `renderer.js`, it isn't wired up in a way that makes it usable.\r\n\r\n```\r\n#r \"../node_modules/fable-core/Fable.Core.dll\"\r\n#load \"../node_modules/fable-import-three/Fable.Import.Three.fs\"\r\n\r\nopen Fable.Import\r\nopen System\r\nopen Fable.Core\r\nopen Fable.Core.JsInterop\r\n\r\n/// Represents the API exposed by ImprovedNoise script\r\ntype IPerlin =\r\n    abstract noise: x:float * y:float * z:float -> float\r\n\r\n[<Global>]\r\nlet ImprovedNoise(): IPerlin = jsNative\r\n\r\nimportDefault(\"../app/js/ImprovedNoise.js\") //to attach the js via webpack\r\n\r\nlet perlin = ImprovedNoise()\r\nlet output = perlin.noise(1.4,2.3,3.6) \r\nBrowser.console.log(output);\r\n```\r\nThe emitted js:\r\n\r\n```\r\n/***/ function(module, exports, __webpack_require__) {\r\n\r\n\t\"use strict\";\r\n\t\r\n\texports.__esModule = true;\r\n\texports.output = exports.perlin = exports.t = undefined;\r\n\t\r\n\tvar _ImprovedNoise = __webpack_require__(2);\r\n\t\r\n\tvar _ImprovedNoise2 = _interopRequireDefault(_ImprovedNoise);\r\n\t\r\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\r\n\t\r\n\t_ImprovedNoise2.default;\r\n\tvar t = exports.t = 1 + 1;\r\n\tconsole.log(t);\r\n\tvar perlin = exports.perlin = ImprovedNoise();\r\n\tconsole.log(t);\r\n\tvar output = exports.output = perlin.noise(1.4, 2.3, 3.6);\r\n\tconsole.log(output);\r\n\r\n\r\n/***/ },\r\n/* 1 */,\r\n/* 2 */\r\n/***/ function(module, exports) {\r\n\r\n\t// http://mrl.nyu.edu/~perlin/noise/\r\n\t\r\n\texports.ImprovedNoise = function () {\r\n\t\r\n```\r\n\r\nAs you can see, there is an `ImprovedNoise()` function that is not wired up to the function in `ImprovedNoise.js`\r\n\r\nIs there a way to make this connect up? It seems that foreign interfaces work in electron when distributed as node modules (many examples of this), so I'd think there would be a way of making it work here. I'm a newb on pretty much everything js, so the answer is not obvious to me."}}
{"actor":{"display_login":"aolney"}}