-
Notifications
You must be signed in to change notification settings - Fork 6
Feature Request: Resolve Object Attributes #12
Description
Hello everyone, thanks for the good work first of all. The title is itself self-explanatory i think, but please find below more info for completion.
Big question is whether this should be supported at all. Please discuss.
Rationale
Sometimes we need to pass object as prop. For example:
<!-- Image.svelte -->
<script lang="ts">
export let src: {
mobile: string;
desktop: string;
};
</script>
<picture>
<!-- mobile img source -->
<!-- desktop img source -->
</picture>Right now it is not possible with svelte-preprocess-import-assets.
<script lang="ts">
import Image from './Image.svelte';
</script>
<Image
src={{
mobile: '../assets/image.150x150.png',
desktop: '../assets/image.400x400.png',
}}
/>src.mobile and src.desktop here would be parsed as literals.
How to?
I played with https://astexplorer.net/ and did some experimentation, seen in stackblitz here (run pnpm install & pnpm dev
Repo here if needed.
This is just some minimal code. It looks ugly, but we can expand from the idea.
const TAG = 'Image';
const STRING_TO_REPLACE = `'/vite.svg'`;
walk(ast.html, {
enter(node) {
if (node.name === TAG) {
const srcAttr = node.attributes.find((attr) => attr.name === 'src');
for (const value of srcAttr.value) {
if (value?.expression?.type === 'ObjectExpression') {
for (const prop of value.expression.properties) {
if (prop.type === 'Property' && prop.value?.type === 'Literal') {
const { start, end } = prop.value;
s.update(start, end, STRING_TO_REPLACE);
}
}
}
}
}
},
});Potential Issues?
(1) How to handle nested objects?
- only support top level? => best imo, keep things minimal, can expand in the future when there's people requesting it
- provide a
depthconfig? - support recursively by default?
(2) Nuances such as if properties are computed values? Maybe we can do a try-catch or detect these cases and just skip the processing.
Change to config interface?
ImportAssetsOptions
A separate option for configuring behavior concerning this feature?
enabledto enable or disable this feature globallydepthto limit, if (1) in Potential Issues is of concern
interface ImportAssetsOptions {
sources?: AssetSource[] | ((defaultSources: AssetSource[]) => AssetSource[]);
importPrefix?: string;
http?: boolean;
urlFilter?: (url: string) => boolean;
+ transformObject: {
+ enabled?: boolean;
+ depth?: number;
+ }
}AssetSource
- An additional
objectAttributesfor this purpose?
interface AssetSource {
tag: string;
srcAttributes?: string[];
srcsetAttributes?: string[];
filter?: (metadata: FilterMetadata) => boolean;
+ objectAttributes?: string[];
}I would love to help out further if needed but might need more guidance.