Merge pull request #1358 from sveltejs/gh-1038

Add support for shorthand imports of components
pull/1363/head
Rich Harris 7 years ago committed by GitHub
commit 0dd7bf047f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -17,7 +17,7 @@ import clone from '../utils/clone';
import Stylesheet from '../css/Stylesheet'; import Stylesheet from '../css/Stylesheet';
import { test } from '../config'; import { test } from '../config';
import nodes from './nodes/index'; import nodes from './nodes/index';
import { Node, GenerateOptions, Parsed, CompileOptions, CustomElementOptions } from '../interfaces'; import { Node, GenerateOptions, ShorthandImport, Parsed, CompileOptions, CustomElementOptions } from '../interfaces';
interface Computation { interface Computation {
key: string; key: string;
@ -90,6 +90,7 @@ export default class Generator {
defaultExport: Node[]; defaultExport: Node[];
imports: Node[]; imports: Node[];
shorthandImports: ShorthandImport[];
helpers: Set<string>; helpers: Set<string>;
components: Set<string>; components: Set<string>;
events: Set<string>; events: Set<string>;
@ -139,6 +140,7 @@ export default class Generator {
this.options = options; this.options = options;
this.imports = []; this.imports = [];
this.shorthandImports = [];
this.helpers = new Set(); this.helpers = new Set();
this.components = new Set(); this.components = new Set();
this.events = new Set(); this.events = new Set();
@ -315,7 +317,7 @@ export default class Generator {
generate(result: string, options: CompileOptions, { banner = '', sharedPath, helpers, name, format }: GenerateOptions ) { generate(result: string, options: CompileOptions, { banner = '', sharedPath, helpers, name, format }: GenerateOptions ) {
const pattern = /\[✂(\d+)-(\d+)$/; 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 parts = module.split('✂]');
const finalChunk = parts.pop(); const finalChunk = parts.pop();
@ -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; const qualified = disambiguator ? `${disambiguator}-${key}` : key;
if (node.type === 'Identifier' && node.name === key) { if (node.type === 'Identifier' && node.name === key) {
@ -531,6 +533,11 @@ export default class Generator {
let name = this.getUniqueName(deconflicted); let name = this.getUniqueName(deconflicted);
this.templateVars.set(qualified, name); this.templateVars.set(qualified, name);
if (allowShorthandImport && node.type === 'Literal' && typeof node.value === 'string') {
this.shorthandImports.push({ name, source: node.value });
return;
}
// deindent // deindent
const indentationLevel = getIndentationLevel(source, node.start); const indentationLevel = getIndentationLevel(source, node.start);
if (indentationLevel) { if (indentationLevel) {
@ -548,7 +555,7 @@ export default class Generator {
if (templateProperties.components) { if (templateProperties.components) {
templateProperties.components.value.properties.forEach((property: Node) => { templateProperties.components.value.properties.forEach((property: Node) => {
addDeclaration(getName(property.key), property.value, 'components'); addDeclaration(getName(property.key), property.value, true, 'components');
}); });
} }
@ -582,7 +589,7 @@ export default class Generator {
const prop = templateProperties.computed.value.properties.find((prop: Node) => getName(prop.key) === key); 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, state: true,
changed: true changed: true
}); });
@ -599,13 +606,13 @@ export default class Generator {
if (templateProperties.events && dom) { if (templateProperties.events && dom) {
templateProperties.events.value.properties.forEach((property: Node) => { 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) { if (templateProperties.helpers) {
templateProperties.helpers.value.properties.forEach((property: Node) => { templateProperties.helpers.value.properties.forEach((property: Node) => {
addDeclaration(getName(property.key), property.value, 'helpers'); addDeclaration(getName(property.key), property.value, false, 'helpers');
}); });
} }
@ -660,13 +667,13 @@ export default class Generator {
if (templateProperties.transitions) { if (templateProperties.transitions) {
templateProperties.transitions.value.properties.forEach((property: Node) => { 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) { if (templateProperties.actions) {
templateProperties.actions.value.properties.forEach((property: Node) => { templateProperties.actions.value.properties.forEach((property: Node) => {
addDeclaration(getName(property.key), property.value, 'actions'); addDeclaration(getName(property.key), property.value, false, 'actions');
}); });
} }
} }

@ -1,6 +1,6 @@
import deindent from '../utils/deindent'; import deindent from '../utils/deindent';
import list from '../utils/list'; import list from '../utils/list';
import { CompileOptions, ModuleFormat, Node } from '../interfaces'; import { CompileOptions, ModuleFormat, Node, ShorthandImport } from '../interfaces';
interface Dependency { interface Dependency {
name: string; name: string;
@ -19,9 +19,10 @@ export default function wrapModule(
sharedPath: string, sharedPath: string,
helpers: { name: string, alias: string }[], helpers: { name: string, alias: string }[],
imports: Node[], imports: Node[],
shorthandImports: ShorthandImport[],
source: string source: string
): 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 dependencies = imports.map((declaration, i) => {
const defaultImport = declaration.specifiers.find( const defaultImport = declaration.specifiers.find(
@ -58,7 +59,16 @@ export default function wrapModule(
} }
return { name, statements, source: declaration.source.value }; 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 === 'amd') return amd(code, name, options, banner, dependencies);
if (format === 'cjs') return cjs(code, name, options, banner, sharedPath, helpers, dependencies); if (format === 'cjs') return cjs(code, name, options, banner, sharedPath, helpers, dependencies);
@ -77,6 +87,7 @@ function es(
sharedPath: string, sharedPath: string,
helpers: { name: string, alias: string }[], helpers: { name: string, alias: string }[],
imports: Node[], imports: Node[],
shorthandImports: ShorthandImport[],
source: string source: string
) { ) {
const importHelpers = helpers && ( const importHelpers = helpers && (
@ -89,10 +100,15 @@ function es(
.join('\n') .join('\n')
); );
const shorthandImportBlock = shorthandImports.length > 0 && (
shorthandImports.map(({ name, source }) => `import ${name} from ${JSON.stringify(source)};`).join('\n')
);
return deindent` return deindent`
${banner} ${banner}
${importHelpers} ${importHelpers}
${importBlock} ${importBlock}
${shorthandImportBlock}
${code} ${code}
export default ${name};`; export default ${name};`;

@ -74,6 +74,11 @@ export interface GenerateOptions {
helpers?: { name: string, alias: string }[]; helpers?: { name: string, alias: string }[];
} }
export interface ShorthandImport {
name: string;
source: string;
};
export interface Visitor { export interface Visitor {
enter: (node: Node) => void; enter: (node: Node) => void;
leave?: (node: Node) => void; leave?: (node: Node) => void;

@ -0,0 +1,3 @@
export default {
html: `<p>This is the widget.</p>`,
};

@ -0,0 +1,5 @@
<Widget/>
<script>
export default { components: { Widget: './Widget.html' } };
</script>
Loading…
Cancel
Save