rollup 빌드시 SCSS 해싱 문제

Derhon·2023년 8월 11일
0
post-thumbnail

Rollup.js를 이용해서 모듈을 개발하는 경우가 참 많다.
인터랙션이 많거나, 최대한 가벼운 모듈을 개발할 때는 SCSS를 사용하는 것이 좋은데... 이상하게 build할때마다 다른 이름의 hash된 파일을 output하는 문제가 발생했다.

이렇게 되면 내 프로젝트에서 스타일링 관련 css를 import할 때 매번 다른 이름으로 import 해야하는 문제가 발생한다.

기존코드

import { babel } from "@rollup/plugin-babel";
import external from "rollup-plugin-peer-deps-external";
import resolve from "@rollup/plugin-node-resolve";
import scss from "rollup-plugin-scss";
import typescript from "@rollup/plugin-typescript";
import terser from "@rollup/plugin-terser";

export default [
  {
    input: "./src/index.ts",
    output: [
      {
        file: "dist/index.js",
        format: "cjs",
      },
      {
        file: "dist/index.es.js",
        format: "es",
        exports: "named",
      },
    ],
    plugins: [
      scss({
        output: true,
        failOnError: true,
        outputStyle: "compressed",
      }),
      babel({
        exclude: "node_modules/**",
        presets: ["@babel/preset-react"],
      }),
      external(),
      resolve(),
      typescript(),
      terser(),
    ],
  },
];

설정 자체에는 이상이 없기 때문에 엄청나게 찾아 헤맸다.
스택오버플로우랑 rollup-plugin-scss 이슈를 다 뒤져도 별 말이 없길래 도대체 뭘까 하고 고민하던 찰나.. .처음부터 돌아가보자라는 생각이 뇌리를 스쳤다.

옵션 확인

rollup-plugin-scss의 번들 옵션을 살펴봤다.

/// <reference types="node" />
import { CreateFilter } from 'rollup-pluginutils';
import type { Plugin } from 'rollup';
export interface CSSPluginOptions {
    exclude?: Parameters<CreateFilter>[1];
    failOnError?: boolean;
    /** Literal asset filename, bypasses any hashes in the filename */
    fileName?: string;
    include?: Parameters<CreateFilter>[0];
    includePaths?: string[];
    insert?: boolean;
    /** Asset name, defaults to output.css, Rollup may add a hash to this! Check out RollupConfig.output.assetFileNames */
    name?: string;
    /** @deprecated Use `fileName` instead, currently still available for backwards compatibility */
    output?: string | false | ((css: string, styles: Styles) => void);
    prefix?: string;
    processor?: (css: string, map: string, styles: Styles) => CSS | Promise<CSS> | PostCSSProcessor;
    sass?: SassRenderer;
    sourceMap?: boolean;
    verbose?: boolean;
    watch?: string | string[];
    outputStyle?: string;
}
type CSS = string | {
    css: string;
    map: string;
};
interface MappedCSS {
    css: string;
    map: string;
}
interface Styles {
    [id: string]: string;
}
interface PostCSSProcessor {
    process: (css: string, options?: any) => MappedCSS;
}
interface SassRenderer {
    renderSync: (options: SassOptions) => SassResult;
}
interface SassOptions {
    data: string;
}
interface SassResult {
    css: Buffer;
    map?: Buffer;
}
export default function scss(options?: CSSPluginOptions): Plugin;
export {};

아 보자마자 머리가 띵~
fileName을 추가해볼까?라고 생각이들었다.

🤦‍♂️ 해결

import { babel } from "@rollup/plugin-babel";
import external from "rollup-plugin-peer-deps-external";
import resolve from "@rollup/plugin-node-resolve";
import scss from "rollup-plugin-scss";
import typescript from "@rollup/plugin-typescript";
import terser from "@rollup/plugin-terser";

export default [
  {
    input: "./src/index.ts",
    output: [
      {
        file: "dist/index.js",
        format: "cjs",
      },
      {
        file: "dist/index.es.js",
        format: "es",
        exports: "named",
      },
    ],
    plugins: [
      scss({
        output: true,
        failOnError: true,
        outputStyle: "compressed",
        fileName: "style.css",
      }),
      babel({
        exclude: "node_modules/**",
        presets: ["@babel/preset-react"],
      }),
      external(),
      resolve(),
      typescript(),
      terser(),
    ],
  },
];

그래... 요즘 이렇다할 에러도없고 너무 쉽다했다.
역시 항상 머리아프게 하는 문제는 별거 아닐 가능성 35186106841651%임을 잊지말자...

profile
🧑‍🚀 이사했어요 ⮕ https://99uulog.tistory.com/

0개의 댓글