fix mutation to imported variable (#4713)

pull/4719/head
Tan Li Hau 5 years ago committed by GitHub
parent 676d57b5f7
commit aabb23cc34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,5 +1,9 @@
# Svelte changelog
## Unreleased
* Fix reactivity with imported values that are then mutated ([#4555](https://github.com/sveltejs/svelte/issues/4555))
## 3.21.0
* Support dimension bindings in cross-origin environments ([#2147](https://github.com/sveltejs/svelte/issues/2147))

@ -632,7 +632,6 @@ export default class Component {
this.add_var({
name,
initialised: instance_scope.initialised_declarations.has(name),
hoistable: /^Import/.test(node.type),
writable
});
@ -986,6 +985,7 @@ export default class Component {
hoistable_nodes,
var_lookup,
injected_reactive_declaration_vars,
imports,
} = this;
const top_level_function_declarations = new Map();
@ -1137,6 +1137,14 @@ export default class Component {
this.fully_hoisted.push(node);
}
}
for (const { specifiers } of imports) {
for (const specifier of specifiers) {
const variable = var_lookup.get(specifier.local.name);
if (!variable.mutated) variable.hoistable = true;
}
}
}
extract_reactive_declarations() {

@ -0,0 +1,3 @@
export default {
html: `<p>prop value</p>`
};

@ -0,0 +1,3 @@
export const obj = {
prop: 'prop value'
};

@ -0,0 +1,8 @@
<script>
import { obj } from './data.js';
$: prop = obj.prop;
obj.foo = 'a different prop';
</script>
<p>{prop}</p>

@ -0,0 +1,38 @@
import * as path from 'path';
export default {
html: `
import
<p>1 + 2 + 3 + 4 = 10</p>
local
<p>1 + 2 + 3 + 4 = 10</p>
<button>Add a number</button>
`,
before_test() {
delete require.cache[path.resolve(__dirname, 'data.js')];
},
async test({ assert, target, window, }) {
const btn = target.querySelector('button');
const clickEvent = new window.MouseEvent('click');
await btn.dispatchEvent(clickEvent);
assert.htmlEqual(target.innerHTML, `
import
<p>1 + 2 + 3 + 4 + 5 = 15</p>
local
<p>1 + 2 + 3 + 4 + 5 = 15</p>
<button>Add a number</button>
`);
await btn.dispatchEvent(clickEvent);
assert.htmlEqual(target.innerHTML, `
import
<p>1 + 2 + 3 + 4 + 5 + 6 = 21</p>
local
<p>1 + 2 + 3 + 4 + 5 + 6 = 21</p>
<button>Add a number</button>
`);
}
};

@ -0,0 +1 @@
export const numbers = [1, 2, 3, 4];

@ -0,0 +1,19 @@
<script>
import { numbers } from './data.js';
const local_numbers = [1, 2, 3, 4];
function addNumber() {
numbers[numbers.length] = numbers.length + 1;
local_numbers[local_numbers.length] = local_numbers.length + 1;
}
$: sum = numbers.reduce((t, n) => t + n, 0);
$: local_sum = local_numbers.reduce((t, n) => t + n, 0);
</script>
import <p>{numbers.join(' + ')} = {sum}</p>
local <p>{local_numbers.join(' + ')} = {local_sum}</p>
<button on:click={addNumber}>
Add a number
</button>
Loading…
Cancel
Save