-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add hook to transform h's arguments #851
feat: add hook to transform h's arguments #851
Conversation
Great progress! I think we will need to update export {
h,
+ resetTransformHArgs,
+ transformHArgs
} from './h' Then we can just do No luck using this so far. Minimal repro of what I tried:
import { transformHArgs, h } from './dist/runtime-core.esm-bundler.js'
transformHArgs(() => ['div'])
console.log(
h('span')
) Final
Once this is working, it should be No luck overriding the arguments so far... Hmm. Seems like once you do I'll keep playing around. |
packages/runtime-core/src/h.ts
Outdated
@@ -159,3 +160,23 @@ export function h(type: any, propsOrChildren?: any, children?: any): VNode { | |||
return createVNode(type, propsOrChildren, children) | |||
} | |||
} | |||
|
|||
const originalH: Function = exports.h |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exports
is only available in Node.js environments (the tests pass because jest
runs the tests in Node.js) and won't work when bundled.
What we should here is let transformHArgs
save the transformer in a local variable, and check for the existence of that variable inside h
. We should probably also wrap the check in a if (__DEV__)
block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, that makes more sense. So something like:
let tranformedArgs
export function tranformHArgs(...args) {
tranformedArgs = [...args]
}
export function resetHArgs(...args) {
tranformedArgs = undefined
}
// other stuff
export function h(type: any, propsOrChildren?: any, children?: any): VNode {
if (__DEV___ || __TEST__ && transformedArgs) {
return createVNode(...transformedArgs)
}
// current implementation here
if (arguments.length === 2) {
if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
// ...
}
Which is more or less the same concept Jess was going for. Is what you are suggesting @yyx990803 ?
This will have a limitation we cannot run many tests in parallel, since they all share the same state. I think we might just have to live with that, I don't see another easy option that doesn't involve a lot of changes.
Thanks for the feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I was thinking of something more like
let argsTransformer
export function transformHArgs(transformer) {
argsTransformer = transformer
}
function originalH(...) {}
export const h = __DEV__
? (...args) => {
if (argsTransformer) {
args = argsTransformer(args, currentRenderingInstance)
}
return originalH(...args)
}
: originalH
Which should not be subject to concurrency issues. Also you will call this only once when VTU is loaded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha! V-nice, will update ⚡️
4c5d25c
to
8496c09
Compare
8496c09
to
f1f676a
Compare
Context
In Vue Test Utils (VTU) we provide two core features: “Shallow Mount” and “Stubs”.
Both
shallowMount
andstubs
enable the user to short circuit rendering a component tree. You can opt into this feature on any mount command (using stubs) orshallowMount
command (stubs everything).This PR adds the necessary functions to enable Vue Test Utils to implement shallowMount and stubs for Vue 3.
Implementation Details
Existing shallowMount functionality in VTU w/ Vue 2
shallowMount
is implemented by overwriting$createElement
in abeforeCreate
hook and conditionally choosing to apply the real$createElement
. In VTU we are able to support shallowMounting parent components that use theh
function directly.Implementing shallowMount in Vue 3
Identical implementation using
beforeCreate
hook is not possible becauseh
is not modifiable for a parent component instance like it was in Vue 2.Proposed API
Conditionally overload
h
’s functionality when its parent context wants to stub the component. Do this by using a transformer function to mutate the arguments passed intoh
.transformHArgs
and it returns an array of arguments to be applied to allh
functions.transformHArgs
with a reset function.Example Usage
Statically override all calls to
h
to return anh1
tag (this isn't useful, but it demonstrates the API)Conditionally modify what is rendered
Questions
@vue/runtime-core
?vm
still?