Repository: bokeh/bokeh

Issue:
Custom extensions cannot import models/widgets/widget
As part of panel we are shipping various custom models, generally that works perfectly but it seems when I export a plot containing custom models to a static HTML file it fails to resolve certain modules, specifically this line raises errors:

          var widget_1 = require("models/widgets/widget"); 

while other imports seem to work just fine, e.g.:

          var p = require("core/properties");

I'm really not quite sure how best to provide a minimal reproducible example, so [here](http://assets.holoviews.org/temp/Panel.html) is the exported HTML file, [here](https://github.com/pyviz/panel/blob/master/panel/models/audio.ts) is the custom model definition and here is the traceback:

```
Uncaught Error: Cannot find module 'models/widgets/widget'
    at s (Panel.html:93)
    at Object.custom/panel.models.widgets.audio (Panel.html:358)
    at s (Panel.html:93)
    at Object.custom/main (Panel.html:147)
    at s (Panel.html:93)
    at Object.t.Bokeh.r.register_plugin (Panel.html:93)
    at outer (Panel.html:137)
    at Panel.html:142
    at Panel.html:132
    at Panel.html:133
```


Discussion:
This may or may not be related to this error I get when I try to import the Widget model like this: 

```
import {Widget} from "models/widgets"
```

```
Compilation failed:

../../../bokeh/bokeh/server/static/js/types/models/widgets/date_picker.d.ts:3:26 - error TS2307: Cannot find module 'pikaday'.

3 import * as Pikaday from "pikaday";
```
cc @mattpap 
> `import {Widget} from "models/widgets"`

This is an unfortunate limitation, you will have to use the canonical module path `models/widgets/index` for now. This should have been fixed awhile ago, because I've been fining my self tripping over this.
>  error TS2307: Cannot find module 'pikaday'.

This is a bug. All those external libraries shouldn't be part of the public API. I though I already fix all instances.
>This is an unfortunate limitation, you will have to use the canonical module path models/widgets/index for now. This should have been fixed awhile ago, because I've been fining my self tripping over this.

Thanks, that makes sense, I think it's reasonable to have to import a specific module. I only tried this because I was hoping it would be able to resolve the original issue, but even ``models/widgets/index`` won't work due to the pikaday issue.
Okay, I removed the DatePicker widget from the ``widgets/index.ts`` which got rid of the pikaday issue but it's still failing to resolve the module in the exported HTML:

```
 Cannot find module 'models/widgets/index'
```
There is no widgets bundle in that HTML file, so it fails correctly. bokeh automatically adds it when a model inheriting `Widget` is being used, though I'm not sure how panel handles this.
Ah, that makes total sense! The problem I guess is that it still bundles custom models even if they are not used, which can lead to situations like this where the bokeh widgets bundle isn't included but custom models which subclass from a widget are bundled and cause errors.
The simple solution would be to filter the custom models that are bundled based on the models that are actually included in the document. In a server session that could be problematic though since a custom model may be added after the page is loaded.
In server and notebook setup we need to include everything, but in standalone HTML case we can be selective, and we already are with widgets, etc., so there is no reason to not be selective with custom models as well.
> so there is no reason to not be selective with custom models as well.

Okay, is that something you could handle very quickly? Otherwise could you point me to the relevant parts of the code and I can work up a PR.
@mattpap Unless you tell me otherwise I'll try to figure out a fix inside ``bundle_for_objs_and_resources`` and will submit a PR.
Actually I'm finishing a PR right now.
You're amazing!

Resolving patch:
diff --git a/bokeh/util/compiler.py b/bokeh/util/compiler.py
--- a/bokeh/util/compiler.py
+++ b/bokeh/util/compiler.py
@@ -597,7 +597,9 @@ def mkpath(module, ext=""):
                     extra_modules[sig] = True
                     modules.append((sig, code, deps_map))
             else:
-                raise RuntimeError("no such module: %s" % module)
+                index = module + ("" if module.endswith("/") else "/") + "index"
+                if index not in known_modules:
+                    raise RuntimeError("no such module: %s" % module)
 
         return resolved
 
diff --git a/sphinx/source/docs/user_guide/examples/extensions_example_wrapping.py b/sphinx/source/docs/user_guide/examples/extensions_example_wrapping.py
--- a/sphinx/source/docs/user_guide/examples/extensions_example_wrapping.py
+++ b/sphinx/source/docs/user_guide/examples/extensions_example_wrapping.py
@@ -17,7 +17,7 @@
 
 import {LayoutDOM, LayoutDOMView} from "models/layouts/layout_dom"
 import {ColumnDataSource} from "models/sources/column_data_source"
-import {LayoutItem} from "core/layout/index"
+import {LayoutItem} from "core/layout"
 import * as p from "core/properties"
 
 declare namespace vis {


Test patch: