Skip to content

Commit 4b5754b

Browse files
committed
centralise logic for manipulating source javascript
1 parent caec96f commit 4b5754b

File tree

5 files changed

+68
-49
lines changed

5 files changed

+68
-49
lines changed

src/generators/Generator.js

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import isReference from '../utils/isReference.js';
44
import flattenReference from '../utils/flattenReference.js';
55
import globalWhitelist from '../utils/globalWhitelist.js';
66
import reservedNames from '../utils/reservedNames.js';
7-
import { removeNode } from '../utils/removeNode.js';
7+
import namespaces from '../utils/namespaces.js';
8+
import { removeNode, removeObjectKey } from '../utils/removeNode.js';
89
import getIntro from './shared/utils/getIntro.js';
910
import getOutro from './shared/utils/getOutro.js';
1011
import processCss from './shared/processCss.js';
@@ -22,6 +23,7 @@ export default class Generator {
2223
this.helpers = new Set();
2324
this.components = new Set();
2425
this.events = new Set();
26+
this.importedComponents = new Map();
2527

2628
this.bindingGroups = [];
2729

@@ -265,6 +267,7 @@ export default class Generator {
265267
const imports = this.imports;
266268
const computations = [];
267269
let defaultExport = null;
270+
let namespace = null;
268271
const templateProperties = {};
269272

270273
if ( js ) {
@@ -351,11 +354,40 @@ export default class Generator {
351354

352355
templateProperties.computed.value.properties.forEach( prop => visit( prop.key.name ) );
353356
}
357+
358+
if ( templateProperties.namespace ) {
359+
const ns = templateProperties.namespace.value.value;
360+
namespace = namespaces[ ns ] || ns;
361+
362+
removeObjectKey( this.code, defaultExport.declaration, 'namespace' );
363+
}
364+
365+
if ( templateProperties.components ) {
366+
let hasNonImportedComponent = false;
367+
templateProperties.components.value.properties.forEach( property => {
368+
const key = property.key.name;
369+
const value = source.slice( property.value.start, property.value.end );
370+
if ( this.importedNames.has( value ) ) {
371+
this.importedComponents.set( key, value );
372+
} else {
373+
hasNonImportedComponent = true;
374+
}
375+
});
376+
if ( hasNonImportedComponent ) {
377+
// remove the specific components that were imported, as we'll refer to them directly
378+
Array.from( this.importedComponents.keys() ).forEach( key => {
379+
removeObjectKey( this.code, templateProperties.components.value, key );
380+
});
381+
} else {
382+
// remove the entire components portion of the export
383+
removeObjectKey( this.code, defaultExport.declaration, 'components' );
384+
}
385+
}
354386
}
355387

356388
return {
357389
computations,
358-
defaultExport,
390+
namespace,
359391
templateProperties
360392
};
361393
}

src/generators/dom/index.js

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import deindent from '../../utils/deindent.js';
22
import getBuilders from './utils/getBuilders.js';
33
import CodeBuilder from '../../utils/CodeBuilder.js';
4-
import namespaces from '../../utils/namespaces.js';
5-
import { removeObjectKey } from '../../utils/removeNode.js';
64
import visitors from './visitors/index.js';
75
import Generator from '../Generator.js';
86
import * as shared from '../../shared/index.js';
@@ -17,8 +15,6 @@ class DomGenerator extends Generator {
1715
this.builders = {
1816
metaBindings: new CodeBuilder()
1917
};
20-
21-
this.importedComponents = new Map();
2218
}
2319

2420
addElement ( name, renderStatement, needsIdentifier = false ) {
@@ -155,7 +151,7 @@ export default function dom ( parsed, source, options ) {
155151

156152
const generator = new DomGenerator( parsed, source, name, visitors, options );
157153

158-
const { computations, defaultExport, templateProperties } = generator.parseJs();
154+
const { computations, templateProperties, namespace } = generator.parseJs();
159155

160156
// Remove these after version 2
161157
if ( templateProperties.onrender ) {
@@ -170,36 +166,6 @@ export default function dom ( parsed, source, options ) {
170166
templateProperties.ondestroy = templateProperties.onteardown;
171167
}
172168

173-
let namespace = null;
174-
if ( templateProperties.namespace ) {
175-
const ns = templateProperties.namespace.value.value;
176-
namespace = namespaces[ ns ] || ns;
177-
178-
removeObjectKey( generator.code, defaultExport.declaration, 'namespace' );
179-
}
180-
181-
if ( templateProperties.components ) {
182-
let hasNonImportedComponent = false;
183-
templateProperties.components.value.properties.forEach( property => {
184-
const key = property.key.name;
185-
const value = source.slice( property.value.start, property.value.end );
186-
if ( generator.importedNames.has( value ) ) {
187-
generator.importedComponents.set( key, value );
188-
} else {
189-
hasNonImportedComponent = true;
190-
}
191-
});
192-
if ( hasNonImportedComponent ) {
193-
// remove the specific components that were imported, as we'll refer to them directly
194-
Array.from( generator.importedComponents.keys() ).forEach( key => {
195-
removeObjectKey( generator.code, templateProperties.components.value, key );
196-
});
197-
} else {
198-
// remove the entire components portion of the export
199-
removeObjectKey( generator.code, defaultExport.declaration, 'components' );
200-
}
201-
}
202-
203169
const getUniqueName = generator.getUniqueNameMaker( [ 'root' ] );
204170
const component = getUniqueName( 'component' );
205171

src/generators/server-side-rendering/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ export default function ssr ( parsed, source, options ) {
117117
` );
118118

119119
templateProperties.components.value.properties.forEach( prop => {
120-
builders.renderCss.addLine( `addComponent( ${generator.alias( 'template' )}.components.${prop.key.name} );` );
120+
const { name } = prop.key;
121+
const expression = generator.importedComponents.get( name ) || `${generator.alias( 'template' )}.components.${name}`;
122+
builders.renderCss.addLine( `addComponent( ${expression} );` );
121123
});
122124
}
123125

src/generators/server-side-rendering/visitors/Component.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export default {
5050
}))
5151
.join( ', ' );
5252

53-
const expression = node.name === ':Self' ? generator.name : `${generator.alias( 'template' )}.components.${node.name}`;
53+
const expression = node.name === ':Self' ? generator.name : generator.importedComponents.get( node.name ) || `${generator.alias( 'template' )}.components.${node.name}`;
5454

5555
bindings.forEach( binding => {
5656
generator.addBinding( binding, expression );

test/server-side-rendering/index.js

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import assert from 'assert';
22
import * as fs from 'fs';
3+
import * as path from 'path';
34

4-
import { addLineNumbers, exists, loadConfig, setupHtmlEqual, svelte, tryToLoadJson } from '../helpers.js';
5+
import { addLineNumbers, loadConfig, setupHtmlEqual, svelte, tryToLoadJson } from '../helpers.js';
56

67
function tryToReadFile ( file ) {
78
try {
@@ -24,24 +25,42 @@ describe( 'ssr', () => {
2425
fs.readdirSync( 'test/server-side-rendering/samples' ).forEach( dir => {
2526
if ( dir[0] === '.' ) return;
2627

27-
const solo = exists( `test/server-side-rendering/samples/${dir}/solo` );
28+
// add .solo to a sample directory name to only run that test
29+
const solo = /\.solo$/.test( dir );
2830

2931
if ( solo && process.env.CI ) {
3032
throw new Error( 'Forgot to remove `solo: true` from test' );
3133
}
3234

3335
( solo ? it.only : it )( dir, () => {
34-
const component = require( `./samples/${dir}/main.html` );
36+
dir = path.resolve( 'test/server-side-rendering/samples', dir );
37+
const component = require( `${dir}/main.html` );
3538

36-
const expectedHtml = tryToReadFile( `test/server-side-rendering/samples/${dir}/_expected.html` );
37-
const expectedCss = tryToReadFile( `test/server-side-rendering/samples/${dir}/_expected.css` ) || '';
39+
const expectedHtml = tryToReadFile( `${dir}/_expected.html` );
40+
const expectedCss = tryToReadFile( `${dir}/_expected.css` ) || '';
3841

39-
const data = tryToLoadJson( `test/server-side-rendering/samples/${dir}/data.json` );
40-
const html = component.render( data );
41-
const { css } = component.renderCss();
42+
const data = tryToLoadJson( `${dir}/data.json` );
43+
let html;
44+
let css;
45+
46+
try {
47+
html = component.render( data );
48+
css = component.renderCss().css;
49+
} catch ( err ) {
50+
fs.readdirSync( dir ).forEach( file => {
51+
if ( file[0] === '_' ) return;
52+
const source = fs.readFileSync( `${dir}/${file}`, 'utf-8' );
53+
const { code } = svelte.compile( source, { generate: 'ssr' });
54+
console.group( file );
55+
console.log( addLineNumbers( code ) );
56+
console.groupEnd();
57+
});
58+
59+
throw err;
60+
}
4261

43-
fs.writeFileSync( `test/server-side-rendering/samples/${dir}/_actual.html`, html );
44-
if ( css ) fs.writeFileSync( `test/server-side-rendering/samples/${dir}/_actual.css`, css );
62+
fs.writeFileSync( `${dir}/_actual.html`, html );
63+
if ( css ) fs.writeFileSync( `${dir}/_actual.css`, css );
4564

4665
assert.htmlEqual( html, expectedHtml );
4766
assert.equal( css.replace( /^\s+/gm, '' ), expectedCss.replace( /^\s+/gm, '' ) );

0 commit comments

Comments
 (0)