[bokehjs] Trying to integrate into a TypeScript project

Hi,

I want to integrate BokehJS (as JS only, there will be no Bokeh Server on this project) into a project that is written in TypeScript. The project is create with the typescript template of create-react-app. However I’m running into issues with two approaches I have tried so far:

1. Install @bokeh/bokehjs via npm and include from node_modules

This get quickly into problems as the .js files included in the module are containing export statements that doesn’t seem to supported when including the files. I assume that the module format is different to what the babel loader is expecting to find.

I run into this error:

**./node_modules/@bokeh/bokehjs/build/js/lib/index.js 3:9
Module parse failed: Unexpected token (3:9)
File was processed with these loaders:
 * ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| export { version } from "./version";
| export { index } from "./embed";
> export * as embed from "./embed";
| export * as protocol from "./protocol";
| export * as _testing from "./testing";**

I tried adding some babel plugins like babel-plugin-transform-export-extensions and other (and adding the dir in node_modules to the babel paths of course), but that didn’t seem to change things.

I guess my experience with the complex webpack/babel/typescript/create-react-app interactions are too limitted to go further down that route.

2. Directly including .ts files

I also tried to git clone the most recent bokeh repository and include the .ts files directly and ignoring the .js build files. To do so I configured the tsconfig.json file in this way:

{
  "compilerOptions": {
    "noImplicitAny": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "strictNullChecks": true,
    "strictBindCallApply": false,
    "strictFunctionTypes": false,
    "strictPropertyInitialization": false,
    "alwaysStrict": true,
    "noErrorTruncation": true,
    "noEmitOnError": false,
    "stripInternal": true,
    "declaration": true,
    "sourceMap": true,
    "importHelpers": false,
    "target": "ES2017",
    "lib": [
      "es2017",
      "dom",
      "dom.iterable"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "experimentalDecorators": true,
    "jsx": "react"
  },
  "include": [
    "src/",
    "src/bokehgit/bokehjs/src/lib/**/*.ts"
  ],
  "exclude": [
    "src/bokehgit/bokehjs/src/lib/**/*.js"
  ]
}

I tried to take as many configurations as possible from https://github.com/bokeh/bokeh/blob/master/bokehjs/src/lib/tsconfig.json

However when using that config I also run into problems, but at least the error message is more specific:

./src/bokehgit/bokehjs/src/lib/index.ts
Syntax error: 'from' expected (3:9)

I use the same typescript version as the bokeh package-lock.json file is suggesting: 3.8.3

3. Including the CDN version via <script> tags

I also tried directly including the scripts as described in the docs with:

    <script src="https://cdn.bokeh.org/bokeh/release/bokeh-2.0.2.min.js"
        crossorigin="anonymous"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.0.2.min.js"
        crossorigin="anonymous"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.0.2.min.js"
        crossorigin="anonymous"></script>

And that actuall works. I got a plot working using Bokeh.embed.embed_item. However that has the huge draw back that I have no IDE support when working on Bokeh code in JS files.

Also I wasn’t able to find all objects that are referenced in the docs, like Bokeh.Plotting wasn’t available.

Is there an official/recommended/working way of including BokehJS into a TypeScript project?

I didn’t find much documentation on that other than the docs stating that it can be used standalone :slight_smile:

Maybe has someone else experience with this kind of usage? Or is this just totally out of scope for the project to support using BokehJS without the server?

Yes, it makes sense that it’s not a server side library. However there seem to be many frontend libraries available in NPM that can just be included into a bundle with webpack. For example material-ui or many others (react is also a frontend library).

These don’t seem to run into this issue when using these libraries. When checking with material-ui which is also written in TypeScript, it configures es5 as target instead of ES2017 as BokehJS is doing.

Might that make a difference here? Is there a reason why BokehJS compiles to ES2017?

Pinging @mateusz for possible input.

Also I wasn’t able to find all objects that are referenced in the docs, like Bokeh.Plotting wasn’t available.

You need to add bokeh-api bundle to make this work.

Option (1) should work fine with webpack. bokehjs is compiled from TypeScript to ES modules. If the module system on your side != ES modules, then you need a babel transformer to perform necessary conversions. If that doesn’t work, then it’s most likely a configuration error, but without a config it’s not possible say what’s exactly wrong. You should avoid option (2), because you can’t simply run tsc on bokehjs’ source code, because we use AST transforms to reduce boilerplate, which require a properly configured compiler instance. You would get a non-functional build if you did so.

1 Like