When following the steps to use calcite-components with Webpack, the warning below is logged in the console:
[calcite] Deprecated script, please remove: <script type="text/javascript" src="index.c627913669bc71b31c3b.js"></script>
To improve performance it is recommended to set the differential scripts in the head as follows:
<script type="module" src="http://localhost:8080/calcite/calcite.esm.js"></script>
<script nomodule="" src="http://localhost:8080/calcite/calcite.js"></script>
I am able to get rid of the warning by using the loader and passing in the window i.e.
import { defineCustomElements as calciteComponents } from "@esri/calcite-components/dist/loader";
(async function init() {
await calciteComponents(window);
})();
However, using the loader is causing issues when using the calcite-icon component. Webpack isn't able to find the icon modules. The following error logs:
Uncaught (in promise) Error: Cannot find module '/assets/question24.js'
When importing calcite-components into a Webpack app by following the steps in the README, the project is able to find the icons just fine.
I see that the warning is deprecated so should I ignore the warning for now? Or is there a way to use the loader to load calcite-components with the icons?
cc @jcfranco incase he knows anything :)
Hey all,
I recently had to really dig into this one as it's been affecting our Vue CLI apps, which uses webpack under the hood and producing similar errors that @rslibed mentioned above. Was able to use the following config to pull the icon path files over in both development and production mode. Essentially use copy-webpack-plugin to move the resources to your output folder as necessary, then update the webpack-dev-server to write it all to disk. Might be better ways to accomplish this, but it's working!
devServer: {
writeToDisk: true
},
configureWebpack: {
plugins: [
new CopyWebpackPlugin([
{
from: "node_modules/@esri/calcite-components/dist/calcite/assets/*.json",
to: "assets",
flatten: true
}
])
]
}
I've been running into this as well since we are using the calcite-tree on the developers site (and the tree uses calcite-icon under the hood). The solution of copying the json assets in to the build output assets folder isn't working because calcite-icon is making a request via a relative path to ./assets/icon.json. So the request ends up being /sub-page/assets/icon.json instead of being from the root.
Could there be a way to specify an asset path?
@noahmulfinger I noticed that too after posting. We're running single page apps over here and I ended up having to remove html5 history mode as a workaround for now :(
Agreed - would be great to be able to define / override asset path
@rslibed @evanmosby @noahmulfinger Thanks for reporting this. Could you share a small repro case to investigate further?
@jcfranco For sure! Check out https://github.com/evanmosby/calcite-icon-test. Once you're running that hello world app, I have two routes setup each with a calcite-icon component .
You'll notice the "About page" has a nested route. Navigate there and hard refresh, you'll start noticing the icon erratically loading and those console errors noted above. When the icon doesn't load, check out the network request to the respective icon JSON file and you'll see the path changes from /assets/...json to /nested/assests/...json depending on the where the app was initialized from. It would appear initialization is relatively pathed from that page. You'll note in vue.config.js I've also had to configure webpack to copy the icon assets into /assets otherwise icons simply fail to load alltogether.
Thanks for checking it out - hit me up on Teams is something isn't making sense.
Just for reference, looks like this is a general issue with stencil/Ionic. See https://github.com/ionic-team/stencil/issues/1868 and https://github.com/ionic-team/ionicons/issues/646
After doing some more digging into the stencil source code, I discovered that you can pass options to defineCustomElements, one of which is resourcesUrl. For example, you can do:
defineCustomElements(window, {
resourcesUrl: "/calcite/"
});
And then all of the icon requests will be /calcite/assets/icon.json. So getting calcite-icon to work with webpack requires two steps:
<assetFolder>/assets/*.json in your build output.resourcesUrl to /<assetFolder>/@rslibed @evanmosby Can you see if the above works for you as well?
Also, this may be beyond the scope of this issue, but I think it would be ideal if we could only include the icons that are actually needed when building through webpack. Not sure what this would look like yet. There are just a lot of icon files to include, most of which are unused.
@noahmulfinger - dude, that's a great find! Working like a champ!
I think this may be resolved with @noahmulfinger 's work resourcesUrl workaround? Should be close this one?
Closing. Thanks for looking into this @noahmulfinger!
@rslibed Feel free to reopen if needed.
@paulcpederson @jcfranco Might be good to document this somewhere since it's not even documented by stencil. Maybe in then new examples repo? Or in the main README. Happy to open a PR once I know where.
@noahmulfinger yeah if you want to add a new example in the examples repo feel free!
Most helpful comment
After doing some more digging into the stencil source code, I discovered that you can pass options to
defineCustomElements, one of which isresourcesUrl. For example, you can do:And then all of the icon requests will be
/calcite/assets/icon.json. So gettingcalcite-iconto work with webpack requires two steps:<assetFolder>/assets/*.jsonin your build output.resourcesUrlto/<assetFolder>/@rslibed @evanmosby Can you see if the above works for you as well?
Also, this may be beyond the scope of this issue, but I think it would be ideal if we could only include the icons that are actually needed when building through webpack. Not sure what this would look like yet. There are just a lot of icon files to include, most of which are unused.