Skip to content

explicit file path in import and export statements in ES modules for better web-browser support #843

@sudo-barun

Description

@sudo-barun

The ES modules in the lib-esm/ directory do not include explicit file path in import and export statements. This includes both lack of .js file extension and index.js file.

For example, lib-esm/router.js has:

import { UrlRouter } from './url/urlRouter';
import { makeStub } from './common';

instead of:

import { UrlRouter } from './url/urlRouter.js';
import { makeStub } from './common/index.js';

Due to this, it is difficult to use @uirouter/core in browser without using build tools.

I was able to replicate this official minimal example locally: https://stackblitz.com/edit/ui-router-plain-javascript?file=index.js
But, I had to provide lots of importmaps to make it work properly. Most of the importmaps would have been not required if the ES modules had provided explicit file path in import and export statements.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Integrate UI-Router with Vanilla JavaScript</title>
</head>
<body>

<div>
  <a href="javascript:void(0)" onclick="router.stateService.go('state1')">state1</a>
  <a href="javascript:void(0)" onclick="router.stateService.go('state1.nest1')">state1.nest2</a>
  <a href="javascript:void(0)" onclick="router.stateService.go('state2')">state2</a>
  
  <br>
  <ui-view id="root"></ui-view>
</div>

<script type="importmap">
{
  "imports": {
    "@uirouter/core": "/node_modules/@uirouter/core/lib-esm/index.js",

    "/node_modules/@uirouter/core/lib-esm/common": "/node_modules/@uirouter/core/lib-esm/common/index.js",
    "/node_modules/@uirouter/core/lib-esm/common/index": "/node_modules/@uirouter/core/lib-esm/common/index.js",
    "/node_modules/@uirouter/core/lib-esm/common/common": "/node_modules/@uirouter/core/lib-esm/common/common.js",
    "/node_modules/@uirouter/core/lib-esm/common/predicates": "/node_modules/@uirouter/core/lib-esm/common/predicates.js",
    "/node_modules/@uirouter/core/lib-esm/common/trace": "/node_modules/@uirouter/core/lib-esm/common/trace.js",
    "/node_modules/@uirouter/core/lib-esm/common/hof": "/node_modules/@uirouter/core/lib-esm/common/hof.js",
    "/node_modules/@uirouter/core/lib-esm/common/queue": "/node_modules/@uirouter/core/lib-esm/common/queue.js",
    "/node_modules/@uirouter/core/lib-esm/common/coreservices": "/node_modules/@uirouter/core/lib-esm/common/coreservices.js",
    "/node_modules/@uirouter/core/lib-esm/common/glob": "/node_modules/@uirouter/core/lib-esm/common/glob.js",
    "/node_modules/@uirouter/core/lib-esm/common/strings": "/node_modules/@uirouter/core/lib-esm/common/strings.js",
    "/node_modules/@uirouter/core/lib-esm/common/safeConsole": "/node_modules/@uirouter/core/lib-esm/common/safeConsole.js",

    "/node_modules/@uirouter/core/lib-esm/hooks/coreResolvables": "/node_modules/@uirouter/core/lib-esm/hooks/coreResolvables.js",
    "/node_modules/@uirouter/core/lib-esm/hooks/redirectTo": "/node_modules/@uirouter/core/lib-esm/hooks/redirectTo.js",
    "/node_modules/@uirouter/core/lib-esm/hooks/onEnterExitRetain": "/node_modules/@uirouter/core/lib-esm/hooks/onEnterExitRetain.js",
    "/node_modules/@uirouter/core/lib-esm/hooks/resolve": "/node_modules/@uirouter/core/lib-esm/hooks/resolve.js",
    "/node_modules/@uirouter/core/lib-esm/hooks/views": "/node_modules/@uirouter/core/lib-esm/hooks/views.js",
    "/node_modules/@uirouter/core/lib-esm/hooks/updateGlobals": "/node_modules/@uirouter/core/lib-esm/hooks/updateGlobals.js",
    "/node_modules/@uirouter/core/lib-esm/hooks/url": "/node_modules/@uirouter/core/lib-esm/hooks/url.js",
    "/node_modules/@uirouter/core/lib-esm/hooks/lazyLoad": "/node_modules/@uirouter/core/lib-esm/hooks/lazyLoad.js",
    "/node_modules/@uirouter/core/lib-esm/hooks/ignoredTransition": "/node_modules/@uirouter/core/lib-esm/hooks/ignoredTransition.js",
    "/node_modules/@uirouter/core/lib-esm/hooks/invalidTransition": "/node_modules/@uirouter/core/lib-esm/hooks/invalidTransition.js",

    "/node_modules/@uirouter/core/lib-esm/params": "/node_modules/@uirouter/core/lib-esm/params/index.js",
    "/node_modules/@uirouter/core/lib-esm/params/index": "/node_modules/@uirouter/core/lib-esm/params/index.js",
    "/node_modules/@uirouter/core/lib-esm/params/stateParams": "/node_modules/@uirouter/core/lib-esm/params/stateParams.js",
    "/node_modules/@uirouter/core/lib-esm/params/param": "/node_modules/@uirouter/core/lib-esm/params/param.js",
    "/node_modules/@uirouter/core/lib-esm/params/interface": "/node_modules/@uirouter/core/lib-esm/params/interface.js",
    "/node_modules/@uirouter/core/lib-esm/params/paramTypes": "/node_modules/@uirouter/core/lib-esm/params/paramTypes.js",
    "/node_modules/@uirouter/core/lib-esm/params/paramType": "/node_modules/@uirouter/core/lib-esm/params/paramType.js",

    "/node_modules/@uirouter/core/lib-esm/path/index": "/node_modules/@uirouter/core/lib-esm/path/index.js",
    "/node_modules/@uirouter/core/lib-esm/path/pathUtils": "/node_modules/@uirouter/core/lib-esm/path/pathUtils.js",
    "/node_modules/@uirouter/core/lib-esm/path/pathNode": "/node_modules/@uirouter/core/lib-esm/path/pathNode.js",

    "/node_modules/@uirouter/core/lib-esm/resolve": "/node_modules/@uirouter/core/lib-esm/resolve/index.js",
    "/node_modules/@uirouter/core/lib-esm/resolve/index": "/node_modules/@uirouter/core/lib-esm/resolve/index.js",
    "/node_modules/@uirouter/core/lib-esm/resolve/resolveContext": "/node_modules/@uirouter/core/lib-esm/resolve/resolveContext.js",
    "/node_modules/@uirouter/core/lib-esm/resolve/resolvable": "/node_modules/@uirouter/core/lib-esm/resolve/resolvable.js",
    "/node_modules/@uirouter/core/lib-esm/resolve/interface": "/node_modules/@uirouter/core/lib-esm/resolve/interface.js",

    "/node_modules/@uirouter/core/lib-esm/state": "/node_modules/@uirouter/core/lib-esm/state/index.js",
    "/node_modules/@uirouter/core/lib-esm/state/index": "/node_modules/@uirouter/core/lib-esm/state/index.js",
    "/node_modules/@uirouter/core/lib-esm/state/stateRegistry": "/node_modules/@uirouter/core/lib-esm/state/stateRegistry.js",
    "/node_modules/@uirouter/core/lib-esm/state/stateService": "/node_modules/@uirouter/core/lib-esm/state/stateService.js",
    "/node_modules/@uirouter/core/lib-esm/state/stateMatcher": "/node_modules/@uirouter/core/lib-esm/state/stateMatcher.js",
    "/node_modules/@uirouter/core/lib-esm/state/stateBuilder": "/node_modules/@uirouter/core/lib-esm/state/stateBuilder.js",
    "/node_modules/@uirouter/core/lib-esm/state/stateQueueManager": "/node_modules/@uirouter/core/lib-esm/state/stateQueueManager.js",
    "/node_modules/@uirouter/core/lib-esm/state/targetState": "/node_modules/@uirouter/core/lib-esm/state/targetState.js",
    "/node_modules/@uirouter/core/lib-esm/state/stateObject": "/node_modules/@uirouter/core/lib-esm/state/stateObject.js",
    "/node_modules/@uirouter/core/lib-esm/state/interface": "/node_modules/@uirouter/core/lib-esm/state/interface.js",

    "/node_modules/@uirouter/core/lib-esm/transition/index": "/node_modules/@uirouter/core/lib-esm/transition/index.js",
    "/node_modules/@uirouter/core/lib-esm/transition/transitionService": "/node_modules/@uirouter/core/lib-esm/transition/transitionService.js",
    "/node_modules/@uirouter/core/lib-esm/transition/interface": "/node_modules/@uirouter/core/lib-esm/transition/interface.js",
    "/node_modules/@uirouter/core/lib-esm/transition/transition": "/node_modules/@uirouter/core/lib-esm/transition/transition.js",
    "/node_modules/@uirouter/core/lib-esm/transition/hookRegistry": "/node_modules/@uirouter/core/lib-esm/transition/hookRegistry.js",
    "/node_modules/@uirouter/core/lib-esm/transition/transitionEventType": "/node_modules/@uirouter/core/lib-esm/transition/transitionEventType.js",
    "/node_modules/@uirouter/core/lib-esm/transition/transitionHook": "/node_modules/@uirouter/core/lib-esm/transition/transitionHook.js",
    "/node_modules/@uirouter/core/lib-esm/transition/rejectFactory": "/node_modules/@uirouter/core/lib-esm/transition/rejectFactory.js",
    "/node_modules/@uirouter/core/lib-esm/transition/hookBuilder": "/node_modules/@uirouter/core/lib-esm/transition/hookBuilder.js",

    "/node_modules/@uirouter/core/lib-esm/url/index": "/node_modules/@uirouter/core/lib-esm/url/index.js",
    "/node_modules/@uirouter/core/lib-esm/url/interface": "/node_modules/@uirouter/core/lib-esm/url/interface.js",
    "/node_modules/@uirouter/core/lib-esm/url/urlMatcherFactory": "/node_modules/@uirouter/core/lib-esm/url/urlMatcherFactory.js",
    "/node_modules/@uirouter/core/lib-esm/url/urlRouter": "/node_modules/@uirouter/core/lib-esm/url/urlRouter.js",
    "/node_modules/@uirouter/core/lib-esm/url/urlService": "/node_modules/@uirouter/core/lib-esm/url/urlService.js",
    "/node_modules/@uirouter/core/lib-esm/url/urlMatcher": "/node_modules/@uirouter/core/lib-esm/url/urlMatcher.js",
    "/node_modules/@uirouter/core/lib-esm/url/urlRule": "/node_modules/@uirouter/core/lib-esm/url/urlRule.js",
    "/node_modules/@uirouter/core/lib-esm/url/urlRules": "/node_modules/@uirouter/core/lib-esm/url/urlRules.js",
    "/node_modules/@uirouter/core/lib-esm/url/urlConfig": "/node_modules/@uirouter/core/lib-esm/url/urlConfig.js",

    "/node_modules/@uirouter/core/lib-esm/view/index": "/node_modules/@uirouter/core/lib-esm/view/index.js",
    "/node_modules/@uirouter/core/lib-esm/view/interface": "/node_modules/@uirouter/core/lib-esm/view/interface.js",
    "/node_modules/@uirouter/core/lib-esm/view/view": "/node_modules/@uirouter/core/lib-esm/view/view.js",

    "/node_modules/@uirouter/core/lib-esm/vanilla": "/node_modules/@uirouter/core/lib-esm/vanilla/index.js",
    "/node_modules/@uirouter/core/lib-esm/vanilla/interface": "/node_modules/@uirouter/core/lib-esm/vanilla/interface.js",
    "/node_modules/@uirouter/core/lib-esm/vanilla/plugins": "/node_modules/@uirouter/core/lib-esm/vanilla/plugins.js",
    "/node_modules/@uirouter/core/lib-esm/vanilla/browserLocationConfig": "/node_modules/@uirouter/core/lib-esm/vanilla/browserLocationConfig.js",
    "/node_modules/@uirouter/core/lib-esm/vanilla/hashLocationService": "/node_modules/@uirouter/core/lib-esm/vanilla/hashLocationService.js",
    "/node_modules/@uirouter/core/lib-esm/vanilla/utils": "/node_modules/@uirouter/core/lib-esm/vanilla/utils.js",
    "/node_modules/@uirouter/core/lib-esm/vanilla/pushStateLocationService": "/node_modules/@uirouter/core/lib-esm/vanilla/pushStateLocationService.js",
    "/node_modules/@uirouter/core/lib-esm/vanilla/memoryLocationService": "/node_modules/@uirouter/core/lib-esm/vanilla/memoryLocationService.js",
    "/node_modules/@uirouter/core/lib-esm/vanilla/memoryLocationConfig": "/node_modules/@uirouter/core/lib-esm/vanilla/memoryLocationConfig.js",
    "/node_modules/@uirouter/core/lib-esm/vanilla/injector": "/node_modules/@uirouter/core/lib-esm/vanilla/injector.js",
    "/node_modules/@uirouter/core/lib-esm/vanilla/q": "/node_modules/@uirouter/core/lib-esm/vanilla/q.js",
    "/node_modules/@uirouter/core/lib-esm/vanilla/baseLocationService": "/node_modules/@uirouter/core/lib-esm/vanilla/baseLocationService.js",

    "/node_modules/@uirouter/core/lib-esm/router": "/node_modules/@uirouter/core/lib-esm/router.js",
    "/node_modules/@uirouter/core/lib-esm/globals": "/node_modules/@uirouter/core/lib-esm/globals.js",
    "/node_modules/@uirouter/core/lib-esm/interface": "/node_modules/@uirouter/core/lib-esm/interface.js"
  }
}
</script>

<script type="module">

import { pushStateLocationPlugin, servicesPlugin, UIRouter } from '@uirouter/core';
// import { Visualizer } from '@uirouter/visualizer';

// Create the router
var router = new UIRouter();
window.router = router;

// router.plugin(Visualizer);
router.plugin(pushStateLocationPlugin);
router.plugin(servicesPlugin);

// This transition hook renders each active states' html property
router.transitionService.onSuccess({}, (trans, state) => {
  trans.exiting().forEach(stateDef => naiveClearRenderedDom(stateDef));
  trans.entering().forEach(stateDef => naiveRenderIntoDom(stateDef));
});

// Register some sample states
router.stateRegistry.register({ name: 'state1', url: '/state1', html:  `<h1>This is state 1...</h1><ui-view id="state1"></ui-view>` });
router.stateRegistry.register({ name: 'state1.nest1', url: '/nest1', html: "This is a nestted state" });
router.stateRegistry.register({ name: 'state2', url: '/state2', html: "This is state 2..." });

// Start the router
router.trace.enable(1);
router.urlService.rules.initial({ state: 'state1.nest1' });
router.urlService.listen();
router.urlService.sync();


function naiveRenderIntoDom(stateDef) {
  var state = stateDef.$$state();
  var parentId = state.parent.name || 'root';
  console.log(`rendering into ${parentId}`)
  var parent = document.getElementById(parentId);
  parent.innerHTML = state.html;
}

function naiveClearRenderedDom(stateDef) {
  var state = stateDef.$$state();
  var parentId = state.parent.name || 'root';
  console.log(`clearing ${parentId}`)
  var parent = document.getElementById(parentId);
  parent.innerHTML = ``;
}

</script>

</body>
</html>

By having explicit path, the importmap can be reduced to:

<script type="importmap">
{
  "imports": {
    "@uirouter/core": "/node_modules/@uirouter/core/lib-esm/index.js",
    "@uirouter/core/": "/node_modules/@uirouter/core/"
  }
}
</script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions