can one load reasonml es6 modules without a bundler - reason

I am trying to use my VSCODDE liver server: https://github.com/ritwickdey/vscode-live-server for development without having to run a (parceljs would be my favorite, since it has hot loading, but it is having issues with reasonml).
This almost works, but the the bucklescript compiler expects that the the node-modules to be on the path, and it appears bundlers find them, but not if one does a load this way:
es5index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=utf-8>
<link rel=stylesheet href="./style.css">
<title>Web Data Client</title>
<script src="../src/client/App.bs.js" type=module></script>
</head>
<body>
<div id="index"></div>
</body>
</html>
This is the error I get:
ncaught TypeError: Failed to resolve module specifier "react". Relative references must start with either "/", "./", or "../".
which is to be expected since BSB created this in
App.bs.js
import * as $$Array from "./../../node_modules/bs-platform/lib/es6/array.js";
import * as Block from "./../../node_modules/bs-platform/lib/es6/block.js";
import * as Curry from "./../../node_modules/bs-platform/lib/es6/curry.js";
import * as React from "react";
import * as Glamor from "./../../node_modules/bs-glamor/src/glamor.js";
import * as Js_exn from "./../../node_modules/bs-platform/lib/es6/js_exn.js";
import * as Js_dict from "./../../node_modules/bs-platform/lib/es6/js_dict.js";
import * as Js_json from "./../../node_modules/bs-platform/lib/es6/js_json.js";
import * as ReactDOMRe from "./../../node_modules/reason-react/src/ReactDOMRe.js";
import * as Caml_option from "./../../node_modules/bs-platform/lib/es6/caml_option.js";
import * as ReasonReact from "./../../node_modules/reason-react/src/ReasonReact.js";
import * as Editor$Webdataclient from "./Editor.bs.js";
import * as Loader$Webdataclient from "./Loader.bs.js";
import * as Mutations$Webdataclient from "./Mutations.bs.js";
now if the imports had were from the ../node-modules/* folder, I think all would work
bsconfig.json file:
// This is the configuration file used by BuckleScript's build system bsb.
// Its documentation lives here: http://bucklescript.github.io/bucklescript/docson/#build-schema.json
{
"name": "webdataclient",
"version": "0.1.0",
"sources": [
{
"dir": "src",
"subdirs": true
}
],
"package-specs": {
"module": "es6-global",
"in-source": true
},
"suffix": ".bs.js",
"namespace": true,
"reason": {
"react-jsx": 2
},
"refmt": 3,
"ppx-flags": [
"graphql_ppx/ppx"
],
"bs-dependencies": [
"reason-react",
"bs-fetch",
"bs-glamor"
]
}

It doesn't look like BuckleScript can import external JavaScript modules with es6-global, including React. The relevant GitHub issue is here.
The problem is that BuckleScript currently has no way of knowing the path to the JavaScript file that "react" is supposed to resolve to. BuckleScript knows the paths to the modules it compiles, so they work fine. But it doesn't know anything about externals, so it outputs their paths as-is.

Related

How to treat bootstrap's data-sap-ui-libs vs manifest's sap.ui5/dependencies/libs?

I usually declare all standard libraries that the application depends on in the manifest under sap.ui5/dependencies/libs.
Now what should I put in the bootstrap argument data-sap-ui-libs, the same libraries? What are the effects if I put less / more in data-sap-ui-libs? How do they differ?
PS. I couldn't find this in SAP's documentation, but please proof me wrong. :-)
The bootstrapping (data-sap-ui-libs) is done in the index.html. It only needs to contain the libs which are referenced in the index.html.
If your code looks like this:
new sap.m.Shell({
app: new sap.ui.core.ComponentContainer({
name: "my.namespace.app",
height: "100%"
})
}).placeAt("content");
Then you should require the following libs:
data-sap-ui-libs="sap.m, sap.ui.core"
If your code looks like this:
sap.ui.require([
"sap/m/Shell",
"sap/ui/core/ComponentContainer"
], function(Shell, ComponentContainer) {
new Shell({
app: new ComponentContainer({
name: "my.namespace.app",
height: "100%"
})
}).placeAt("content");
});
You don't need to require anything (but it may affect loading time of your app).
All libraries that are used in the views should be required in the manifest.json. So if you use sap.m in your app you should require it in your manifest.json, even if you've already required it in the index.html.
This is because the Component.js and the manifest.json are the default entry points for an app and the index.html ist just a wrapper for standalone apps outside of a Fiori Launchpad.
What are the effects if I put less/more in data-sap-ui-libs? How do they differ?
My recommendation is to remove data-sap-ui-libs from index.html altogether. Especially if the app is dealing with OData, it's important to retrieve the $metadata document as early as possible. See the example below:
In index.html
<head>
<script id="sap-ui-bootstrap"
src="https://ui5.sap.com/<version>/resources/sap-ui-core.js"
data-sap-ui-theme="sap_horizon"
data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
data-sap-ui-async="true"
data-sap-ui-compatversion="edge"
data-sap-ui-excludejquerycompat="true"
data-sap-ui-resourceroots='{ "demo": "./" }'
data-sap-ui-xx-waitfortheme="init"
></script><!-- No data-sap-ui-lib -->
</head>
<body id="content" class="sapUiBody">
<div style="height: 100%"
data-sap-ui-component
data-name="demo"
data-height="100%"
></div>
</body>
In manifest.json
{
"sap.app": {
"dataSources": {
"myODataSource": {
"uri": "/odata_org/V2/Northwind/Northwind.svc/",
"type": "OData",
"settings": {
"odataVersion": "2.0",
"localUri": "model/metadata.xml",
"annotations": [
"annotation0"
]
}
},
"annotation0": {
"type": "ODataAnnotation",
"uri": "annotation/annotation0.xml",
"settings": {
"localUri": "annotation/annotation0.xml"
}
}
},
"...": "..."
},
"sap.ui5": {
"dependencies": {
"minUI5Version": "1.108.4",
"libs": {
"sap.ui.core": {},
"sap.m": {},
"sap.ui.table": {},
"sap.ui.unified": {}
}
},
"models": {
"": {
"dataSource": "myODataSource",
"settings": {
"preliminaryContext": true,
"tokenHandling": false
},
"preload": true
}
},
"...": "..."
},
"...": "..."
}
Result
As you can see, the $metadata document is being fetched in parallel with the control libraries. This ensures that entities can be requested right away (e.g. in $batch) as soon as the libs are loaded. If libs were declared in data-sap-ui-libs, they'd be loading first, then the $metadata, and then the entities which creates an unnecessary bottleneck.
But even without considering OData, I noticed the page gets already a bit faster when the libs are removed from data-sap-ui-libs. In general, try different approaches and do performance measurements, in addition to documented performance guidelines, and regardless of what people say (including me).
TL;DR
Use data-sap-ui-libs only if:
The app has no Component.js at all.
Modules from libraries other than sap.ui.core are accessed before creating the component (E.g. instantiating sap.m.Shell as a shell for the ComponentContainer)
Otherwise, remove data-sap-ui-libs altogether and maintain /sap.ui5/dependencies/libs only - Especially if the app is supposed to be launched from an app container such as SAP Fiori launchpad (FLP) which skips loading index.html altogether.
See also What happens if a library preload file / library dependencies is not updated in the UI5-manifest?
I would kept them declared on the manifest.
By declaring them on your .html file under the data-sap-ui-libs, you are basically requiring those dependencies right after the UI5 lib is loaded - even before your component is loaded.
By declaring them on your manifest, you are declaring the dependencies for your own component. So, those dependencies are only loaded before the initialization of your component.
As the component should be isolated, you component should not expect to be always used in a standalone mode.

How to get aurelia-cli and Syncfusion non aurelia-syncfusion-bridge to work?

Windows 7 x64
aurelia-cli 0.23.0
syncfusion 14.4.20
jquery 3.1.1
I saw the other question regarding this but it doesn't seem to follow the bootstrap example. I believe Syncfusion should also be setup using the bootstrap example as a template but I cannot seem to get it to work.
My test project is just a new aurelia-cli project with default settings.
I am using the ejDatePicker control as an example.
aurelia.json I added
{
"name": "jsrender",
"path": "../node_modules/jsrender",
"main": "jsrender",
"deps": ["jquery"],
"exports": "$"
},
{
"name": "syncfusion",
"path": "../node_modules/syncfusion-javascript",
"main": "/Scripts/ej/web/ej.web.all.min",
"deps": ["jquery", "jsrender"],
"exports": "$",
"resources": [
"Content/ej/web/ej.widgets.core.min.css",
"Content/ej/web/bootstrap-theme/ej.theme.min.css"
]
}
app.html
<template>
<require from="syncfusion/Content/ej/web/ej.widgets.core.min.css"></require>
<require from="syncfusion/Content/ej/web/bootstrap-theme/ej.theme.min.css"></require>
<!--Container for ejDatePicker widget-->
<input id="startDate" type="text" />
</template>
app.js
export class App {
constructor(){
$("#startDate").ejDatePicker();
}
}
main.js
import 'jquery';
import 'jsrender'
import 'syncfusion'
......
I am not getting any errors but the control is not displaying. However if I remove the suncfusion config from aurelia.json then $("#startDate").ejDatePicker(); complains that ejDatePicker is not valid so to me that means that the config in aurelia.json is pulling in the correct javascript file.
I had the $("#startDate").ejDatePicker(); in the constructor instead of attached(). It is working after I made that change.

How to Integrate MathJax with Ionic2

I'm getting template parsing errors while integrating MathJax into Ionic2 please help me with this,
package.json
"dependencies": {
.....
"mathjax": "^2.7.0"
},
home.ts
import mj from "mathjax";
home.html
<ion-card-title> Name </ion-card-title>
<span> When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrtb^2-4ac \over 2a.}$$</span>
<button (click)= render()> Render Katex</button>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: 'inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>
<script type="text/javascript" async src="../../../node_modules/mathjax/MathJax.js?config=TeX-MML-AM_CHTML"></script>
https://www.npmjs.com/package/#types/mathjax
You need to install typescript declarations.
Try
npm install #types/mathjax --save
check out this question
I have been googling "Integrating MathJax in ionic 3 offline" for last 2 days. All I found that is I have to use a directive to achieve that. But this approach is not fast for such an app which has lots of mathematical equation. So I came up with another solution:
download MathJax offline file from here, extract and rename that with MathJax and place the whole folder in www/assets folder of your ionic app.
add the code given below in the head section of index.html file
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
imageFont: null,
extensions: ["tex2jax.js"],
jax: ["input/TeX","output/HTML-CSS"],
tex2jax: {inlineMath: [["$","$"],["\\(","\\)"]]}
});
</script>
<script type="text/javascript" async
src="assets/MathJax/MathJax.js">
</script>
now for every page where you want to load mathematical equation, just paste the code below.
ionViewDidEnter() {
eval('MathJax.Hub.Queue(["Typeset", MathJax.Hub])');
}
By doing these three steps you will have integrated MathJax successfully.
But the problem is the size of MathJax folder is so big. You can reduce the size up to 3mb by just having the following directories and files
MathJax.js
extensions
fonts
HTML-CSS
TeX
eof
otf
svg
jax
element
input
TeX
output
HTML-CSS
autoload
config.js
fonts
TeX
imageFonts.js
jax.js
In your index.html file, add following script...
`
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
showProcessingMessages: false,
tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] }
});
</script>
<script type="text/javascript" async src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_HTMLorMML">
</script>
Then make a directive for mathjax as follows
import {Directive, ElementRef, Input} from '#angular/core';
declare var MathJax: {
Hub: {
Queue: (param: Object[]) => void
}}
#Directive({selector: '[MathJax]'})
export class MathJaxDirective {
#Input('MathJax') MathJaxInput: string = "";
constructor(private el: ElementRef) {
}
ngOnChanges() {
this.el.nativeElement.innerHTML = this.MathJaxInput;
MathJax.Hub.Queue(["Typeset", MathJax.Hub, this.el.nativeElement]);
}
}
Then in app.module.ts
import {MathJaxDirective} from "... to use it in you entire app
For a condition if you have multiple modules then make a commonModule something like
import { NgModule } from "#angular/core";
import { MathJaxDirective } from "./directives/MathJax.directive";
#NgModule({
declarations: [MathJaxDirective],
exports: [MathJaxDirective]
})
export class CommonModule { }
and import this module in the required module
Now you are good to go
just in your .html
<div [Mathjax]="sometxt">{{ sometxt }}</div>
and in your .ts
sometxt: string = "$$someLatex"
Hope, this will help someone

Problems with i18n with Play App 2.4.6

I have one simple project with Play Framework 2.4.6 that have internationalization configured as documentation on Play describe.
My files are that:
1) Controller:
package controllers
import play.api._
import play.api.mvc._
import play.api.i18n.{I18nSupport,MessagesApi,Messages,Lang}
import play.api.i18n.Messages.Implicits._
import play.api.Play.current
import javax.inject.Inject
class Application #Inject()(val messagesApi: MessagesApi) extends Controller with I18nSupport {
def index = Action { implicit request =>
Ok(views.html.index("Your new application is ready."))
}
}
2) Message resource file:
application.name = Orthoclinic
welcome = Welcome to play!
3) Main template:
#(title: String)(content: Html)(implicit messages: Messages)
<!DOCTYPE html>
<html lang="en">
<head>
<title>#title</title>
<link rel="stylesheet" media="screen" href="#routes.Assets.versioned("/assets/stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="#routes.Assets.versioned("/assets/images/favicon.png")">
<script src="#routes.Assets.versioned("/assets/javascripts/hello.js")" type="text/javascript"></script>
</head>
<body>
#Messages("application.name")
#content
</body>
</html>
4) Index template:
#(message: String)
#main("Welcome to Play") {
#play20.welcome(message)
}
5) routes file:
# Home page
GET / controllers.Application.index
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
6) Application conf file:
play.crypto.secret = "k1mIneaPlay_pRoJ"
play.i18n.langs = [ "en", "en-us", "pt-br", "es" ]
Calling ./activator reload compile run my result is that:
[error] /home/josenildo/scala-ide/workspace/orthoclinic-app/app/views/main.scala.html:13: could not find implicit value for para
meter messages: play.api.i18n.Messages
[error] #Messages("application.name")
I have followed the documentation for i18n last version on Play Documentation here.
What's the problem on that implementation?
You just need to add the implicit messages argument to your index.scala.html template:
#(message: String)(implicit messages: Messages)
#main("Welcome to Play") {
#play20.welcome(message)
}
An implicit Messages instance needs to be in-scope whenever you use i18n via #Messages("my.key"), which has a corresponding implicit messages argument that will be supplied by the compiler (see the signature here).
Also, you may want to get rid of import play.api.i18n.Messages.Implicits._, since it shouldn't be required if your controller extends I18NSupport, and indeed may cause an error concerning ambiguous implicit values.

How to use Angular2 and Typescript in Jsfiddle

Dummy question ...
I try to code an angular2 (2.0.0-beta.6) app in Typescript in jsfiddle.
I know that there is other solution online but ...
In fact, my example is very small and the problem is on import module :
import {bootstrap} from 'angular2/platform/browser'
import {Component} from 'angular2/core';
I got the following error :
Uncaught ReferenceError: System is not defined
Uncaught ReferenceError: require is not defined
I try to add some dependencies (require, system ...) but it doesn't work.
And there is no more Self-Executing bundle for recent version (beta-6) of Angular2 (angular2.sfx.dev.js).
Some tests :
https://jsfiddle.net/asicfr/q8bwosfn/1/
https://jsfiddle.net/asicfr/q8bwosfn/3/
https://jsfiddle.net/asicfr/q8bwosfn/4/
https://jsfiddle.net/asicfr/q8bwosfn/5/
https://jsfiddle.net/asicfr/q8bwosfn/6/
In Plunker you can just use the menu
New > Angularjs > 2.0.x (TS)
to get a minimal working Angular2 application
Router
If you want to use the router add in config.js
'#angular/router': {
main: 'router.umd.js',
defaultExtension: 'js'
},
<base href="."> as first child in the <head> of index.html might be necessary as well.
To switch to HashLocationStrategy change main.ts from
import {bootstrap} from '#angular/platform-browser-dynamic';
import {App} from './app';
bootstrap(App, [])
.catch(err => console.error(err));
to
import {bootstrap} from '#angular/platform-browser-dynamic';
import {App} from './app';
import {provide} from '#angular/core'
import {ROUTER_PROVIDERS} from '#angular/router';
import {LocationStrategy, HashLocationStrategy} from '#angular/common';
bootstrap(App, [ROUTER_PROVIDERS, provide(LocationStrategy, {useClass: HasLocationStrategy}])
.catch(err => console.error(err));
If you are not tied to JS Fiddle, consider Plunker instead. The Angular devs keep a bare workspace up to date with new Angular releases at this link.
It is more current than even Plunker's own Angular 2 setup (which you can access from the Plunker menu: New > AngularJS > 2.0.x (TS)
The downside: that setup is in TypeScript, so if you wish to develop with vanilla Javascript (ES5 or ES6), your best bet is to use the Plunker menu option instead.
You need also to include SystemJS JS file. I saw that you missed it. All these includes are necessary:
<script src="https://code.angularjs.org/2.0.0-beta.3/angular2-polyfills.js"></script>
<script src="https://code.angularjs.org/tools/system.js"></script>
<script src="https://code.angularjs.org/tools/typescript.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.3/Rx.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.3/angular2.dev.js"></script>
You also need then to configure SystemJS with the following code and then import your main module containing the bootstrap function:
System.config({
transpiler: 'typescript',
typescriptOptions: { emitDecoratorMetadata: true },
packages: {
'app': {
defaultExtension: 'ts'
}
}
});
System.import('app/main')
.then(null, console.error.bind(console));