Skip to content

Commit

Permalink
Merge pull request #1358 from sveltejs/gh-1038
Browse files Browse the repository at this point in the history
Add support for shorthand imports of components
  • Loading branch information
Rich-Harris authored Apr 20, 2018
2 parents 350d1ed + f90091b commit 0dd7bf0
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 14 deletions.
25 changes: 16 additions & 9 deletions src/generators/Generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import clone from '../utils/clone';
import Stylesheet from '../css/Stylesheet';
import { test } from '../config';
import nodes from './nodes/index';
import { Node, GenerateOptions, Parsed, CompileOptions, CustomElementOptions } from '../interfaces';
import { Node, GenerateOptions, ShorthandImport, Parsed, CompileOptions, CustomElementOptions } from '../interfaces';

interface Computation {
key: string;
Expand Down Expand Up @@ -90,6 +90,7 @@ export default class Generator {

defaultExport: Node[];
imports: Node[];
shorthandImports: ShorthandImport[];
helpers: Set<string>;
components: Set<string>;
events: Set<string>;
Expand Down Expand Up @@ -139,6 +140,7 @@ export default class Generator {
this.options = options;

this.imports = [];
this.shorthandImports = [];
this.helpers = new Set();
this.components = new Set();
this.events = new Set();
Expand Down Expand Up @@ -315,7 +317,7 @@ export default class Generator {
generate(result: string, options: CompileOptions, { banner = '', sharedPath, helpers, name, format }: GenerateOptions ) {
const pattern = /\[✂(\d+)-(\d+)$/;

const module = wrapModule(result, format, name, options, banner, sharedPath, helpers, this.imports, this.source);
const module = wrapModule(result, format, name, options, banner, sharedPath, helpers, this.imports, this.shorthandImports, this.source);

const parts = module.split('✂]');
const finalChunk = parts.pop();
Expand Down Expand Up @@ -517,7 +519,7 @@ export default class Generator {
`);
};

const addDeclaration = (key: string, node: Node, disambiguator?: string, conflicts?: Record<string, boolean>) => {
const addDeclaration = (key: string, node: Node, allowShorthandImport?: boolean, disambiguator?: string, conflicts?: Record<string, boolean>) => {
const qualified = disambiguator ? `${disambiguator}-${key}` : key;

if (node.type === 'Identifier' && node.name === key) {
Expand All @@ -531,6 +533,11 @@ export default class Generator {
let name = this.getUniqueName(deconflicted);
this.templateVars.set(qualified, name);

if (allowShorthandImport && node.type === 'Literal' && typeof node.value === 'string') {
this.shorthandImports.push({ name, source: node.value });
return;
}

// deindent
const indentationLevel = getIndentationLevel(source, node.start);
if (indentationLevel) {
Expand All @@ -548,7 +555,7 @@ export default class Generator {

if (templateProperties.components) {
templateProperties.components.value.properties.forEach((property: Node) => {
addDeclaration(getName(property.key), property.value, 'components');
addDeclaration(getName(property.key), property.value, true, 'components');
});
}

Expand Down Expand Up @@ -582,7 +589,7 @@ export default class Generator {

const prop = templateProperties.computed.value.properties.find((prop: Node) => getName(prop.key) === key);

addDeclaration(key, prop.value, 'computed', {
addDeclaration(key, prop.value, false, 'computed', {
state: true,
changed: true
});
Expand All @@ -599,13 +606,13 @@ export default class Generator {

if (templateProperties.events && dom) {
templateProperties.events.value.properties.forEach((property: Node) => {
addDeclaration(getName(property.key), property.value, 'events');
addDeclaration(getName(property.key), property.value, false, 'events');
});
}

if (templateProperties.helpers) {
templateProperties.helpers.value.properties.forEach((property: Node) => {
addDeclaration(getName(property.key), property.value, 'helpers');
addDeclaration(getName(property.key), property.value, false, 'helpers');
});
}

Expand Down Expand Up @@ -660,13 +667,13 @@ export default class Generator {

if (templateProperties.transitions) {
templateProperties.transitions.value.properties.forEach((property: Node) => {
addDeclaration(getName(property.key), property.value, 'transitions');
addDeclaration(getName(property.key), property.value, false, 'transitions');
});
}

if (templateProperties.actions) {
templateProperties.actions.value.properties.forEach((property: Node) => {
addDeclaration(getName(property.key), property.value, 'actions');
addDeclaration(getName(property.key), property.value, false, 'actions');
});
}
}
Expand Down
24 changes: 20 additions & 4 deletions src/generators/wrapModule.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import deindent from '../utils/deindent';
import list from '../utils/list';
import { CompileOptions, ModuleFormat, Node } from '../interfaces';
import { CompileOptions, ModuleFormat, Node, ShorthandImport } from '../interfaces';

interface Dependency {
name: string;
Expand All @@ -19,9 +19,10 @@ export default function wrapModule(
sharedPath: string,
helpers: { name: string, alias: string }[],
imports: Node[],
shorthandImports: ShorthandImport[],
source: string
): string {
if (format === 'es') return es(code, name, options, banner, sharedPath, helpers, imports, source);
if (format === 'es') return es(code, name, options, banner, sharedPath, helpers, imports, shorthandImports, source);

const dependencies = imports.map((declaration, i) => {
const defaultImport = declaration.specifiers.find(
Expand Down Expand Up @@ -58,7 +59,16 @@ export default function wrapModule(
}

return { name, statements, source: declaration.source.value };
});
})
.concat(
shorthandImports.map(({ name, source }) => ({
name,
statements: [
`${name} = (${name} && ${name}.__esModule) ? ${name}["default"] : ${name};`,
],
source,
}))
);

if (format === 'amd') return amd(code, name, options, banner, dependencies);
if (format === 'cjs') return cjs(code, name, options, banner, sharedPath, helpers, dependencies);
Expand All @@ -77,6 +87,7 @@ function es(
sharedPath: string,
helpers: { name: string, alias: string }[],
imports: Node[],
shorthandImports: ShorthandImport[],
source: string
) {
const importHelpers = helpers && (
Expand All @@ -89,10 +100,15 @@ function es(
.join('\n')
);

const shorthandImportBlock = shorthandImports.length > 0 && (
shorthandImports.map(({ name, source }) => `import ${name} from ${JSON.stringify(source)};`).join('\n')
);

return deindent`
${banner}
${importHelpers}
${importBlock}
${shorthandImportBlock}
${code}
export default ${name};`;
Expand Down Expand Up @@ -297,4 +313,4 @@ function getGlobalFn(globals: any): (id: string) => string {
}

return () => undefined;
}
}
7 changes: 6 additions & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ export interface GenerateOptions {
helpers?: { name: string, alias: string }[];
}

export interface ShorthandImport {
name: string;
source: string;
};

export interface Visitor {
enter: (node: Node) => void;
leave?: (node: Node) => void;
Expand All @@ -91,4 +96,4 @@ export interface PreprocessOptions {
filename?: string
}

export type Preprocessor = (options: {content: string, attributes: Record<string, string | boolean>, filename?: string}) => { code: string, map?: SourceMap | string };
export type Preprocessor = (options: {content: string, attributes: Record<string, string | boolean>, filename?: string}) => { code: string, map?: SourceMap | string };
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>This is the widget.</p>
3 changes: 3 additions & 0 deletions test/runtime/samples/component-shorthand-import/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
html: `<p>This is the widget.</p>`,
};
5 changes: 5 additions & 0 deletions test/runtime/samples/component-shorthand-import/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Widget/>

<script>
export default { components: { Widget: './Widget.html' } };
</script>

0 comments on commit 0dd7bf0

Please sign in to comment.