purs-loader icon indicating copy to clipboard operation
purs-loader copied to clipboard

Initial sketch of main function support

Open ethul opened this issue 8 years ago • 2 comments

@sgentle @Pauan

Sketch on resolving #33. Initial thoughts?

Thanks!

ethul avatar Nov 06 '16 20:11 ethul

Thanks for taking a look. I am still experimenting with this, but it seems useful to pass in the module to the main in order to allow the entry to invoke "accept" when HMR for webpack is enabled. I didn't immediately see a way to do this strictly in an FFI function. I am open to ideas though!

On Wednesday, 9 November 2016, Pauan [email protected] wrote:

@Pauan commented on this pull request.

In src/index.js https://github.com/ethul/purs-loader/pull/72#pullrequestreview-7758338:

@@ -182,6 +183,12 @@ function toJavaScript(psModule) { }) }

  • const main = options.mainModule[psModule.name];
  • if (main) {
  •  js = `${js}\nmodule.exports.${main}(module)();`;
    

Why does this call the function with module? Isn't module.exports.${main} an Eff?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ethul/purs-loader/pull/72#pullrequestreview-7758338, or mute the thread https://github.com/notifications/unsubscribe-auth/AAVYy2yjJSK-dQEsYhtRcfkMjpbgbs18ks5q8VmKgaJpZM4KqrCt .

ethul avatar Nov 09 '16 12:11 ethul

To clarify, here is the example entry I was working with:

Example.purs

module Example (Module, example) where

import Prelude (Unit, (>>=), bind, unit, void)

import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)

import DOM.Node.Types (Element)
import DOM (DOM)

import React (createElement)
import ReactDOM (render, renderToString)

import Example.App (app)

example :: forall eff. Module -> Eff (dom :: DOM, console :: CONSOLE | eff) Unit
example module_ = do
  let appEl = createElement app unit []

  if isServerSide
     then void (log (renderToString appEl))
     else void (getElementById "app" >>= render appEl)

  hot module_

foreign import isServerSide :: Boolean

foreign import getElementById :: forall eff. String -> Eff eff Element

foreign import hot :: forall eff. Module -> Eff eff Unit

foreign import data Module :: *

Example.js

'use strict';

exports.isServerSide = typeof document === 'undefined';

exports.getElementById = function(id) {
  return function(){
    return document.getElementById(id);
  };
};

exports.hot = function(module) {
  return function(){
    if (module.hot) {
      module.hot.accept();
    }
  };
}

webpack.config.js

...
{ test: /\.purs$/
, loader: 'purs-loader'
, query: { src: [ 'bower_components/purescript-*/src/**/*.purs', 'src/**/*.purs' ]
          ...
          , mainModule: { Example: 'example' }
          }
}
...

ethul avatar Nov 09 '16 13:11 ethul