stencil
stencil copied to clipboard
hashFileNames not working properly - not every file is hashed. This results in broken components
Stencil version:
@stencil/[email protected]
I'm submitting a: [X] bug report [ ] feature request [ ] support request => Please do not submit support requests here, use one of these channels: https://stencil-worldwide.herokuapp.com/ or https://forum.ionicframework.com/
Current behavior: We have a hash mismatch on stencil files which will fail to load component(s) and throw an error.
We have the following files generated in the esm folder:
- components/esm/index-5010886e.js
- my-component.entry.js
- my-second-component.entry.js
The entry files contain a reference to the index file.
my-component.entry.js
import { r as registerInstance, c as createEvent, h, H as Host } from './index-5010886e.js';
...
- When the hash of the index file changes, it will try to load the component entry files. Because it is hashed, it will defeat the browser caching mechanism (which is good).
- When loading the component entry file, the browser will use the cached version (there is no cache defeating mechanism on the file - this is bad).
- because the entry files have a reference to a hashed index file, it will throw an error and fail to load the component. The application will show blank spots instead of a component.
Note: This will not happen if browser caching is turned off.
Expected behavior: Like the index.js, The entry files should have a hash. This will prevent browsers from caching the files and causing an error, because the hash of the index file and the reference in the entry file do not match.
- give all {component}.entry.js files the same hash as the index.hash.js file > {component}.hash.entry.js
- make sure that the index.hash.js file loads the bundle with the hash (line 1495)
Steps to reproduce:
- Do a stencil build
- open a browser, make sure caching is turned on and navigate to a page where the components are used
- trigger a hash change (not sure what triggers this - presumably a stenciljs version upgrade or, as the documentation specifies, by a content change)
- Do another stencil build
- refresh the page on the browser
Related code:
index.hash.js (compiled)
const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
// loadModuleImport
const exportName = cmpMeta.$tagName$.replace(/-/g, '_');
const bundleId = ( cmpMeta.$lazyBundleIds$);
const module = cmpModules.get(bundleId) ;
if (module) {
return module[exportName];
}
return import(
/* webpackInclude: /\.entry\.js$/ */
/* webpackExclude: /\.system\.entry\.js$/ */
/* webpackMode: "lazy" */
`./${bundleId}.entry.js${ ''}`).then(importedModule => { // <-- THIS PART LOADS ENTRIES W/H HASH
{
cmpModules.set(bundleId, importedModule);
}
return importedModule[exportName];
}, consoleError);
};
Other information: Stencil documentation specifies this on the topic:
source: https://stenciljs.com/docs/config ` hashFileNames default: true
During production builds, the content of each generated file is hashed to represent the content, and the hashed value is used as the filename. If the content isn't updated between builds, then it receives the same filename. When the content is updated, then the filename is different. By doing this, deployed apps can "forever-cache" the build directory and take full advantage of content delivery networks (CDNs) and heavily caching files for faster apps. `
This information seems to be incorrect. It states that each generated file is hashed, while it does not hash *.entry.js files
I had a similar problem when I use a web component built with Stencil: the .entry File was served from cache, while index file was "fresh" (because it was hashed). That lead to some strange errors, which disappeared when the cache was emptied.
I worked around the problem by loading the files from www/build
instead of from dist
.
In www/build
, all files are nicely hashed, so no more issues with caching when I deploy a new version.
Is the www/build
directory meant to be used for that purpose?
Did you guys found a solution ?
The issue is the same with www/build
repository, all files are not hashed (espacially the files we need to use :) )
We ended up using a different implementation method.
And yes, i believe you can use the build files, but they are not meant to be used for production builds.
Same as this issue: https://github.com/ionic-team/stencil/issues/2526
Following this issue: Our temp workaround is changing the name of the directory to build our theme whenever we make any changes to the web component. 👎