Description
I'm upgrading an app from Webpack Encore to AssetMapper. I have everything working. I love the simplicity that AssetMapper brings in.
Thanks to @weaverryan for creating it and thanks to all the maintainers of the component.
I have some questions:
1. Unconditional shim loading
AssetMapper injects this, which loads a JavaScript file unconditionally (but asynchronously):
<!-- ES Module Shims: Import maps polyfill for modules browsers without import maps support -->
<script async src="https://ga.jspm.io/npm:[email protected]/dist/es-module-shims.js"></script>
I don't like this because:
- Most browsers support modules already, so this is unnecessary
- It doesn't look safe enough: is the
jspm.io
host trustworthy? Who owns it? Also, the link doesn't include an integrity hash, so we don't know what this third-party host will inject in our sites.
We could use this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#feature_detection and some code like this (I haven't tested it, but you get an idea)
if (!HTMLScriptElement.supports?.('importmap')) {
window.addEventListener('DOMContentLoaded', function () {
const jsShim = document.createElement('script');
jsShim.src = 'https://ga.jspm.io/npm:[email protected]/dist/es-module-shims.js';
const firstJsFile = document.getElementsByTagName('script')[0];
firstJsFile.parentNode.insertBefore(jsShim, firstJsFile);
};
});
}
2. Full importmap
loading
All my pages look like this:
<script type="importmap">
{
"imports": {
"app": "/assets/app-1b3462c3ad3db0a53dae6f1629755d2b.js",
"bootstrap": "/assets/vendor/bootstrap/bootstrap.index-f0935445d9c6022100863214b519a1f2.js",
"@popperjs/core": "/assets/vendor/@popperjs/core/core.index-ceb5b6c0f9e1d3f6c78ef733facfdcda.js",
"admin": "/assets/admin-21f507ca8e60a600707f09370efdce36.js",
// ...
}
}
</script>
I don't like at all that admin
and other JS/CSS that belong to the private part of the application are publicly exposed. This could even leak sensitive information. See next point.
3. CSS/JS Comments are fully exposed
Since CSS/JS files are not processed at all, all their contents are sent verbatim. That means that comments are included too.
I never store passwords, keys, etc. in comments but sometimes I add private information in comments of no-public CSS/JS files (e.g. admin
). This could leak private/confidential info.
4. Strange CSS entries in importmap
I see this in the importmap:
<script type="importmap">
{
"imports": {
"app": "/assets/app-1b3462c3ad3db0a53dae6f1629755d2b.js",
"bootstrap/dist/css/bootstrap.min.css": "data:application/javascript,",
"/assets/styles/app.css": "data:application/javascript,",
"bootstrap": "/assets/vendor/bootstrap/bootstrap.index-f0935445d9c6022100863214b519a1f2.js",
"/assets/styles/REDACTED.css": "data:application/javascript,const%20d%3Ddocument%2Cl%3Dd.createElement%28%22link%22%29%3Bl.rel%3D%22stylesheet%22%2Cl.href%3D%22%2Fassets%2Fstyles%2FREDACTED-36dadcef3eec5c0d3a330e5bda46230e.css%22%2C%28d.head%7C%7Cd.getElementsByTagName%28%22head%22%29%5B0%5D%29.appendChild%28l%29",
// ...
}
}
</script>
Why do we need the empty "data:application/javascript,"
? If they don't contain anything, why add them as entries in the importmap at all?
5. No PurgeCSS
I know that the beauty of AssetMapper is no CSS/JS processing (but we provide optional processing for Sass and Tailwind) but it's sad that we don't have the option to run the PurgeCSS tool to remove all the unneeded CSS.
In this app, we load the entire Bootstrap CSS in a private part of the website, but in the rest of the site we only use 10% or less of Bootstrap.
What we have now:
- Full Bootstrap CSS unmodified: 274 KB
- Full Bootstrap CSS minified: 227 KB
- Full Bootstrap CSS compressed with Brotli: 30 KB
- Full Bootstrap CSS minified and compressed with Brotli: ~30 KB
So, we're fine because we'll only load 30 KB thanks to Brotli...
... however, with PurgeCSS, we'd load 1 KB or 2 KB.