move vars out of stats

pull/2102/head
Richard Harris 5 years ago
parent fd39e9505b
commit b2f371a3d1

@ -1,5 +1,3 @@
import Component from './compile/Component';
const now = (typeof process !== 'undefined' && process.hrtime)
? () => {
const t = process.hrtime();
@ -63,41 +61,13 @@ export default class Stats {
this.currentChildren = this.currentTiming ? this.currentTiming.children : this.timings;
}
render(component: Component) {
render() {
const timings = Object.assign({
total: now() - this.startTime
}, collapseTimings(this.timings));
// TODO would be good to have this info even
// if options.generate is false
const imports = component && component.imports.map(node => {
return {
source: node.source.value,
specifiers: node.specifiers.map(specifier => {
return {
name: (
specifier.type === 'ImportDefaultSpecifier' ? 'default' :
specifier.type === 'ImportNamespaceSpecifier' ? '*' :
specifier.imported.name
),
as: specifier.local.name
};
})
}
});
return {
timings,
vars: component.vars.filter(variable => !variable.global && !variable.implicit && !variable.internal).map(variable => ({
name: variable.name,
export_name: variable.export_name || null,
injected: variable.injected || false,
module: variable.module || false,
mutated: variable.mutated || false,
reassigned: variable.reassigned || false,
referenced: variable.referenced || false,
writable: variable.writable || false
}))
timings
};
}
}

@ -217,106 +217,121 @@ export default class Component {
}
generate(result: string) {
const { compileOptions, name } = this;
const { format = 'esm' } = compileOptions;
let js = null;
let css = null;
const banner = `/* ${this.file ? `${this.file} ` : ``}generated by Svelte v${"__VERSION__"} */`;
if (result) {
const { compileOptions, name } = this;
const { format = 'esm' } = compileOptions;
// TODO use same regex for both
result = result.replace(compileOptions.generate === 'ssr' ? /(@+|#+)(\w*(?:-\w*)?)/g : /(@+)(\w*(?:-\w*)?)/g, (match: string, sigil: string, name: string) => {
if (sigil === '@') {
if (internal_exports.has(name)) {
if (compileOptions.dev && internal_exports.has(`${name}Dev`)) name = `${name}Dev`;
this.helpers.add(name);
}
const banner = `/* ${this.file ? `${this.file} ` : ``}generated by Svelte v${"__VERSION__"} */`;
return this.alias(name);
}
// TODO use same regex for both
result = result.replace(compileOptions.generate === 'ssr' ? /(@+|#+)(\w*(?:-\w*)?)/g : /(@+)(\w*(?:-\w*)?)/g, (match: string, sigil: string, name: string) => {
if (sigil === '@') {
if (internal_exports.has(name)) {
if (compileOptions.dev && internal_exports.has(`${name}Dev`)) name = `${name}Dev`;
this.helpers.add(name);
}
return sigil.slice(1) + name;
});
return this.alias(name);
}
const importedHelpers = Array.from(this.helpers)
.sort()
.map(name => {
const alias = this.alias(name);
return { name, alias };
return sigil.slice(1) + name;
});
const module = wrapModule(
result,
format,
name,
compileOptions,
banner,
compileOptions.sveltePath,
importedHelpers,
this.imports,
this.vars.filter(variable => variable.module && variable.export_name).map(variable => ({
name: variable.name,
as: variable.export_name
})),
this.source
);
const importedHelpers = Array.from(this.helpers)
.sort()
.map(name => {
const alias = this.alias(name);
return { name, alias };
});
const parts = module.split('✂]');
const finalChunk = parts.pop();
const module = wrapModule(
result,
format,
name,
compileOptions,
banner,
compileOptions.sveltePath,
importedHelpers,
this.imports,
this.vars.filter(variable => variable.module && variable.export_name).map(variable => ({
name: variable.name,
as: variable.export_name
})),
this.source
);
const compiled = new Bundle({ separator: '' });
const parts = module.split('✂]');
const finalChunk = parts.pop();
function addString(str: string) {
compiled.addSource({
content: new MagicString(str),
});
}
const compiled = new Bundle({ separator: '' });
const { filename } = compileOptions;
function addString(str: string) {
compiled.addSource({
content: new MagicString(str),
});
}
// special case — the source file doesn't actually get used anywhere. we need
// to add an empty file to populate map.sources and map.sourcesContent
if (!parts.length) {
compiled.addSource({
filename,
content: new MagicString(this.source).remove(0, this.source.length),
});
}
const { filename } = compileOptions;
// special case — the source file doesn't actually get used anywhere. we need
// to add an empty file to populate map.sources and map.sourcesContent
if (!parts.length) {
compiled.addSource({
filename,
content: new MagicString(this.source).remove(0, this.source.length),
});
}
const pattern = /\[✂(\d+)-(\d+)$/;
const pattern = /\[✂(\d+)-(\d+)$/;
parts.forEach((str: string) => {
const chunk = str.replace(pattern, '');
if (chunk) addString(chunk);
parts.forEach((str: string) => {
const chunk = str.replace(pattern, '');
if (chunk) addString(chunk);
const match = pattern.exec(str);
const match = pattern.exec(str);
const snippet = this.code.snip(+match[1], +match[2]);
const snippet = this.code.snip(+match[1], +match[2]);
compiled.addSource({
filename,
content: snippet,
compiled.addSource({
filename,
content: snippet,
});
});
});
addString(finalChunk);
addString(finalChunk);
const css = compileOptions.customElement ?
{ code: null, map: null } :
this.stylesheet.render(compileOptions.cssOutputFilename, true);
css = compileOptions.customElement ?
{ code: null, map: null } :
this.stylesheet.render(compileOptions.cssOutputFilename, true);
const js = {
code: compiled.toString(),
map: compiled.generateMap({
includeContent: true,
file: compileOptions.outputFilename,
})
};
js = {
code: compiled.toString(),
map: compiled.generateMap({
includeContent: true,
file: compileOptions.outputFilename,
})
};
}
return {
js,
css,
ast: this.ast,
warnings: this.warnings,
stats: this.stats.render(this)
vars: this.vars.filter(v => !v.global && !v.implicit && !v.internal).map(v => ({
name: v.name,
export_name: v.export_name || null,
injected: v.injected || false,
module: v.module || false,
mutated: v.mutated || false,
reassigned: v.reassigned || false,
referenced: v.referenced || false,
writable: v.writable || false
})),
stats: this.stats.render()
};
}

@ -95,13 +95,11 @@ export default function compile(source: string, options: CompileOptions = {}) {
);
stats.stop('create component');
if (options.generate === false) {
return { ast, warnings, stats: stats.render(component), js: null, css: null };
}
const js = options.generate === 'ssr'
? renderSSR(component, options)
: renderDOM(component, options);
const js = options.generate === false
? null
: options.generate === 'ssr'
? renderSSR(component, options)
: renderDOM(component, options);
return component.generate(js);
}

@ -1,5 +0,0 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, []);
},
};

@ -1,5 +0,0 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, []);
},
};

@ -1,5 +0,0 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, []);
},
};

@ -1,5 +0,0 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, []);
},
};

@ -1,5 +0,0 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, []);
},
};

@ -0,0 +1,60 @@
import * as fs from 'fs';
import * as assert from 'assert';
import { svelte, loadConfig, tryToLoadJson } from '../helpers.js';
describe('vars', () => {
fs.readdirSync('test/vars/samples').forEach(dir => {
if (dir[0] === '.') return;
// add .solo to a sample directory name to only run that test
const solo = /\.solo/.test(dir);
const skip = /\.skip/.test(dir);
if (solo && process.env.CI) {
throw new Error('Forgot to remove `solo: true` from test');
}
(solo ? it.only : skip ? it.skip : it)(dir, () => {
const config = loadConfig(`./vars/samples/${dir}/_config.js`);
const filename = `test/vars/samples/${dir}/input.svelte`;
const input = fs.readFileSync(filename, 'utf-8').replace(/\s+$/, '');
const expectedError = tryToLoadJson(
`test/vars/samples/${dir}/error.json`
);
let result;
let error;
try {
result = svelte.compile(input, config.options);
config.test(assert, result.vars);
} catch (e) {
error = e;
}
if (error || expectedError) {
if (error && !expectedError) {
throw error;
}
if (expectedError && !error) {
throw new Error(`Expected an error: ${expectedError.message}`);
}
assert.equal(error.message, expectedError.message);
assert.deepEqual(error.start, expectedError.start);
assert.deepEqual(error.end, expectedError.end);
assert.equal(error.pos, expectedError.pos);
}
});
});
it('returns a vars object when options.generate is false', () => {
const { vars } = svelte.compile('', {
generate: false
});
assert.ok(Array.isArray(vars));
});
});

@ -0,0 +1,5 @@
export default {
test(assert, vars) {
assert.deepEqual(vars, []);
},
};

@ -1,6 +1,6 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, [
test(assert, vars) {
assert.deepEqual(vars, [
{
name: 'console',
injected: false,

@ -1,6 +1,6 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, [
test(assert, vars) {
assert.deepEqual(vars, [
{
name: 'foo',
injected: false,

@ -0,0 +1,5 @@
export default {
test(assert, vars) {
assert.deepEqual(vars, []);
},
};

@ -1,6 +1,6 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, [
test(assert, vars) {
assert.deepEqual(vars, [
{
name: 'a',
injected: false,

@ -0,0 +1,5 @@
export default {
test(assert, vars) {
assert.deepEqual(vars, []);
},
};

@ -1,6 +1,6 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, [
test(assert, vars) {
assert.deepEqual(vars, [
{
name: 'x',
export_name: null,

@ -1,6 +1,6 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, [
test(assert, vars) {
assert.deepEqual(vars, [
{
name: 'count',
export_name: null,

@ -1,6 +1,6 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, [
test(assert, vars) {
assert.deepEqual(vars, [
{
name: 'count',
export_name: null,

@ -1,6 +1,6 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, [
test(assert, vars) {
assert.deepEqual(vars, [
{
name: 'name',
export_name: 'name',

@ -1,6 +1,6 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, [
test(assert, vars) {
assert.deepEqual(vars, [
{
name: 'foo',
export_name: null,

@ -1,6 +1,6 @@
export default {
test(assert, stats) {
assert.deepEqual(stats.vars, [
test(assert, vars) {
assert.deepEqual(vars, [
{
name: 'foo',
export_name: null,

@ -0,0 +1,5 @@
export default {
test(assert, vars) {
assert.deepEqual(vars, []);
},
};

@ -0,0 +1,5 @@
export default {
test(assert, vars) {
assert.deepEqual(vars, []);
},
};
Loading…
Cancel
Save