Sveltekit 퍼지 미사용 CSS

13384 단어
Svelte 파일에서 css를 제거하는 스크립트를 찾기 위해 오랫동안 노력한 끝에 마침내 나만의 스크립트를 작성했습니다.

나는 Tailwindcss를 사용하여 개별 Svelte 구성 요소를 빌드하고 있기 때문에 이 문제가 발생합니다. 그리고 내가svelte-package 구성 요소를 구성하면 전체 라이브러리의 모든 CSS가 각 구성 요소에 들어가 사용되지 않는 CSS가 엄청나게 많아집니다.

// component.svelte
<style lang="postcss">
</style>



// postcss.config.js
plugins: {
    'postcss-import': {}, // so we can use: <style lang="postcss"> @import '../app.css' </style>
    tailwindcss: {},
    autoprefixer: {}
    }



// svelte.config.js
// puts all tailwindcss in each component :/
preprocess: [
    preprocess({
        // postcss: true,
        postcss: {
            configFilePath: path.resolve(__dirname, './postcss.config.js'),
            prependData: `@import '${path.resolve('./src/utilities.css')}';`
        }
    })
],



위의 설정은 사용하지 않는 모든 CSS를 제외하고 개별 구성 요소를 패키징하는 데 적합합니다.

인터넷에 있는 대부분의 솔루션은 @fullhuman/postcss-purgecss를 사용하지만 내가 무엇을 하든 .svelte 파일에서 작동하도록 할 수 없었습니다.

그런 다음 약간의 regex로 파일을 구문 분석하고 일치하지 않는 CSS를 제거할 수 있다는 것을 깨달았습니다.

코드는 다음과 같습니다.

// purge.js

// iterate through all .svelte files in ./package directory
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageDir = path.resolve(__dirname, './package');
const files = fs.readdirSync(packageDir);
const svelteFiles = files.filter((file) => file.endsWith('.svelte'));

svelteFiles.forEach((file) => {
    // remove all unused css in <style> tags from this svelte file
    const filePath = path.resolve(packageDir, file);
    const fileContents = fs.readFileSync(filePath, 'utf8');
    const styleTagRegex = /<style[^]+?<\/style>/gi;
    const styleTagContents = fileContents.match(styleTagRegex);

    // get rest of file contents
    const restOfFile = fileContents.replace(styleTagRegex, '');

    // skip over any components without style
    if (!styleTagContents) return;

    // get content between <style> tags
    const styleTagContentRegex = /<style[^]+?<\/style>/i;
    const styleTagContent = styleTagContents[0].match(styleTagContentRegex)[0];
    // console.log('styleTagContent', styleTagContent);

    // regex parse out each class statement, keep the leading . and the {} block
    const classRegex = /\.([a-zA-Z0-9_-]+)[^]+?{[^]+?}/gi;
    const classStatements = styleTagContent.match(classRegex);

    // for each class Statement NoNewLines
    // check if it is used in any of the svelte files classes
    // if not, remove it from the style tag
    // if so, keep it in the style tag
    // write the new style tag to the file

    const keep = classStatements.map((statement) => {
        const className = statement.match(/\.([a-zA-Z0-9_-]+)/i)[1];

        // check if the className appears as a whole word in between quotes of class=""
        // exclude hyphenated matches
        // only match on whole words surrounded by spaces or quotes
        const regex = new RegExp(`class="[^]*?(\\s|")${className}(\\s|")[^]*?"`, 'gi');
        return restOfFile.match(regex) ? statement : '';
    });

    // join keep together
    const newStyleTagContent = keep.join('');

    // wrap in <style> tags
    const newStyleTagBlock = `<style>${newStyleTagContent}</style>`;

    // replace old style tag with new style tag
    const newFileContents = fileContents.replace(styleTagContent, newStyleTagBlock);

    // write new file contents to file
    fs.writeFileSync(filePath, newFileContents);
});



그것이 당신에게도 도움이 되길 바랍니다!

좋은 웹페이지 즐겨찾기