gregberge / svgr

Transform SVGs into React components 🦁
https://react-svgr.com
MIT License
10.58k stars 421 forks source link

The upgrade of `@babel/generator` to `v7.20.5` ignores new lines from the template #809

Open dfernandez79 opened 1 year ago

dfernandez79 commented 1 year ago

💥 Regression Report

The upgrade of @babel/generator to v7.20.5 ignores new lines from the template

Related Babel issue (closed as "won't fix"): https://github.com/babel/babel/issues/15064

The babel generator caused this issue. But, it will affect users of SVGR that are sensitive to the output format (ie. tests that compare SVGR output or lint checks). In theory, it shouldn't affect the runtime behavior.

Last working version

Worked up to version: 6.3.1 (==> it worked when @babel/generator resolves to pre-7.20, but you can reproduce this issue in 6.3.1 and a newer babel version that matches the semver in @svgr/core)

Stopped working in version: 6.5.1

Forcing NPM to use @babel/generator 7.18.3 works.

To Reproduce

Use a test file (like the one from the playground):

<?xml version="1.0" encoding="UTF-8"?>
<svg width="48px" height="1px" viewBox="0 0 48 1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
    <title>Rectangle 5</title>
    <desc>Created with Sketch.</desc>
    <defs></defs>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="19-Separator" transform="translate(-129.000000, -156.000000)" fill="#063855">
            <g id="Controls/Settings" transform="translate(80.000000, 0.000000)">
                <g id="Content" transform="translate(0.000000, 64.000000)">
                    <g id="Group" transform="translate(24.000000, 56.000000)">
                        <g id="Group-2">
                            <rect id="Rectangle-5" x="25" y="36" width="48" height="1"></rect>
                        </g>
                    </g>
                </g>
            </g>
        </g>
    </g>
</svg>

Then run @svgr/cli with the default options:

npx @svgr/cli test.svg

Output:

import * as React from "react";
const SvgTest = (props) => (
  <svg width={48} height={1} xmlns="http://www.w3.org/2000/svg" {...props}>
    <path d="M0 0h48v1H0z" fill="#063855" fillRule="evenodd" />
  </svg>
);
export default SvgTest;

The output ignores the new lines in the defaultTemplate: https://github.com/gregberge/svgr/blob/main/packages/babel-plugin-transform-svg-component/src/defaultTemplate.ts

Expected behavior

The output should preserve the new lines of the template:

import * as React from "react";

const SvgTest = (props) => (
  <svg width={48} height={1} xmlns="http://www.w3.org/2000/svg" {...props}>
    <path d="M0 0h48v1H0z" fill="#063855" fillRule="evenodd" />
  </svg>
);

export default SvgTest;
liuxingbaoyu commented 1 year ago

Previously babel didn't preserve newlines, it just added them forever. https://github.com/babel/babel/issues/15064#issuecomment-1351776560

dfernandez79 commented 1 year ago

SVGR allows passing options to Babel.

I tried this:

.svgrc

{
  "typescript": true,
  "jsx": {"babelConfig": {"retainLines": true}}
}

Then:

npx @svgr/cli test.svg

I get the output file using Typescript (so svgr is reading the config), but the retainLines option didn't have any effect.

liuxingbaoyu commented 1 year ago

https://babeljs.io/docs/en/options#generatoropts Have you tried setting it as a generator option?

{"babelConfig": {generatoropts:{"retainLines": true}}}

roni-castro-db commented 1 year ago

retainLines did not work for me.

Temporarily I'm fixing this by adding ${'\n'} and then running prettier --write to fix the issue.

https://user-images.githubusercontent.com/95294257/208218832-1ebdb9b9-657a-4daf-aab1-f8be7fb11fe5.mov

dfernandez79 commented 1 year ago

https://babeljs.io/docs/en/options#generatoropts Have you tried setting it as a generator option?

{"babelConfig": {generatoropts:{"retainLines": true}}}

Thanks for the suggestion! I tried it, but it didn't work:

{
  "typescript": true,
  "jsx": {
    "babelConfig": { "generatorOpts": {"retainLines": true } }
  }
}
dfernandez79 commented 1 year ago

@roni-castro-db thanks! that hack worked for me

liuxingbaoyu commented 1 year ago

I did some research.

  1. The configuration does not take effect .svgrrc instead of .svgrc.
  2. The location information is discarded at a certain stage, which makes it impossible to preserve the newline.

This sucks and I haven't thought of a good solution.

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.