Skip to content

Commit

Permalink
fix(runtime-core): Avoid mutating original options object in createApp (
Browse files Browse the repository at this point in the history
  • Loading branch information
yuwu9145 committed Apr 12, 2022
1 parent 4311ddd commit d121a9b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
4 changes: 2 additions & 2 deletions packages/runtime-core/__tests__/helpers/resolveAssets.spec.ts
Expand Up @@ -91,9 +91,9 @@ describe('resolveAssets', () => {
const root = nodeOps.createElement('div')
app.mount(root)

expect(component1!).toBe(Root) // explicit self name reference
expect(component1!).toMatchObject(Root) // explicit self name reference
expect(component2!).toBe(Foo) // successful resolve take higher priority
expect(component3!).toBe(Root) // fallback when resolve fails
expect(component3!).toMatchObject(Root) // fallback when resolve fails
})

describe('warning', () => {
Expand Down
5 changes: 5 additions & 0 deletions packages/runtime-core/src/apiCreateApp.ts
Expand Up @@ -179,6 +179,11 @@ export function createAppAPI<HostElement>(
hydrate?: RootHydrateFunction
): CreateAppFunction<HostElement> {
return function createApp(rootComponent, rootProps = null) {

if (!isFunction(rootComponent)) {
rootComponent = { ...rootComponent }
}

if (rootProps != null && !isObject(rootProps)) {
__DEV__ && warn(`root props passed to app.mount() must be an object.`)
rootProps = null
Expand Down
29 changes: 29 additions & 0 deletions packages/runtime-dom/__tests__/createApp.spec.ts
Expand Up @@ -12,4 +12,33 @@ describe('createApp for dom', () => {
expect(root.children.length).toBe(1)
expect(root.children[0] instanceof SVGElement).toBe(true)
})

// #4398
test('should not mutate original root component options object', () => {

const originalObj = {
data() {
return {
counter: 0
}
}
}

const handler = jest.fn(msg => {
expect(msg).toMatch(`Component is missing template or render function`)
})

const Root = { ...originalObj}

const app = createApp(Root)
app.config.warnHandler = handler
app.mount(document.createElement('div'))

// ensure mount is based on a copy of Root object rather than Root object itself
expect(app._component).not.toBe(Root)

// ensure no mutation happened to Root object
expect(originalObj).toMatchObject(Root)

})
})

0 comments on commit d121a9b

Please sign in to comment.