deconflict name with imports (#655)

pull/674/head
Rich Harris 8 years ago
parent e582691c61
commit 7ad4befd25

@ -54,7 +54,6 @@ export default class Generator {
this.parsed = parsed; this.parsed = parsed;
this.source = source; this.source = source;
this.name = name;
this.options = options; this.options = options;
this.imports = []; this.imports = [];
@ -81,7 +80,10 @@ export default class Generator {
// Svelte's builtin `import { get, ... } from 'svelte/shared.ts'`; // Svelte's builtin `import { get, ... } from 'svelte/shared.ts'`;
this.importedNames = new Set(); this.importedNames = new Set();
this.aliases = new Map(); this.aliases = new Map();
this.usedNames = new Set([name]); this.usedNames = new Set();
this.parseJs();
this.name = this.alias(name);
} }
addSourcemapLocations(node: Node) { addSourcemapLocations(node: Node) {
@ -389,7 +391,7 @@ export default class Generator {
}; };
} }
parseJs(ssr: boolean = false) { parseJs() {
const { source } = this; const { source } = this;
const { js } = this.parsed; const { js } = this.parsed;
@ -417,7 +419,7 @@ export default class Generator {
} }
} }
const defaultExport = body.find( const defaultExport = this.defaultExport = body.find(
(node: Node) => node.type === 'ExportDefaultDeclaration' (node: Node) => node.type === 'ExportDefaultDeclaration'
); );
@ -525,34 +527,6 @@ export default class Generator {
templateProperties.ondestroy = templateProperties.onteardown; templateProperties.ondestroy = templateProperties.onteardown;
} }
// in an SSR context, we don't need to include events, methods, oncreate or ondestroy
if (ssr) {
if (templateProperties.oncreate)
removeNode(
this.code,
defaultExport.declaration,
templateProperties.oncreate
);
if (templateProperties.ondestroy)
removeNode(
this.code,
defaultExport.declaration,
templateProperties.ondestroy
);
if (templateProperties.methods)
removeNode(
this.code,
defaultExport.declaration,
templateProperties.methods
);
if (templateProperties.events)
removeNode(
this.code,
defaultExport.declaration,
templateProperties.events
);
}
// now that we've analysed the default export, we can determine whether or not we need to keep it // now that we've analysed the default export, we can determine whether or not we need to keep it
let hasDefaultExport = !!defaultExport; let hasDefaultExport = !!defaultExport;
if (defaultExport && defaultExport.declaration.properties.length === 0) { if (defaultExport && defaultExport.declaration.properties.length === 0) {
@ -611,11 +585,9 @@ export default class Generator {
} }
} }
return { this.computations = computations;
computations, this.hasJs = hasJs;
hasJs, this.namespace = namespace;
namespace, this.templateProperties = templateProperties;
templateProperties,
};
} }
} }

@ -59,16 +59,16 @@ export default function dom(
options: CompileOptions options: CompileOptions
) { ) {
const format = options.format || 'es'; const format = options.format || 'es';
const name = options.name || 'SvelteComponent';
const generator = new DomGenerator(parsed, source, name, options); const generator = new DomGenerator(parsed, source, options.name || 'SvelteComponent', options);
const { const {
computations, computations,
hasJs, hasJs,
name,
templateProperties, templateProperties,
namespace, namespace,
} = generator.parseJs(); } = generator;
const { block, state } = preprocess(generator, namespace, parsed.html); const { block, state } = preprocess(generator, namespace, parsed.html);

@ -2,6 +2,7 @@ import deindent from '../../utils/deindent';
import Generator from '../Generator'; import Generator from '../Generator';
import Block from './Block'; import Block from './Block';
import visit from './visit'; import visit from './visit';
import { removeNode, removeObjectKey } from '../../utils/removeNode';
import { Parsed, Node, CompileOptions } from '../../interfaces'; import { Parsed, Node, CompileOptions } from '../../interfaces';
export class SsrGenerator extends Generator { export class SsrGenerator extends Generator {
@ -19,6 +20,34 @@ export class SsrGenerator extends Generator {
this.bindings = []; this.bindings = [];
this.renderCode = ''; this.renderCode = '';
this.elementDepth = 0; this.elementDepth = 0;
// in an SSR context, we don't need to include events, methods, oncreate or ondestroy
const { templateProperties, defaultExport } = this;
if (templateProperties.oncreate)
removeNode(
this.code,
defaultExport.declaration,
templateProperties.oncreate
);
if (templateProperties.ondestroy)
removeNode(
this.code,
defaultExport.declaration,
templateProperties.ondestroy
);
if (templateProperties.methods)
removeNode(
this.code,
defaultExport.declaration,
templateProperties.methods
);
if (templateProperties.events)
removeNode(
this.code,
defaultExport.declaration,
templateProperties.events
);
} }
append(code: string) { append(code: string) {
@ -32,11 +61,10 @@ export default function ssr(
options: CompileOptions options: CompileOptions
) { ) {
const format = options.format || 'cjs'; const format = options.format || 'cjs';
const name = options.name || 'SvelteComponent';
const generator = new SsrGenerator(parsed, source, name, options); const generator = new SsrGenerator(parsed, source, options.name || 'SvelteComponent', options);
const { computations, hasJs, templateProperties } = generator.parseJs(true); const { computations, name, hasJs, templateProperties } = generator;
// create main render() function // create main render() function
const mainBlock = new Block({ const mainBlock = new Block({

@ -78,7 +78,7 @@ export default function validate(
try { try {
if (name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) { if (name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) {
const error = new Error(`options.name must be a valid identifier`); const error = new Error(`options.name must be a valid identifier (got '${name}')`);
throw error; throw error;
} }

@ -163,7 +163,7 @@ export function addLineNumbers(code) {
.join('\n'); .join('\n');
} }
function capitalize(str) { function capitalise(str) {
return str[0].toUpperCase() + str.slice(1); return str[0].toUpperCase() + str.slice(1);
} }
@ -173,7 +173,8 @@ export function showOutput(cwd, options = {}) {
const { code } = svelte.compile( const { code } = svelte.compile(
fs.readFileSync(`${cwd}/${file}`, 'utf-8'), fs.readFileSync(`${cwd}/${file}`, 'utf-8'),
Object.assign(options, { Object.assign(options, {
name: capitalize(file.slice(0, -path.extname(file).length)) filename: file,
name: capitalise(path.basename(file).replace(/\.html$/, ''))
}) })
); );

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

@ -0,0 +1,9 @@
<Main/>
<script>
import Main from './nested/main.html';
export default {
components: { Main }
};
</script>

@ -1,6 +1,4 @@
export default { export default {
// solo: true,
data: { data: {
depth: 5 depth: 5
}, },

@ -1,6 +1,7 @@
import assert from "assert"; import assert from "assert";
import * as fs from "fs"; import * as fs from "fs";
import * as path from "path"; import * as path from "path";
import glob from 'glob';
import { import {
showOutput, showOutput,
@ -88,9 +89,13 @@ describe("ssr", () => {
(config.skip ? it.skip : config.solo ? it.only : it)(dir, () => { (config.skip ? it.skip : config.solo ? it.only : it)(dir, () => {
const cwd = path.resolve("test/runtime/samples", dir); const cwd = path.resolve("test/runtime/samples", dir);
fs.readdirSync(`test/runtime/samples/${dir}`).forEach(file => { glob.sync('**/*.html', { cwd: `test/runtime/samples/${dir}` }).forEach(file => {
try {
const resolved = require.resolve(`../runtime/samples/${dir}/${file}`); const resolved = require.resolve(`../runtime/samples/${dir}/${file}`);
delete require.cache[resolved]; delete require.cache[resolved];
} catch (e) {
// do nothing (probably a directory)
}
}); });
const component = require(`../runtime/samples/${dir}/main.html`); const component = require(`../runtime/samples/${dir}/main.html`);

Loading…
Cancel
Save