svgr icon indicating copy to clipboard operation
svgr copied to clipboard

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

Open dfernandez79 opened this issue 3 years ago • 8 comments

💥 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;

dfernandez79 avatar Dec 14 '22 17:12 dfernandez79

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

liuxingbaoyu avatar Dec 14 '22 20:12 liuxingbaoyu

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.

dfernandez79 avatar Dec 16 '22 16:12 dfernandez79

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

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

liuxingbaoyu avatar Dec 16 '22 22:12 liuxingbaoyu

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

roni-castro-db avatar Dec 17 '22 02:12 roni-castro-db

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 avatar Dec 17 '22 11:12 dfernandez79

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

dfernandez79 avatar Dec 17 '22 11:12 dfernandez79

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.

liuxingbaoyu avatar Dec 18 '22 13:12 liuxingbaoyu

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.

stale[bot] avatar May 21 '23 19:05 stale[bot]