1-classname 中文文档教程

发布于 4年前 浏览 23 项目主页 更新于 3年前

npmnpm bundle size

forthebadgeforthebadge

1-classname

生成一位数字类名及更多。

Why

与其使用创建不必要的长类名的传统 css 类名散列,不如使用一位数字类名策略将类名减少到仅 1 个字节。

hashingexamplebyte / class
traditional hash[path][name]__[local]--[hash:base64:5]cssmain__anyLocal--YWtkdat least 8 byte
one digit[a-Z]a1

假设平均传统哈希的平均长度为 16,并且有大约 300 个类并且使用了 id:

// Traditional Hash
16 * 300 // 4,800 byte used

// one digit hash
( 52 * 1 ) / ( (300 - 52) * 2) // 548 byte used

// For further explaination, please visit 'one digit hashing' section below.

通过使用 1-classname,我们将 classname 单独使用的字节减少了 8.75x

Happy Fox

Note

虽然传统的 css 类名确保类名永远不会重复,但使用“一个类名”(此模块)你有确保 className 永远不会被自己复制。 您可能想使用传统的哈希,然后使用一个类名来缩短它,如下所示:

import hash from '1-clasname'

hash(`${getPathAndNameAndClassNameSomehow()}`) // cssmain__anyLocal--YWtkd => a

现在我们 100% 唯一的一位数类名并减少包大小。

One digit hashing

一个数字是减少长散列的策略className 只保留 1 位数字。 如果全部使用一位数,则使用两位数,依此类推。 注意:虽然理论上我们可以对所有类名使用一个数字(例如:表情符号、ASCII 字符),但我们希望遵循 className 的 w3 标准。 这意味着它并不总是一位数,但总是有效的 w3 标准一位数。

这将有助于将长类名减少为短类名,从而减少大量的包大小。

序列可以描述如下:

rangedigitpossible classname
1-521a-Z
53-27562aa-ZZ
2757-2433633aaa-ZZZ
and so onnn([a-Z])

或举例说明如下:

index01232526275152537879103104105275527562757143362
characterabcdzABZaaabaAaBaZbabbZZaaaaabZZZ

随着范围的增加,可以使用斐波那契数列描述如下:

const generateLimit = (digits: number) => {
    if (digits === 0) return 0

    return 52 ** digits + generateLimit(digits - 1)
}

const limit = generateLimit(digits) - (digits - 1)

当className为hash时,将作为key存储在object中如下:

{
    [key-1]: "a",
    [key-2]: "b"
    [key-3]: "c"
}

即第二次调用该类时,不会生成新的类名,而是使用旧的类名。

Getting started

只需使用 yarn 或 npm 安装即可。

yarn add 1-classname

// or with npm
npm install 1-classname

一个类名具有内置的 TypeScript 支持,这意味着不需要 @types/1-classname

Usage

该库旨在与 css-loader 的 localIdentName 一起使用。

以下代码演示如何减少 .module.sass 文件的类名。

cssLoaderOptions: {
    getLocalIdent: (
        loaderContext,
        localIdentName,
        localName,
        options
    ) => {
        const filePath = loaderContext.resourcePath
        const fileBaseName = basename(filePath)

        if (/\.module\.sass$/.test(fileBaseName)) {
            const modulePathParts = filePath.split('/')

            const moduleName =
                modulePathParts[modulePathParts.length - 2]

            return `_${oneClassName(moduleName + localName)}`
        }

        return localName
    }
}

如果你想要前缀,你可以使用模板文字:

generateLocalIdentSomehow: (string) => `${generatePrefixSomehow()}-${hash(string)}`,

Contribution

欢迎所有贡献、讨论和 PR。

如果您有任何问题,请随时在 issue 提问

npmnpm bundle size

forthebadgeforthebadge

1-classname

Generate one digit classname and beyond.

Why

Instead of using traditional css classname hashing which created unnecessary long className, using one digit classname strategy reduce className to only 1 byte.

hashingexamplebyte / class
traditional hash[path][name]__[local]--[hash:base64:5]cssmain__anyLocal--YWtkdat least 8 byte
one digit[a-Z]a1

Let's say if average tranditional hash has an average length of 16 and there's about 300 classes and id is used:

// Traditional Hash
16 * 300 // 4,800 byte used

// one digit hash
( 52 * 1 ) / ( (300 - 52) * 2) // 548 byte used

// For further explaination, please visit 'one digit hashing' section below.

By using 1-classname, we reduce byte used by classname alone by 8.75x

Happy Fox

Note

Although traditional css classname ensure that className will never be duplicated, using 'one classname' (this module) you have to make sure that className will never be duplicated by yourself. You might wanted to use traditional hash then use one className to shorten it as the following:

import hash from '1-clasname'

hash(`${getPathAndNameAndClassNameSomehow()}`) // cssmain__anyLocal--YWtkd => a

Now we 100% unique one digit className and decrease bundle size.

One digit hashing

One digit is strategy to reduce long hash className to 1 digit only. If all one digit is used, it will use 2 digits and so on. Note: Although, theotically we can use one digit for all className (ex: emoji, ASCII character), we want to follow w3 standard for className. Which means it not really always one digit but always valid w3 standard one digit.

This will helps reduce long className into short one thus reduce a lot of bundle size.

The sequence can be describe as the following:

rangedigitpossible classname
1-521a-Z
53-27562aa-ZZ
2757-2433633aaa-ZZZ
and so onnn([a-Z])

or illustration as example as the following:

index01232526275152537879103104105275527562757143362
characterabcdzABZaaabaAaBaZbabbZZaaaaabZZZ

As the range goes on, it can be describe by using fibonacci sequence as the following:

const generateLimit = (digits: number) => {
    if (digits === 0) return 0

    return 52 ** digits + generateLimit(digits - 1)
}

const limit = generateLimit(digits) - (digits - 1)

When the className is hash, it'll be stored as key in object as the following:

{
    [key-1]: "a",
    [key-2]: "b"
    [key-3]: "c"
}

Which means when the class is called after the second time, it will not generate new className but rather using old one.

Getting started

Simply install with yarn or npm.

yarn add 1-classname

// or with npm
npm install 1-classname

One classname has built-in TypeScript supports which means no @types/1-classname is need.

Usage

This library is designed to be used with localIdentName of css-loader.

The following code demonstrate how to reduce className of .module.sass file.

cssLoaderOptions: {
    getLocalIdent: (
        loaderContext,
        localIdentName,
        localName,
        options
    ) => {
        const filePath = loaderContext.resourcePath
        const fileBaseName = basename(filePath)

        if (/\.module\.sass$/.test(fileBaseName)) {
            const modulePathParts = filePath.split('/')

            const moduleName =
                modulePathParts[modulePathParts.length - 2]

            return `_${oneClassName(moduleName + localName)}`
        }

        return localName
    }
}

If you want prefix you can use template literal:

generateLocalIdentSomehow: (string) => `${generatePrefixSomehow()}-${hash(string)}`,

Contribution

All contribution, discussion and PR is welcome.

If you have any questions, feels free to ask at issue

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文