Skip to content

[eslint-plugin] optimize-svg-components 동작 문의 #123

@Yoonlang

Description

@Yoonlang

Description

안녕하세요,

optimize-svg-components의 docs의 내용을 제가 제대로 이해했는지, 그리고 동작에 의문이 드는 점이 있어서 문의드립니다!

주요 문의 내용

  1. props가 비어있을 때 svgo 최적화를 해주지 않는 것은 의도된 것인지
  2. props가 비어있지 않을 때에도 비어있다고 판단하여 svgo 최적화를 진행하지 않는 점

1. props가 비어있을 때 svgo 최적화를 해주지 않는 것은 의도된 것인지

https://github.com/NaverPayDev/code-style/blob/main/packages/eslint-plugin/docs/optimize-svg-components.md

단, 다음과 같은 특징이 있는 컴포넌트는 최적화에서 제외합니다.
props로 id가 존재하는 경우
내부에 classnames로 클래스를 정의한 경우
요소에 한글을 포함한 경우
이미 최적화되었다고 판단된 경우 (주의사항 참고)

라고 적혀있어서 props가 비어있을 때도 svgo 최적화가 될 것이라 판단했습니다.

내부 동작에선 svgValidator가 아래 코드와 같이 return !isEmpty(props)를 포함하여 이에 대해 문의드립니다!

const svgValidator = (context, globalScope) => {
const importDeclarations = getImportDeclarations(globalScope.block)
const hasClassNames =
findSpecificImportDeclaration(importDeclarations, {
from: 'classnames/bind',
}) ||
findSpecificImportDeclaration(importDeclarations, {
from: 'styled-components',
})
const props = hasClassNames ? null : extractComponentProps(globalScope.block)
const comments = getAllComments(context)
const isOptimizedAlready = comments.some(({value}) => value.includes(SVG_OPTIMIZED_COMMENT_CONTENT))
return !isEmpty(props) && !hasClassNames && !isOptimizedAlready
}

2. props가 비어있지 않을 때에도 비어있다고 판단하여 svgo 최적화를 진행하지 않는 점

다음은 저의 예시입니다.

// src/components/common/svg/check-icon.tsx

import type {SVGStyleProps} from '@naverpay/svg-manager'

function CheckIcon(properties: SVGStyleProps) {
    return (
        <svg xmlns="http://www.w3.org/2000/svg" width={properties.width} height="13" viewBox="0 0 18 15">
            <path
                fill="#09aa5c"
                fillRule="evenodd"
                stroke="#09aa5c"
                strokeWidth=".5"
                d="M6.351 13.999c-.241 0-.473-.099-.644-.276l-4.44-4.61C1.095 8.935 1 8.694 1 8.442c0-.25.096-.491.266-.667.358-.37.931-.37 1.288 0l3.797 3.94 9.094-9.439c.357-.37.93-.37 1.288 0 .17.176.267.417.267.668 0 .252-.096.492-.267.669L6.996 13.723c-.172.178-.404.278-.645.277"
            />
            <path />
            <path />
            <path />
            <path />
        </svg>
    )
}

export default CheckIcon
{
        plugins: {
            '@naverpay': naverpayPlugin,
        },
        rules: {
            '@naverpay/optimize-svg-components': ['error', {pathGroups: [{path: '**/svg/**/*.tsx'}]}],
        },
    },

해당 예시에서는 로직상 정상적으로 svgo 최적화가 진행되어야하지만 진행되지 않음을 확인했습니다.

아래는 직접 콘솔을 찍어본 결과입니다.

const svgValidator = (context, globalScope) => {
  const importDeclarations = getImportDeclarations(globalScope.block);
  const hasClassNames = findSpecificImportDeclaration(importDeclarations, {
    from: "classnames/bind"
  }) || findSpecificImportDeclaration(importDeclarations, {
    from: "styled-components"
  });
  const props = hasClassNames ? null : extractComponentProps(globalScope.block);
  console.log('props', props)
  const comments = getAllComments(context);
  const isOptimizedAlready = comments.some(({
    value
  }) => value.includes(SVG_OPTIMIZED_COMMENT_CONTENT));
  console.log('isOptimizedAlready',isOptimizedAlready)
  console.log('hasClassNames', hasClassNames)
  console.log('isEmpty(props)', isEmpty(props))
  console.log('extractComponentProps(globalScope.block)', extractComponentProps(globalScope.block))
  return !isEmpty(props) && !hasClassNames && !isOptimizedAlready;
};
props null
isOptimizedAlready false
hasClassNames undefined
isEmpty(props) true
extractComponentProps(globalScope.block) null
canOptimize false // svgValidator의 반환값

Environment

일부만 보여드리는 점 양해 부탁드립니다.

pnpm version: 10.13.1
node version: v22.17.1

// package.json

{
    "type": "module",
    "dependencies": {
        "@naverpay/svg-manager": "^1.0.0",
    },
  "devDependencies": {
        "@eslint/eslintrc": "^3",
        "@naverpay/editorconfig": "^0.0.4",
        "@naverpay/eslint-config": "^2.3.0",
        "@naverpay/eslint-plugin": "^2.2.0",
        "@naverpay/markdown-lint": "^0.0.3",
        "@naverpay/prettier-config": "^1.0.1",
        "@naverpay/stylelint-config": "^1.0.0",
        "@next/eslint-plugin-next": "^15.4.5",
        "eslint": "^9",
        "eslint-config-next": "15.2.4",
        "eslint-plugin-react-hooks": "^5.2.0",
        "stylelint": "^16.22.0",
    },
}

// eslint.config.mjs

const eslintConfig = [
    ...naverpay.configs.typescript,
    ...naverpay.configs.strict,
    ...naverpay.configs.packageJson,
    ...naverpay.configs.react,
    {
        files: ['**/app/api/**/*.{js,ts}'],
        ...naverpay.configs.node,
    },
    {
        plugins: {
            '@naverpay': naverpayPlugin,
        },
        rules: {
            '@naverpay/prevent-default-import': ['error', {packages: ['react']}],
            '@naverpay/sort-exports': ['error', {rules: []}],
            '@naverpay/memo-react-components': ['error', {path: ['**/components/**']}],
            '@naverpay/optimize-svg-components': ['error', {pathGroups: [{path: '**/svg/**/*.tsx'}]}],
            '@naverpay/svg-unique-id': ['warn', {paths: ['**/svg/**/*.tsx']}],
            '@naverpay/peer-deps-in-dev-deps': 'error',
        },
    },
]

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions