Merge branch 'master' into v3-readme

pull/1953/head
Conduitry 7 years ago
commit 8df8f2dd13

@ -24,6 +24,7 @@ This is the Svelte compiler, which is primarily intended for authors of tooling
* [rollup-plugin-svelte](https://github.com/rollup/rollup-plugin-svelte) Rollup plugin * [rollup-plugin-svelte](https://github.com/rollup/rollup-plugin-svelte) Rollup plugin
* [parcel-plugin-svelte](https://github.com/DeMoorJasper/parcel-plugin-svelte) - Parcel build plugin * [parcel-plugin-svelte](https://github.com/DeMoorJasper/parcel-plugin-svelte) - Parcel build plugin
* [sveltify](https://github.com/tehshrike/sveltify) - Browserify transform * [sveltify](https://github.com/tehshrike/sveltify) - Browserify transform
* [rules_svelte](https://github.com/thelgevold/rules_svelte) - Bazel Rules
### CSS Preprocessors ### CSS Preprocessors
@ -132,6 +133,7 @@ The `style` and `script` preprocessors will run *after* the `markup` preprocesso
* [EmilTholin/svelte-test](https://github.com/EmilTholin/svelte-test) * [EmilTholin/svelte-test](https://github.com/EmilTholin/svelte-test)
* [lukechinworth/codenames](https://github.com/lukechinworth/codenames/tree/svelte)  example integration with Redux * [lukechinworth/codenames](https://github.com/lukechinworth/codenames/tree/svelte)  example integration with Redux
* [khtdr/svelte-redux-shopping-cart](https://github.com/khtdr/svelte-redux-shopping-cart) Redux Shopping Cart example (with devtools and hot-reloading) * [khtdr/svelte-redux-shopping-cart](https://github.com/khtdr/svelte-redux-shopping-cart) Redux Shopping Cart example (with devtools and hot-reloading)
* [svelte-bazel-example](https://github.com/thelgevold/svelte-bazel-example) — Building Svelte with Bazel
## Development ## Development

4262
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
{ {
"name": "svelte", "name": "svelte",
"version": "3.0.0-beta.3", "version": "3.0.0-beta.7",
"description": "The magical disappearing UI framework", "description": "The magical disappearing UI framework",
"module": "index.mjs", "module": "index.mjs",
"main": "index", "main": "index",
@ -81,7 +81,6 @@
"rollup-plugin-sucrase": "^2.1.0", "rollup-plugin-sucrase": "^2.1.0",
"rollup-plugin-typescript": "^1.0.0", "rollup-plugin-typescript": "^1.0.0",
"rollup-plugin-virtual": "^1.0.1", "rollup-plugin-virtual": "^1.0.1",
"rollup-watch": "^4.3.1",
"sade": "^1.4.0", "sade": "^1.4.0",
"sander": "^0.6.0", "sander": "^0.6.0",
"shelljs": "^0.8.2", "shelljs": "^0.8.2",

@ -13,7 +13,7 @@ Start the server with `npm run dev`, and navigate to [localhost:3000](http://loc
## Using a local copy of Svelte ## Using a local copy of Svelte
By default, the REPL will fetch the most recent version of Svelte from https://unpkg.com/svelte. To use the local copy of the compiler and runtime from this repo, you can navigate to [localhost:3000/repl?version=local](http://localhost:3000/repl?version=local). By default, the REPL will fetch the most recent version of Svelte from https://unpkg.com/svelte. To use the local copy of the compiler and runtime from this repo, you can navigate to [localhost:3000/repl?version=local](http://localhost:3000/repl?version=local). To produce the proper browser-compatible UMD build, you will need to run `npm run build` with the `PUBLISH` environment variable set (to any non-empty string).
## REPL GitHub integration ## REPL GitHub integration

@ -20,7 +20,7 @@
version; // workaround version; // workaround
return { return {
imports: bundle.imports, imports: bundle && bundle.imports || [],
components: $component_store, components: $component_store,
values: $values_store values: $values_store
}; };

@ -99,17 +99,18 @@ async function getBundle(mode, cache, lookup) {
const name = id.replace(/^\.\//, '').replace(/\.svelte$/, ''); const name = id.replace(/^\.\//, '').replace(/\.svelte$/, '');
const { js, css, stats } = svelte.compile(code, Object.assign({ const { js, stats, warnings } = svelte.compile(code, Object.assign({
generate: mode, generate: mode,
format: 'esm', format: 'esm',
name: name, name: name,
filename: name + '.svelte', filename: name + '.svelte'
onwarn: warning => { }, commonCompilerOptions));
(warnings || stats.warnings).forEach(warning => { // TODO remove stats post-launch
console.warn(warning.message); console.warn(warning.message);
console.log(warning.frame); console.log(warning.frame);
warningCount += 1; warningCount += 1;
}, });
}, commonCompilerOptions));
return js; return js;
} }

@ -31,13 +31,13 @@ const commonCompilerOptions = {
function compile({ source, options, entry }) { function compile({ source, options, entry }) {
try { try {
const { js, css, stats } = svelte.compile( const { js, css, stats, vars } = svelte.compile(
source, source,
Object.assign({}, commonCompilerOptions, options) Object.assign({}, commonCompilerOptions, options)
); );
const props = entry const props = entry
? stats.vars.map(v => v.export_name).filter(Boolean) ? (vars || stats.vars).map(v => v.export_name).filter(Boolean) // TODO remove stats post-launch
: null; : null;
return { js: js.code, css: css.code, props }; return { js: js.code, css: css.code, props };

@ -34,7 +34,6 @@ export function compile(input, opts) {
const options = { const options = {
name: opts.name, name: opts.name,
format: opts.format, format: opts.format,
sourceMap: opts.sourcemap,
css: opts.css !== false, css: opts.css !== false,
dev: opts.dev, dev: opts.dev,
immutable: opts.immutable, immutable: opts.immutable,
@ -45,13 +44,13 @@ export function compile(input, opts) {
if (isDir) { if (isDir) {
mkdirp(output); mkdirp(output);
compileDirectory(input, output, options); compileDirectory(input, output, options, opts.sourcemap);
} else { } else {
compileFile(input, output, options); compileFile(input, output, options, opts.sourcemap);
} }
} }
function compileDirectory(input, output, options) { function compileDirectory(input, output, options, sourcemap) {
fs.readdirSync(input).forEach(file => { fs.readdirSync(input).forEach(file => {
const src = path.resolve(input, file); const src = path.resolve(input, file);
const dest = path.resolve(output, file); const dest = path.resolve(output, file);
@ -60,12 +59,13 @@ function compileDirectory(input, output, options) {
compileFile( compileFile(
src, src,
dest.substring(0, dest.lastIndexOf('.html')) + '.js', dest.substring(0, dest.lastIndexOf('.html')) + '.js',
options options,
sourcemap
); );
} else { } else {
const stats = fs.statSync(src); const stats = fs.statSync(src);
if (stats.isDirectory()) { if (stats.isDirectory()) {
compileDirectory(src, dest, options); compileDirectory(src, dest, options, sourcemap);
} }
} }
}); });
@ -74,7 +74,7 @@ function compileDirectory(input, output, options) {
let SOURCEMAPPING_URL = 'sourceMa'; let SOURCEMAPPING_URL = 'sourceMa';
SOURCEMAPPING_URL += 'ppingURL'; SOURCEMAPPING_URL += 'ppingURL';
function compileFile(input, output, options) { function compileFile(input, output, options, sourcemap) {
console.error(`compiling ${path.relative(process.cwd(), input)}...`); // eslint-disable-line no-console console.error(`compiling ${path.relative(process.cwd(), input)}...`); // eslint-disable-line no-console
options = Object.assign({}, options); options = Object.assign({}, options);
@ -83,8 +83,7 @@ function compileFile(input, output, options) {
options.filename = input; options.filename = input;
options.outputFilename = output; options.outputFilename = output;
const { sourceMap } = options; const inline = sourcemap === 'inline';
const inline = sourceMap === 'inline';
let source = fs.readFileSync(input, 'utf-8'); let source = fs.readFileSync(input, 'utf-8');
if (source[0] === 0xfeff) source = source.slice(1); if (source[0] === 0xfeff) source = source.slice(1);
@ -97,9 +96,11 @@ function compileFile(input, output, options) {
error(err); error(err);
} }
const { js } = compiled; const { js, warnings } = compiled;
if (sourceMap) { warnings.forEach(warning => console.warn(warning.toString()));
if (sourcemap) {
js.code += `\n//# ${SOURCEMAPPING_URL}=${inline || !output js.code += `\n//# ${SOURCEMAPPING_URL}=${inline || !output
? js.map.toUrl() ? js.map.toUrl()
: `${path.basename(output)}.map`}\n`; : `${path.basename(output)}.map`}\n`;
@ -110,7 +111,7 @@ function compileFile(input, output, options) {
mkdirp(outputDir); mkdirp(outputDir);
fs.writeFileSync(output, js.code); fs.writeFileSync(output, js.code);
console.error(`wrote ${path.relative(process.cwd(), output)}`); // eslint-disable-line no-console console.error(`wrote ${path.relative(process.cwd(), output)}`); // eslint-disable-line no-console
if (sourceMap && !inline) { if (sourcemap && !inline) {
fs.writeFileSync(`${output}.map`, js.map); fs.writeFileSync(`${output}.map`, js.map);
console.error(`wrote ${path.relative(process.cwd(), `${output}.map`)}`); // eslint-disable-line no-console console.error(`wrote ${path.relative(process.cwd(), `${output}.map`)}`); // eslint-disable-line no-console
} }

@ -433,7 +433,7 @@ export default class Component {
}); });
} }
extract_imports(content, is_module: boolean) { extract_imports(content) {
const { code } = this; const { code } = this;
content.body.forEach(node => { content.body.forEach(node => {
@ -441,26 +441,11 @@ export default class Component {
// imports need to be hoisted out of the IIFE // imports need to be hoisted out of the IIFE
removeNode(code, content.start, content.end, content.body, node); removeNode(code, content.start, content.end, content.body, node);
this.imports.push(node); this.imports.push(node);
node.specifiers.forEach((specifier: Node) => {
if (specifier.local.name[0] === '$') {
this.error(specifier.local, {
code: 'illegal-declaration',
message: `The $ prefix is reserved, and cannot be used for variable and import names`
});
}
this.add_var({
name: specifier.local.name,
module: is_module,
hoistable: true
});
});
} }
}); });
} }
extract_exports(content, is_module: boolean) { extract_exports(content) {
const { code } = this; const { code } = this;
content.body.forEach(node => { content.body.forEach(node => {
@ -558,30 +543,20 @@ export default class Component {
}); });
} }
if (!/Import/.test(node.type)) {
const kind = node.type === 'VariableDeclaration'
? node.kind
: node.type === 'ClassDeclaration'
? 'class'
: node.type === 'FunctionDeclaration'
? 'function'
: null;
// sanity check
if (!kind) throw new Error(`Unknown declaration type ${node.type}`);
this.add_var({ this.add_var({
name, name,
module: true, module: true,
hoistable: true, hoistable: true,
writable: kind === 'var' || kind === 'let' writable: node.kind === 'var' || node.kind === 'let'
}); });
}
}); });
globals.forEach(name => { globals.forEach((node, name) => {
if (name[0] === '$') { if (name[0] === '$') {
// TODO should this be possible? this.error(node, {
code: 'illegal-subscription',
message: `Cannot reference store value inside <script context="module">`
})
} else { } else {
this.add_var({ this.add_var({
name, name,
@ -590,8 +565,8 @@ export default class Component {
} }
}); });
this.extract_imports(script.content, true); this.extract_imports(script.content);
this.extract_exports(script.content, true); this.extract_exports(script.content);
remove_indentation(this.code, script.content); remove_indentation(this.code, script.content);
this.module_javascript = this.extract_javascript(script); this.module_javascript = this.extract_javascript(script);
} }
@ -627,29 +602,17 @@ export default class Component {
}); });
} }
if (!/Import/.test(node.type)) {
const kind = node.type === 'VariableDeclaration'
? node.kind
: node.type === 'ClassDeclaration'
? 'class'
: node.type === 'FunctionDeclaration'
? 'function'
: null;
// sanity check
if (!kind) throw new Error(`Unknown declaration type ${node.type}`);
this.add_var({ this.add_var({
name, name,
initialised: instance_scope.initialised_declarations.has(name), initialised: instance_scope.initialised_declarations.has(name),
writable: kind === 'var' || kind === 'let' hoistable: /^Import/.test(node.type),
writable: node.kind === 'var' || node.kind === 'let'
}); });
}
this.node_for_declaration.set(name, node); this.node_for_declaration.set(name, node);
}); });
globals.forEach(name => { globals.forEach((node, name) => {
if (this.var_lookup.has(name)) return; if (this.var_lookup.has(name)) return;
if (this.injected_reactive_declaration_vars.has(name)) { if (this.injected_reactive_declaration_vars.has(name)) {
@ -680,8 +643,8 @@ export default class Component {
} }
}); });
this.extract_imports(script.content, false); this.extract_imports(script.content);
this.extract_exports(script.content, false); this.extract_exports(script.content);
this.track_mutations(); this.track_mutations();
} }

@ -205,8 +205,8 @@ export default class ElementWrapper extends Wrapper {
block.parent.addDependencies(block.dependencies); block.parent.addDependencies(block.dependencies);
// appalling hack // appalling hack
block.wrappers.splice(block.wrappers.indexOf(this), 1); block.parent.wrappers.splice(block.parent.wrappers.indexOf(this), 1);
this.slot_block.wrappers.push(this); block.wrappers.push(this);
} }
} }

@ -2,6 +2,7 @@ import Renderer from '../Renderer';
import Block from '../Block'; import Block from '../Block';
import Node from '../../nodes/shared/Node'; import Node from '../../nodes/shared/Node';
import Tag from './shared/Tag'; import Tag from './shared/Tag';
import Wrapper from './shared/Wrapper';
export default class MustacheTagWrapper extends Tag { export default class MustacheTagWrapper extends Tag {
var = 'text'; var = 'text';

@ -27,10 +27,13 @@ export default function ssr(
const reactive_stores = component.vars.filter(variable => variable.name[0] === '$'); const reactive_stores = component.vars.filter(variable => variable.name[0] === '$');
const reactive_store_values = reactive_stores const reactive_store_values = reactive_stores
.map(({ name }) => { .map(({ name }) => {
const assignment = `${name} = @get_store_value(${name.slice(1)});`; const store = component.var_lookup.get(name.slice(1));
if (store.hoistable) return;
const assignment = `${name} = @get_store_value(${store.name});`;
return component.compileOptions.dev return component.compileOptions.dev
? `@validate_store(${name.slice(1)}, '${name.slice(1)}'); ${assignment}` ? `@validate_store(${store.name}, '${store.name}'); ${assignment}`
: assignment; : assignment;
}); });
@ -109,7 +112,16 @@ export default function ssr(
return \`${renderer.code}\`;`; return \`${renderer.code}\`;`;
const blocks = [ const blocks = [
reactive_stores.length > 0 && `let ${reactive_stores.map(store => store.name).join(', ')};`, reactive_stores.length > 0 && `let ${reactive_stores
.map(({ name }) => {
const store = component.var_lookup.get(name.slice(1));
if (store.hoistable) {
const get_store_value = component.helper('get_store_value');
return `${name} = ${get_store_value}(${store.name})`;
}
return name;
})
.join(', ')};`,
user_code, user_code,
parent_bindings.join('\n'), parent_bindings.join('\n'),
css.code && `$$result.css.add(#css);`, css.code && `$$result.css.add(#css);`,

@ -5,7 +5,7 @@ import { Node } from '../interfaces';
export function createScopes(expression: Node) { export function createScopes(expression: Node) {
const map = new WeakMap(); const map = new WeakMap();
const globals = new Set(); const globals: Map<string, Node> = new Map();
let scope = new Scope(null, false); let scope = new Scope(null, false);
walk(expression, { walk(expression, {
@ -39,8 +39,8 @@ export function createScopes(expression: Node) {
} else if (/(Class|Variable)Declaration/.test(node.type)) { } else if (/(Class|Variable)Declaration/.test(node.type)) {
scope.addDeclaration(node); scope.addDeclaration(node);
} else if (node.type === 'Identifier' && isReference(node, parent)) { } else if (node.type === 'Identifier' && isReference(node, parent)) {
if (!scope.has(node.name)) { if (!scope.has(node.name) && !globals.has(node.name)) {
globals.add(node.name); globals.set(node.name, node);
} }
} }
}, },

@ -0,0 +1,7 @@
export default {
preserveIdentifiers: true,
html: `
<span slot="name">Hello world</span>
`
};

@ -0,0 +1,9 @@
<script>
import Nested from './Nested.svelte';
let name = 'world';
</script>
<Nested>
<span slot="name">Hello {name}</span>
</Nested>

@ -0,0 +1,3 @@
export default {
error: `Cannot reference store value inside <script context="module">`
};

@ -0,0 +1,3 @@
import { writable } from '../../../../store.js';
export default writable(42);

@ -0,0 +1,6 @@
<script context="module">
import foo from './foo.js';
const answer = $foo;
</script>
<p>{answer}</p>

@ -0,0 +1,5 @@
export default {
html: `
<p>42</p>
`
};

@ -0,0 +1,3 @@
import { writable } from '../../../../store.js';
export default writable(42);

@ -0,0 +1,9 @@
<script context="module">
import foo from './foo.js';
</script>
<script>
const answer = $foo;
</script>
<p>{answer}</p>

@ -0,0 +1,5 @@
export default {
html: `
<p>42</p>
`
};

@ -0,0 +1,3 @@
import { writable } from '../../../../store.js';
export default writable(42);

@ -0,0 +1,6 @@
<script>
import foo from './foo.js';
const answer = $foo;
</script>
<p>{answer}</p>
Loading…
Cancel
Save