score:2

Accepted answer

is there a way such that - for example - i can locally npm run build the needed module, react-datepicker, and then call the react api from my script as shown above?

yes, there is a well known solution!

write an index.js as follows

import react from "react";
import datepicker from 'react-datepicker'
import "react-datepicker/dist/react-datepicker.css";

export {importedcomponent}

window.mydatepicker = function mydatepicker(props) {
    console.log("props from window.mydatepicker", props)
    return react.createelement( datepicker, props );
  }

build via npm and copy the static folder from the build of your by npm run build to the spa folder of your proj

copy the 3 script tags from the index.html in the build into the index.html template of your proj and <div id="root"></div> (of course you use a different id for your project app and there will be nothing to render here)

in my case they are (they will be different for you)

<div id="root"></div>
<script>!function(e){function t(t){for(var n,l,p=t[0],f=t[1],i=t[2],c=0,s=[];c<p.length;c++)l=p[c],object.prototype.hasownproperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in f)object.prototype.hasownproperty.call(f,n)&&(e[n]=f[n]);for(a&&a(t);s.length;)s.shift()();return u.push.apply(u,i||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,p=1;p<r.length;p++){var f=r[p];0!==o[f]&&(n=!1)}n&&(u.splice(t--,1),e=l(l.s=r[0]))}return e}var n={},o={1:0},u=[];function l(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,l),r.l=!0,r.exports}l.m=e,l.c=n,l.d=function(e,t,r){l.o(e,t)||object.defineproperty(e,t,{enumerable:!0,get:r})},l.r=function(e){"undefined"!=typeof symbol&&symbol.tostringtag&&object.defineproperty(e,symbol.tostringtag,{value:"module"}),object.defineproperty(e,"__esmodule",{value:!0})},l.t=function(e,t){if(1&t&&(e=l(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esmodule)return e;var r=object.create(null);if(l.r(r),object.defineproperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)l.d(r,n,function(t){return e[t]}.bind(null,n));return r},l.n=function(e){var t=e&&e.__esmodule?function(){return e.default}:function(){return e};return l.d(t,"a",t),t},l.o=function(e,t){return object.prototype.hasownproperty.call(e,t)},l.p="/";var p=this.webpackjsonpcontent_npm=this.webpackjsonpcontent_npm||[],f=p.push.bind(p);p.push=t,p=p.slice();for(var i=0;i<p.length;i++)t(p[i]);var a=f;r()}([])</script>
<script src="/static/js/2.a6e4c224.chunk.js"></script>
<script src="/static/js/main.b075c560.chunk.js"></script>

now go with

datepicker=react$1.createelement(window.mydatepicker,{
   selected:mydate,
   onchange:p$1[1],
   showtimeselect: true,
  });

in you spa.js and enjoy any react component like this one from websharper.react!

btw i had to pass a js date, not a moment date here in the selected of props, i'm not sure why, anyway, this is not relevant to the problem.

fyi, this is the f# code from websharper project

let mydate, setmydate = wrapreact.usestate (datetime.today.js)
let importdatepicker = js.eval("window.mydatepicker") :?> react.class 
let propdp = 
                {
                    selected = mydate 
                    onchange = setmydate
                    showtimeselect = true
                }
let datepicker =
    react.createelement( importdatepicker, propdp)
wrapreact.setcount <- setcount
div [] [
    
    datepicker
    p [] [html.textf "you selected %s date %s time" (mydate.todatestring()) (mydate.totimestring())]

full open source project shared on github.

score:0

i think that the main problem is that websharper scripts are not javascript modules. in that case it should be immediate to import an external module or make the above spa.js as the webpack main entry. in fact it is well known that there are differences between <script type=module> and <script>

  • module script execute in strict mode
  • module script has its own scope
  • module script can import other javascript modules
  • module script has this as undefined
  • inline module script can have async attribute
  • module script is always deferred

as confirmed by adam granicz indeed on websharper side:

that should be the way, yes, @jand42 and others have been working on changing the current output to support modules and a better ts interoperability - this has been on the agenda for years, so closing it would be a good step forward

(in the meantime there are of course alternatives, e.g. flatpickr, which has bindings also for jquery, instead of react-datepicker or pure react or f# fable instead of websharper.react and so on)


Related Query

More Query from same tag