Skip to content

Commit 9d98980

Browse files
authored
Drop support for route.bundle (#464)
* chore: remove bundle logic * chore: remove bundle docs * chore: move dynamic imports doc to the top * chore: regenerate analysis.json * chore: remove bundle tests
1 parent 62bd9ab commit 9d98980

File tree

7 files changed

+151
-468
lines changed

7 files changed

+151
-468
lines changed

analysis.json

Lines changed: 103 additions & 103 deletions
Large diffs are not rendered by default.

demo/vaadin-router-code-splitting-demos.html

Lines changed: 46 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -6,110 +6,6 @@
66
}
77
</style>
88

9-
<h3>Lazy Loading JS Bundles</h3>
10-
<p>
11-
Vaadin Router works great with code splitting. If your build tool allows
12-
you to split your code into various bundles which can then be loaded on
13-
demand, Vaadin Router can load these bundled lazily just-in-time before
14-
rendering a route.
15-
In order to use this feature specify a bundle URL in the <code>bundle
16-
</code> property of the route object.
17-
</p>
18-
<p>
19-
By default Vaadin Router loads route bundles as regular JavaScript files (async),
20-
but it supports ES module bundles as well. In order to use a ES module as a route bundle,
21-
set the <code>bundle</code> property to an object with the following structure:
22-
<marked-element>
23-
<script type="text/markdown">
24-
```js
25-
{
26-
bundle: {
27-
module: '/bundle.esm.js', // for browsers supporting ES modules
28-
nomodule: '/bundle.es5.js' // fallback for older browsers
29-
}
30-
}
31-
```
32-
</script>
33-
</marked-element>
34-
<p>
35-
Note: If the bundle URL does not end with <code>.js</code> nor with <code>
36-
.mjs</code>, Vaadin Router throws an <code>Error</code> and does not
37-
attempt to load it. Use a custom route action as shown in the next demo if
38-
you need to load non-js bundles.
39-
</p>
40-
<p>
41-
This demo shows how to load the <code>user.bundle.js</code>
42-
script which defines the custom element for the <code>/user/:id</code> route.
43-
Check the network tab in the browser DevTools to see that the script is
44-
loaded only after clicking the <code>/user/guest</code> link.
45-
</p>
46-
<vaadin-demo-snippet id="vaadin-router-code-splitting-1" iframe-src="iframe.html">
47-
<template preserve-content>
48-
<a href="/">Home</a>
49-
<a href="/user/guest">User Profile</a>
50-
<div id="outlet"></div>
51-
<script>
52-
// import {Router} from '@vaadin/router'; // for Webpack / Polymer CLI
53-
// const Router = Vaadin.Router; // for vaadin-router.umd.js
54-
55-
const router = new Router(document.getElementById('outlet'));
56-
router.setRoutes([
57-
{path: '/', component: 'x-home-view'},
58-
{
59-
path: '/user/:id',
60-
bundle: `${Vaadin.Demo.componentsRoot}/user.bundle.js`,
61-
component: 'x-user-js-bundle-view' // <-- defined in the bundle
62-
},
63-
]);
64-
</script>
65-
</template>
66-
</vaadin-demo-snippet>
67-
68-
<h3>Lazy Loading non-JS Bundles, e.g. HTML Imports</h3>
69-
<p>
70-
In cases when loading <code>.js</code> and <code>.mjs</code> is not
71-
enough&mdash;most notably, when using HTML imports in Polymer-based
72-
apps&mdash;the lazy loading feature can be implemented with a custom route
73-
action (for more details see <a href="#vaadin-router-route-actions-demos">
74-
Route Actions</a>).
75-
</p>
76-
<p>
77-
This demo shows a way to lazily add an HTML import. The <code>user.bundle.html</code>
78-
file contains entire Polymer 2 component definition including a template, a class,
79-
and a script that defines a custom element.
80-
</p>
81-
<vaadin-demo-snippet id="vaadin-router-code-splitting-2" iframe-src="iframe.html">
82-
<template preserve-content>
83-
<link rel="import" href="../../polymer/lib/utils/import-href.html">
84-
<a href="/">Home</a>
85-
<a href="/user/admin">User Profile</a>
86-
<div id="outlet"></div>
87-
<script>
88-
// import {Router} from '@vaadin/router'; // for Webpack / Polymer CLI
89-
// const Router = Vaadin.Router; // for vaadin-router.umd.js
90-
91-
const loadCustomBundle = (context) => {
92-
// This is one way of loading a bundle lazily (works for Polymer apps).
93-
// Other apps might use different ways.
94-
Polymer.importHref(
95-
`${Vaadin.Demo.componentsRoot}/user.bundle.html`,
96-
null,
97-
function(err) {
98-
throw new Error('bundle not found');
99-
},
100-
true
101-
);
102-
};
103-
104-
const router = new Router(document.getElementById('outlet'));
105-
router.setRoutes([
106-
{path: '/', component: 'x-home-view'},
107-
{path: '/user/:id', action: loadCustomBundle, component: 'x-user-html-bundle-view'}
108-
]);
109-
</script>
110-
</template>
111-
</vaadin-demo-snippet>
112-
1139
<h3>Using Dynamic Imports</h3>
11410
<p>
11511
Vaadin Router allows you to implement your own loading mechanism for bundles using
@@ -198,6 +94,52 @@ <h3>Splitting and Lazy-Loading the Routes Configuration</h3>
19894
</script>
19995
</template>
20096
</vaadin-demo-snippet>
97+
98+
<h3>Lazy Loading non-JS Bundles, e.g. HTML Imports</h3>
99+
<p>
100+
In cases when loading <code>.js</code> and <code>.mjs</code> is not
101+
enough&mdash;most notably, when using HTML imports in Polymer-based
102+
apps&mdash;the lazy loading feature can be implemented with a custom route
103+
action (for more details see <a href="#vaadin-router-route-actions-demos">
104+
Route Actions</a>).
105+
</p>
106+
<p>
107+
This demo shows a way to lazily add an HTML import. The <code>user.bundle.html</code>
108+
file contains entire Polymer 2 component definition including a template, a class,
109+
and a script that defines a custom element.
110+
</p>
111+
<vaadin-demo-snippet id="vaadin-router-code-splitting-2" iframe-src="iframe.html">
112+
<template preserve-content>
113+
<link rel="import" href="../../polymer/lib/utils/import-href.html">
114+
<a href="/">Home</a>
115+
<a href="/user/admin">User Profile</a>
116+
<div id="outlet"></div>
117+
<script>
118+
// import {Router} from '@vaadin/router'; // for Webpack / Polymer CLI
119+
// const Router = Vaadin.Router; // for vaadin-router.umd.js
120+
121+
const loadCustomBundle = (context) => {
122+
// This is one way of loading a bundle lazily (works for Polymer apps).
123+
// Other apps might use different ways.
124+
Polymer.importHref(
125+
`${Vaadin.Demo.componentsRoot}/user.bundle.html`,
126+
null,
127+
function(err) {
128+
throw new Error('bundle not found');
129+
},
130+
true
131+
);
132+
};
133+
134+
const router = new Router(document.getElementById('outlet'));
135+
router.setRoutes([
136+
{path: '/', component: 'x-home-view'},
137+
{path: '/user/:id', action: loadCustomBundle, component: 'x-user-html-bundle-view'}
138+
]);
139+
</script>
140+
</template>
141+
</vaadin-demo-snippet>
142+
201143
</template>
202144
<script>
203145
class VaadinRouterCodeSplittingDemos extends DemoReadyEventEmitter(ElementDemo(Polymer.Element)) {

interfaces.d.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ declare module './dist/vaadin-router' {
9898
name?: string;
9999
// Route requires at least one of the following optional properties
100100
action?: ActionFn;
101-
bundle?: string;
102101
children?: Route[] | ChildrenFn;
103102
component?: string;
104103
redirect?: string;
@@ -117,10 +116,6 @@ declare module './dist/vaadin-router' {
117116
action: ActionFn;
118117
}
119118

120-
interface RouteWithBundle extends BaseRoute {
121-
bundle: string;
122-
}
123-
124119
interface RouteWithChildren extends AnimatableRoute {
125120
children: Route[] | ChildrenFn;
126121
}
@@ -134,7 +129,6 @@ declare module './dist/vaadin-router' {
134129
}
135130

136131
export type Route = RouteWithAction
137-
| RouteWithBundle
138132
| RouteWithChildren
139133
| RouteWithComponent
140134
| RouteWithRedirect

src/router.js

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import animate from './transitions/animate.js';
55
import {
66
ensureRoute,
77
fireRouterEvent,
8-
loadBundle,
98
log,
109
logValue,
1110
toArray,
@@ -279,13 +278,6 @@ export class Router extends Resolver {
279278
if (isString(route.redirect)) {
280279
return commands.redirect(route.redirect);
281280
}
282-
283-
if (route.bundle) {
284-
return loadBundle(route.bundle)
285-
.then(() => {}, () => {
286-
throw new Error(log(`Bundle not found: ${route.bundle}. Check if the file name is correct`));
287-
});
288-
}
289281
})
290282
.then(result => {
291283
if (isResultNotEmpty(result)) {
@@ -359,14 +351,6 @@ export class Router extends Resolver {
359351
* The target route should also be defined.
360352
* See also **Redirects** section in [Live Examples](#/classes/Router/demos/demo/index.html).
361353
*
362-
* * `bundle` – string containing the path to `.js` or `.mjs` bundle to load before resolving the route,
363-
* or the object with "module" and "nomodule" keys referring to different bundles.
364-
* Each bundle is only loaded once. If "module" and "nomodule" are set, only one bundle is loaded,
365-
* depending on whether the browser supports ES modules or not.
366-
* The property is ignored when either an `action` returns the result or `redirect` property is present.
367-
* Any error, e.g. 404 while loading bundle will cause route resolution to throw.
368-
* See also **Code Splitting** section in [Live Examples](#/classes/Router/demos/demo/index.html).
369-
*
370354
* * `component` – the tag name of the Web Component to resolve the route to.
371355
* The property is ignored when either an `action` returns the result or `redirect` property is present.
372356
* If route contains the `component` property (or an action that return a component)

src/utils.js

Lines changed: 2 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,18 @@ export function logValue(value) {
2020
}
2121
}
2222

23-
const MODULE = 'module';
24-
const NOMODULE = 'nomodule';
25-
const bundleKeys = [MODULE, NOMODULE];
26-
27-
function ensureBundle(src) {
28-
if (!src.match(/.+\.[m]?js$/)) {
29-
throw new Error(
30-
log(`Unsupported type for bundle "${src}": .js or .mjs expected.`)
31-
);
32-
}
33-
}
34-
3523
export function ensureRoute(route) {
3624
if (!route || !isString(route.path)) {
3725
throw new Error(
3826
log(`Expected route config to be an object with a "path" string property, or an array of such objects`)
3927
);
4028
}
4129

42-
const bundle = route.bundle;
43-
44-
const stringKeys = ['component', 'redirect', 'bundle'];
30+
const stringKeys = ['component', 'redirect'];
4531
if (
4632
!isFunction(route.action) &&
4733
!Array.isArray(route.children) &&
4834
!isFunction(route.children) &&
49-
!isObject(bundle) &&
5035
!stringKeys.some(key => isString(route[key]))
5136
) {
5237
throw new Error(
@@ -57,20 +42,8 @@ export function ensureRoute(route) {
5742
);
5843
}
5944

60-
if (bundle) {
61-
if (isString(bundle)) {
62-
ensureBundle(bundle);
63-
} else if (!bundleKeys.some(key => key in bundle)) {
64-
throw new Error(
65-
log('Expected route bundle to include either "' + NOMODULE + '" or "' + MODULE + '" keys, or both')
66-
);
67-
} else {
68-
bundleKeys.forEach(key => key in bundle && ensureBundle(bundle[key]));
69-
}
70-
}
71-
7245
if (route.redirect) {
73-
['bundle', 'component'].forEach(overriddenProp => {
46+
['component'].forEach(overriddenProp => {
7447
if (overriddenProp in route) {
7548
console.warn(
7649
log(
@@ -87,49 +60,6 @@ export function ensureRoutes(routes) {
8760
toArray(routes).forEach(route => ensureRoute(route));
8861
}
8962

90-
function loadScript(src, key) {
91-
let script = document.head.querySelector('script[src="' + src + '"][async]');
92-
if (!script) {
93-
script = document.createElement('script');
94-
script.setAttribute('src', src);
95-
if (key === MODULE) {
96-
script.setAttribute('type', MODULE);
97-
} else if (key === NOMODULE) {
98-
script.setAttribute(NOMODULE, '');
99-
}
100-
script.async = true;
101-
}
102-
return new Promise((resolve, reject) => {
103-
script.onreadystatechange = script.onload = e => {
104-
script.__dynamicImportLoaded = true;
105-
resolve(e);
106-
};
107-
script.onerror = e => {
108-
if (script.parentNode) {
109-
script.parentNode.removeChild(script);
110-
}
111-
reject(e);
112-
};
113-
if (script.parentNode === null) {
114-
document.head.appendChild(script);
115-
} else if (script.__dynamicImportLoaded) {
116-
resolve();
117-
}
118-
});
119-
}
120-
121-
export function loadBundle(bundle) {
122-
if (isString(bundle)) {
123-
return loadScript(bundle);
124-
} else {
125-
return Promise.race(
126-
bundleKeys
127-
.filter(key => key in bundle)
128-
.map(key => loadScript(bundle[key], key))
129-
);
130-
}
131-
}
132-
13363
export function fireRouterEvent(type, detail) {
13464
return !window.dispatchEvent(new CustomEvent(
13565
`vaadin-router-${type}`,

test/router/lifecycle-events.spec.html

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,37 +1193,6 @@
11931193
});
11941194
});
11951195

1196-
describe('lifecycle events with bundle', () => {
1197-
const existingBundlePath = encodeURI('data:application/javascript,callbacksLog.push("bundle");//.js');
1198-
function getBundleScript() {
1199-
return document.head.querySelector('script[src="' + existingBundlePath + '"][async]');
1200-
}
1201-
afterEach(() => {
1202-
const bundleScript = getBundleScript();
1203-
if (bundleScript) {
1204-
bundleScript.parentNode.removeChild(bundleScript);
1205-
}
1206-
});
1207-
1208-
it('should invoke lifecycle events after bundle loading is complete', async() => {
1209-
router.setRoutes([
1210-
{path: '/', component: 'x-home-view'},
1211-
{path: '/x-spy', bundle: existingBundlePath, component: 'x-spy'}
1212-
]);
1213-
1214-
await router.render('/');
1215-
callbacksLog = [];
1216-
await router.render('/x-spy');
1217-
1218-
verifyCallbacks([
1219-
'bundle',
1220-
'x-spy.onBeforeEnter',
1221-
'x-spy.connectedCallback',
1222-
'x-spy.onAfterEnter'
1223-
]);
1224-
});
1225-
});
1226-
12271196
describe('lifecycle events with action', () => {
12281197
it('lifecycle events when reusing element (#355)', async() => {
12291198
const view = document.createElement('x-spy');

0 commit comments

Comments
 (0)