最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Detect use of non-existent classNames in CSS ModulesReact - Stack Overflow

programmeradmin2浏览0评论

In my react project if I use some non-existent className from css modules file,

 // mycss.modules.scss

.thing { color: red }

// index.jsx

import styles from mycss.modules.scss

<div className={styles.otherThing}>Some div</div>

// Browser would return:

<div>Some div</div>

it quietly fails without letting me know that this class does not exist. How I can check if this class name exist or not and throw an error. Would be great to receive an error during build time, when saving file.

In my react project if I use some non-existent className from css modules file,

 // mycss.modules.scss

.thing { color: red }

// index.jsx

import styles from mycss.modules.scss

<div className={styles.otherThing}>Some div</div>

// Browser would return:

<div>Some div</div>

it quietly fails without letting me know that this class does not exist. How I can check if this class name exist or not and throw an error. Would be great to receive an error during build time, when saving file.

Share Improve this question edited Apr 5, 2020 at 9:06 Mechanic 5,4004 gold badges19 silver badges42 bronze badges asked Apr 2, 2020 at 22:25 Edvards NiedreEdvards Niedre 7101 gold badge8 silver badges21 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 7 +50

If you are open to typescript solution, I found one TS plugin for you.

typescript-plugin-css-modules

It can populate the styles object with type information for available keys.

You don't have to switch whole project to typescript, you can add // @ts-check directive at the top of this file to enable the TS engine design time check.

Unless you want to put forth a pull request to add something like a strict mode option to the webpack loader itself, i dont think theres much you can do since its just a base object. An easy alternative is to just do styles.styleName.toString(), this way if styleName is undefined, it will throw an error.

NOTE: This solution does not require you to change any of your code, just add the loader and it should work out of the box. Please note the caveat about production builds at the end, or check the source for full instructions at Github.

I have created a Webpack loader that works with CSS/LESS/Other CSS module loaders.

The full source and readme can be found on GitHub.

For those who just want to add the loader to their project, it can be used like this:

Add this webpack loader source file somewhere, e.g /webpack/loaders/css-module-proxy.js

/**
 * A CSS/LESS/Style module loader that prepends a proxy in non-production builds.
 *
 * The proxy checks if the loaded style module actually contains the style we are trying to fetch.
 * If it doesn't exist (its accessor returns undefined), we crash on debug (non-production) builds!
 *
 * Inspired by https://github./royriojas/css-local-loader
 */
module.exports = function cssLocalLoader(source, map) {
    this.cacheable();
    if (process.env.NODE_ENV !== "production") {
        // noMatch:
        // Makes sure that any access prefixed with underscore are filtered out
        // otherwise it will crash at runtime when Webpack is probing the locals export.
        // toJsonMatch:
        // Makes sure that toJSON access on the locals object gets proxied to the correct
        // toJSON function.
        const requireWrapper = `
            // If the access matches this regexp, skip it
            const oldLocals = exports.locals;
            const noMatch = /^[_]+/;
            const toJsonMatch = /^toJSON$/;
            const proxy = new Proxy(oldLocals, {
              get: function(target, name) {
                if (noMatch.test(name)) {
                    return undefined;
                }
                if (toJsonMatch.test(name)) {
                    return oldLocals.toJSON;
                }
                const clz = target[name];
                if (clz === undefined) {
                    throw new Error("Error: LESS / CSS class named \\"" + name + "\\" does not exist");
                }
                return clz;
              }
            });
            exports.locals = proxy;
        `;
        const newSource = `${source}\n\n${requireWrapper}`;
        this.callback(null, newSource, map);
    } else {
        this.callback(null, source, map);
    }
};

And then use it from your webpack config, example below is for LESS:

{
    test: /\.module\.less$/,
    use: [
        { loader: path.resolve("webpack/loaders/css-module-proxy.js") },
        {
            loader: "css-loader",
            options: {
                modules: true,
                importLoaders: 1,
                localIdentName: "[name]__[local]__[hash:base64:5]",
            },
        },
        { loader: "less-loader" },
    ],
},

Don't forget to build your release code with NODE_ENV=production or it may crash when a user visits your site...

Actually it is possible in javascript code. But I think that className exist check is not good idea.

document.styleSheets[].rules[].selectorText

original link How can you determine if a css class exists with Javascript?

add this function to the top:

// index.jsx
import styles from mycss.modules.scss

function strictStyles (clsName){
  if(styles[clsName]){
    return styles[clsName]
  }else{
    throw "CSS class doesn't exist";
  }
}

...
<div className={strictStyles(otherThing)}>Some div</div>
...
发布评论

评论列表(0)

  1. 暂无评论