diff --git a/package-lock.json b/package-lock.json index 9771d83536..51ee2c94a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.0.0-beta.15", + "version": "3.0.0-beta.16", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -61,9 +61,9 @@ "dev": true }, "acorn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.5.tgz", - "integrity": "sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", "dev": true }, "acorn-dynamic-import": { diff --git a/package.json b/package.json index 4b85fdfdb9..2f272a882d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.0.0-beta.15", + "version": "3.0.0-beta.16", "description": "The magical disappearing UI framework", "module": "index.mjs", "main": "index", @@ -51,7 +51,7 @@ "devDependencies": { "@types/mocha": "^5.2.0", "@types/node": "^10.5.5", - "acorn": "^6.0.5", + "acorn": "^6.1.1", "acorn-dynamic-import": "^4.0.0", "agadoo": "^1.0.1", "c8": "^3.4.0", diff --git a/site/src/components/Repl/Output/Viewer.svelte b/site/src/components/Repl/Output/Viewer.svelte index f5fcb0295e..d2f7b87001 100644 --- a/site/src/components/Repl/Output/Viewer.svelte +++ b/site/src/components/Repl/Output/Viewer.svelte @@ -76,7 +76,7 @@ window.location.hash = ''; window._svelteTransitionManager = null; - window.component = new SvelteComponent({ + window.component = new SvelteComponent.default({ target: document.body }); `); diff --git a/site/static/workers/bundler.js b/site/static/workers/bundler.js index 2874820529..06a2364f93 100644 --- a/site/static/workers/bundler.js +++ b/site/static/workers/bundler.js @@ -14,7 +14,7 @@ self.addEventListener('message', async event => { version === 'local' ? '/repl/local?file=compiler.js' : `https://unpkg.com/svelte@${version}/compiler.js`, - `https://unpkg.com/rollup@0.68/dist/rollup.browser.js` + `https://unpkg.com/rollup@1/dist/rollup.browser.js` ); fulfil(); @@ -62,7 +62,6 @@ function fetch_if_uncached(url) { async function getBundle(mode, cache, lookup) { let bundle; - let error; const all_warnings = []; const new_cache = {}; @@ -89,6 +88,8 @@ async function getBundle(mode, cache, lookup) { if (importee.endsWith('.html')) importee = importee.replace(/\.html$/, '.svelte'); if (importee in lookup) return importee; + + throw new Error(`Could not resolve "${importee}" from "${importer}"`); }, load(id) { if (id.startsWith(`https://`)) return fetch_if_uncached(id); @@ -104,7 +105,7 @@ async function getBundle(mode, cache, lookup) { : svelte.compile(code, Object.assign({ generate: mode, format: 'esm', - name: name, + name, filename: name + '.svelte' }, commonCompilerOptions)); @@ -122,6 +123,7 @@ async function getBundle(mode, cache, lookup) { return result.js; } }], + inlineDynamicImports: true, onwarn(warning) { all_warnings.push({ message: warning.message @@ -129,7 +131,7 @@ async function getBundle(mode, cache, lookup) { } }); } catch (error) { - return { error, bundle: null, cache: new_cache, warnings: all_warnings } + return { error, bundle: null, cache: new_cache, warnings: all_warnings }; } return { bundle, cache: new_cache, error: null, warnings: all_warnings }; @@ -166,7 +168,7 @@ async function bundle(components) { let uid = 1; - const dom_result = await dom.bundle.generate({ + const dom_result = (await dom.bundle.generate({ format: 'iife', name: 'SvelteComponent', globals: id => { @@ -174,8 +176,9 @@ async function bundle(components) { import_map.set(id, name); return name; }, + exports: 'named', sourcemap: true - }); + })).output[0]; if (token !== currentToken) return; @@ -193,16 +196,17 @@ async function bundle(components) { if (token !== currentToken) return; const ssr_result = ssr - ? await ssr.bundle.generate({ + ? (await ssr.bundle.generate({ format: 'iife', name: 'SvelteComponent', globals: id => import_map.get(id), + exports: 'named', sourcemap: true - }) + })).output[0] : null; return { - imports: dom.bundle.imports, + imports: dom_result.imports, import_map, dom: dom_result, ssr: ssr_result, diff --git a/src/compile/Component.ts b/src/compile/Component.ts index 9dbfb3b41c..004ecb32ca 100644 --- a/src/compile/Component.ts +++ b/src/compile/Component.ts @@ -438,6 +438,12 @@ export default class Component { } if (node.type === 'ExportNamedDeclaration') { + if (node.source) { + this.error(node, { + code: `not-implemented`, + message: `A component currently cannot have an export ... from` + }); + } if (node.declaration) { if (node.declaration.type === 'VariableDeclaration') { node.declaration.declarations.forEach(declarator => { @@ -1034,7 +1040,10 @@ export default class Component { if (!assignee_nodes.has(identifier)) { const { name } = identifier; const owner = scope.findOwner(name); - if ((!owner || owner === component.instance_scope) && (name[0] === '$' || component.var_lookup.has(name))) { + if ( + (!owner || owner === component.instance_scope) && + (name[0] === '$' || component.var_lookup.has(name) && component.var_lookup.get(name).writable) + ) { dependencies.add(name); } } diff --git a/src/compile/render-dom/Block.ts b/src/compile/render-dom/Block.ts index 1d5c3c99a2..8051b9407c 100644 --- a/src/compile/render-dom/Block.ts +++ b/src/compile/render-dom/Block.ts @@ -239,6 +239,8 @@ export default class Block { const properties = new CodeBuilder(); + const methodName = (short: string, long: string) => dev ? `${short}: function ${this.getUniqueName(long)}` : short; + if (localKey) { properties.addBlock(`key: ${localKey},`); } @@ -258,7 +260,7 @@ export default class Block { ); properties.addBlock(deindent` - ${dev ? 'c: function create' : 'c'}() { + ${methodName('c', 'create')}() { ${this.builders.create} ${hydrate} }, @@ -270,7 +272,7 @@ export default class Block { properties.addLine(`l: @noop,`); } else { properties.addBlock(deindent` - ${dev ? 'l: function claim' : 'l'}(nodes) { + ${methodName('l', 'claim')}(nodes) { ${this.builders.claim} ${this.renderer.options.hydratable && !this.builders.hydrate.isEmpty() && `this.h();`} }, @@ -280,7 +282,7 @@ export default class Block { if (this.renderer.options.hydratable && !this.builders.hydrate.isEmpty()) { properties.addBlock(deindent` - ${dev ? 'h: function hydrate' : 'h'}() { + ${methodName('h', 'hydrate')}() { ${this.builders.hydrate} }, `); @@ -290,7 +292,7 @@ export default class Block { properties.addLine(`m: @noop,`); } else { properties.addBlock(deindent` - ${dev ? 'm: function mount' : 'm'}(#target, anchor) { + ${methodName('m', 'mount')}(#target, anchor) { ${this.builders.mount} }, `); @@ -301,7 +303,7 @@ export default class Block { properties.addLine(`p: @noop,`); } else { properties.addBlock(deindent` - ${dev ? 'p: function update' : 'p'}(changed, ${this.maintainContext ? 'new_ctx' : 'ctx'}) { + ${methodName('p', 'update')}(changed, ${this.maintainContext ? 'new_ctx' : 'ctx'}) { ${this.maintainContext && `ctx = new_ctx;`} ${this.builders.update} }, @@ -311,15 +313,15 @@ export default class Block { if (this.hasAnimation) { properties.addBlock(deindent` - ${dev ? `r: function measure` : `r`}() { + ${methodName('r', 'measure')}() { ${this.builders.measure} }, - ${dev ? `f: function fix` : `f`}() { + ${methodName('f', 'fix')}() { ${this.builders.fix} }, - ${dev ? `a: function animate` : `a`}() { + ${methodName('a', 'animate')}() { ${this.builders.animate} }, `); @@ -330,7 +332,7 @@ export default class Block { properties.addLine(`i: @noop,`); } else { properties.addBlock(deindent` - ${dev ? 'i: function intro' : 'i'}(#local) { + ${methodName('i', 'intro')}(#local) { ${this.hasOutros && `if (#current) return;`} ${this.builders.intro} }, @@ -341,7 +343,7 @@ export default class Block { properties.addLine(`o: @noop,`); } else { properties.addBlock(deindent` - ${dev ? 'o: function outro' : 'o'}(#local) { + ${methodName('o', 'outro')}(#local) { ${this.builders.outro} }, `); @@ -352,7 +354,7 @@ export default class Block { properties.addLine(`d: @noop`); } else { properties.addBlock(deindent` - ${dev ? 'd: function destroy' : 'd'}(detach) { + ${methodName('d', 'destroy')}(detach) { ${this.builders.destroy} } `); diff --git a/test/js/samples/reactive-values-non-writable-dependencies/expected.js b/test/js/samples/reactive-values-non-writable-dependencies/expected.js index 42f57a0037..deded0d4e9 100644 --- a/test/js/samples/reactive-values-non-writable-dependencies/expected.js +++ b/test/js/samples/reactive-values-non-writable-dependencies/expected.js @@ -17,11 +17,11 @@ let a = 1; let b = 2; function instance($$self, $$props, $$invalidate) { - + let max; - $$self.$$.update = ($$dirty = { Math: 1, a: 1, b: 1 }) => { + $$self.$$.update = ($$dirty = { a: 1, b: 1 }) => { if ($$dirty.a || $$dirty.b) { max = Math.max(a, b); $$invalidate('max', max); } diff --git a/test/validator/samples/reactive-declaration-no-deps/errors.json b/test/validator/samples/reactive-declaration-no-deps/errors.json new file mode 100644 index 0000000000..0063d4005e --- /dev/null +++ b/test/validator/samples/reactive-declaration-no-deps/errors.json @@ -0,0 +1,7 @@ +[{ + "message": "Invalid reactive declaration — must depend on local state", + "code": "invalid-reactive-declaration", + "start": { "line": 2, "column": 1, "character": 10 }, + "end": { "line": 2, "column": 23, "character": 32 }, + "pos": 10 +}] diff --git a/test/validator/samples/reactive-declaration-no-deps/input.svelte b/test/validator/samples/reactive-declaration-no-deps/input.svelte new file mode 100644 index 0000000000..c334f92ab5 --- /dev/null +++ b/test/validator/samples/reactive-declaration-no-deps/input.svelte @@ -0,0 +1,3 @@ +