core icon indicating copy to clipboard operation
core copied to clipboard

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

Open sudo-barun opened this issue 1 year ago • 0 comments

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>

sudo-barun avatar Sep 04 '24 07:09 sudo-barun