npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

module-classnames-loader

v1.2.2

Published

a css module helper based on css-loader module

Downloads

16

Readme

module-classnames-loader

module-classnames-loader 是一个 webpack loader. 当你需要在 react 项目里使用模块化类名时, 它能在运行时聪明的应用你的模块化类名, 从而减少你的工作量. :hibiscus::hibiscus:

开始使用

你可这样安装:

npm install --save-dev module-classnames-loader

然后在 webpack 里配置好 loader, 假如有如下配置:

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: ['babel-loader', 'module-classnames-loader'],
      },
      // 依然需要 css loader 来处理模块化
      {
        test: /\.module\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          }
        ]
      }
    ],
  },
};

注意, 你应该把 module-classnames-loader 放到处理js文件loader的右侧. 因为它会通过分析你的 jsx 语法来定位类名位置. 所以务必要在 babel-loader 处理完 jsx 语法之前使用.

最终的模块化处理依然是基于 css-loader. 所以务必做好 css-loader 的相关配置.

如果你使用 less/scss , 只需按照原样逻辑配置好相关 loader 即可. :point_right::point_right: less-loader | :point_right::point_right: sass-loader

注意: 要模块化的css文件, 务必要命名成 *.module.(css|less|scss) 的形式
如: 'syle.module.css',
create-react-app 正是使用这种方式来进行模块化css文件, 使用 create-react-app 将可以无缝衔接

假设你的程序有如下文件:

module.js

在使用 module-classnames-loader 之前, 你可能需要使用以下方式来使用模块化类名:

import React from 'resct'
import style from './style.module.css'

function Banner(){
  return (
    // 
    <div className={`${ style.name1 } ${ style.name2 }`}>...</div>
  )
}

而现在, 你只需要这样:

import React from 'resct'
import './style.module.css'

function Banner(){
  return (
    // 
    <div className="name1 name2">...</div>
  )
}

:school_satchel::school_satchel:怎么样, 是不是已经有点心跳加速了. 别急, 再看看以下用例的对比::school_satchel::school_satchel:

注: 为了行文方便, 我将直接使用 jsx 表示使用方式.

假设你用了classnames 库:

before

import style from './style.module.css'
import 'classnames'

<div 
  className={classnames{
    [style.name1]: true,
    [style.name2]: true,

  }}
>...</div>

after

import './style.module.css'
import 'classnames'

<div 
  className={classnames{
    name1: true,
    name2: true,
  }}
>...</div>

事实上, 你可以随意使用表达式而无需担心:

import './style.module.css'

let names = 'n1 n2'

<div 
  className={names + 'n3'}
>...</div>

我们再看一些你关心的问题:

假设你有两个模块化的 css 文件:


// file1.module.css

.name1{
  margin: 0;
}

// file2.module.css
.name1{
  margin: 0;
}
.name2{
  margin: 0;
}

我们先引入 file1.module.css :

import './file1.module.css'

// 假设 file1.module.css 能够得到如下对象
{
  name1: wcz_Nlfc_o3
}

<div className="name1 box">...</div>

// 最终, div 的类名会变成 ======>>>

<div class="wcz_Nlfc_o3 box">...</div>

看到了吧, 'box' 不在模块化的类名里, 它会被原样保留. :scream::scream:

看看我们引入了两个css文件的情况:

import './file1.module.css'
import './file2.module.css'

// 假设 file1.module.css 能够得到如下对象
{
  name1: f1_name1,
  name2: f1_name2,
}
// 假设 file2.module.css 能够得到如下对象
{
  name1: f2_name1,
  name3: f2_name3
}

<div className="name1 name2 name3 box">...</div>

// 最终, div 的类名会变成 ======>>>

<div class="f2_name1 f1_name2 f2_name3 box">...</div>

这里有两个重要的点:

  • 如果位于不同模块化对象的类名, 会分别查找应用
  • 如果出现同名的模块化类名, 后面引入的 'css' 会覆盖前面的, 看看上面的 'name1'

如果不想被覆盖, 而只想使用 file1.module.css 的 'name1' 只需单独处理即可(继承上面代码):

import s1 from './file1.module.css'
import './file2.module.css'

<div class={`${s1.name1} name2 name3 box`}>...</div>

// 此时, div 会变成 =======>>>

<div class="f1_name1 f1_name2 f2_name3 box">...</div>

options

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          'babel-loader',
          {
            loader: 'module-classnames-loader',
            options: {
              sourceMap: false // true 会开启sourceMap
              identifier: 'module', // default: module, 模块化的名字需要为: '*.module.(css|less|scss)'
            }
          }
        ],
      },
      
    ],
  },
};

options todo:

  • sourceMap: boolean, default: false, 是否生成sourceMap
  • identifier: default: 'module', 用于配置需要模块化样式文件名的样板符号, 例如改成: 'mod', 那么你的文件名应为: *.mod.(css|less|scss) , 其他符号依次类推
  • defaultImport: boolean, default: false. 和 identifier互斥.
  • parserOptions: 能够解析的语法, 默认开启以下特性:
    • 'jsx',
    • 'typescript',
    • 'flowComments',
    • 'asyncGenerators',
    • 'bigInt',
    • 'classProperties',
    • 'classPrivateProperties',
    • 'classPrivateMethods',
    • ['decorators',{ decoratorsBeforeExport: true }],
    • 'doExpressions',
    • 'dynamicImport',
    • 'exportDefaultFrom',
    • 'exportNamespaceFrom',
    • 'functionBind',
    • 'functionSent',
    • 'importMeta',
    • 'logicalAssignment',
    • 'nullishCoalescingOperator',
    • 'numericSeparator',
    • 'objectRestSpread',
    • 'optionalCatchBinding',
    • 'optionalChaining',
    • 'throwExpressions',

License

MIT licensed.