Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(atomic): add SVG transformer #4867

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

chore(atomic): add SVG transformer #4867

wants to merge 4 commits into from

Conversation

y-lakhdar
Copy link
Contributor

@y-lakhdar y-lakhdar commented Jan 16, 2025

Update the Lit build process to be support SVG imports

Explanation

We are essentially creating a compiler which takes a list of TypeScript files (Lit components and dependencies) and compiles them to their corresponding JavaScript keeping the same file structure as in /src.
Typescript doc

To that compiler, I have added a SVG custom transformer.

Example

The following typescript file

import Tick from '../../../images/checkbox.svg';
() => console.log(Tick);

was transpiled to

import Tick from '../../../images/checkbox.svg';
() => console.log(Tick);

With the SVG transformer, we have

const Tick = "<svg viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n    <path d=\"M1.5 5L4.6 7.99999L11 1\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n</svg>";
() => console.log(Tick);

Pseudo-code

  1. Load the TypeScript configuration file (tsconfig.lit.json)
  2. Create a default CompilerHost which uses the file system to get files (using program.emit function).
  3. To that program, provide a customTransformers which will essentially visit recursively tree nodes and check for svg import statements.
  4. When a SVG import statement is encountered, replace it with a "create variable statement" using the createVariableStatement typescript built-in method. Ensure to right-hand side of the assignation is the content of the .svg file

https://coveord.atlassian.net/browse/KIT-3865

Copy link

Pull Request Report

PR Title

✅ Title follows the conventional commit spec.

Live demo links

Bundle Size

File Old (kb) New (kb) Change (%)
case-assist 243.8 243.8 0
commerce 355 355 0
search 414.9 414.9 0
insight 406.2 406.2 0
recommendation 256.1 256.1 0
ssr 408.8 408.8 0
ssr-commerce 372.7 372.7 0

SSR Progress

Use case SSR (#) CSR (#) Progress (%)
search 39 44 89
recommendation 0 4 0
case-assist 0 6 0
insight 0 27 0
commerce 0 15 0
Detailed logs search : buildInteractiveResult
search : buildInteractiveInstantResult
search : buildInteractiveRecentResult
search : buildInteractiveCitation
search : buildGeneratedAnswer
recommendation : missing SSR support
case-assist : missing SSR support
insight : missing SSR support
commerce : missing SSR support

GitHub Actions Bot and others added 2 commits January 16, 2025 17:37
before: [svgTransformer],
};

return program.emit(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creates a CompilerHost with our custom transformer

createStringLiteral(svgContent)
),
],
NodeFlags.Const
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asking to make the assignation statement a const.

const variable = ...

variableName,
bindingName,
exclamationToken,
createStringLiteral(svgContent)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

converting the SVG content into a string literal for the right hand side of the assignation

export default function svgTransformer(context) {
const {factory} = context;

function visit(node) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recursive method that visits node and their children following import statements

const {factory} = context;

function visit(node) {
if (isImportDeclaration(node)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the statement is something like

import something from "something"

const svgContent = readFileSync(svgPath, 'utf8');
const variableName = node.importClause?.name?.escapedText;

return createStatement(factory, svgContent, variableName);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After getting the variable name from the import and the content from the svg file, we are ready to craft the new statement

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants