-
Notifications
You must be signed in to change notification settings - Fork 920
Description
What problem does this feature solve?
When hosting multiple instances of Vue (compiled and built with different versions, by different third-party developers, from uncontrolled environments, etc) in the same browser (For instance, in a micro-front-end environment) which are consumed dynamically by a host interface, it has been observed that styles from one application may bleed in to another when the individual applications are not built using the option productionMode: true
.
In this scenario, it is preferred to test functionality of the prototype application in "Development" mode against other applications similarly built. We may also provide third-party developers with boiler-plate apps, so we can reasonably expect a common setup for the application directory structure, naming conventions and bundling to aid developers get up and running quickly. Generally, one would expect the production mode to be set via the environment arguments, but currently, in order for the styles to not bleed, we have to work around this issue by using the productionMode: true
option.
Under these admittedly edge-case circumstances, it has been observed that the vue-loader functionality for creating the CSS scope ID needs to be a little more robust then it currently is, as under the conditions, it is possible to achieve css hash collision making for conflicting app styles.
What does the proposed API look like?
The simplest alteration to the code to prevent hash conflict would simply be to alter line 94 of /lib/index.js
from:
index.js/
const id = hash(
isProduction
? (shortFilePath + '\n' + source)
: shortFilePath
)
into
const id = hash(shortFilePath + '\n' + source)
Adding the source to the hash routine, even during non-production routine would ensure that both the hash, and any conflicting apps would be identical (which in practice should be observably correct). A side effect might be that this may slow down the hash routine, and therefore, slow dev builds - though I have no metrics to back this up.
Another easily achievable option would be to provide a "salt" option for the hash routine to aid uniqueness.
index.d.ts, line 8
interface VueLoaderOptions {
...
scopeIdHashSalt?: string
}
index.js, line 94
const hashValue = isProduction
? (shortFilePath + '\n' + source)
: shortFilePath
const hashSalt = options.scopeIdHashSalt || ''
const id = hash(hashValue + hashSalt)
The value of this option is that I would expect it not to impact your current tests as much as the first example but is a sure-fire means of removing the chance of hash collisions unless the developer is extremely unlucky.
Another option might be simply to use a timestamp as a bit of salt - I tentatively suggest this might be enough but testing ID generation would be troublesome.
To the Vue developers:
My apologies if you feel that this should have been a bug report - After reading the code for vue-loader I wasn't sure whether this qualified as bug or a feature, since the code looked to intentionally distinguish between production and development during the hash routine, and since salting your hash was not a feature already integrated I opted to use the feature request.