【问题标题】:Obfuscate React classNames in existing codebase在现有代码库中混淆 React 类名
【发布时间】:2020-07-19 14:56:42
【问题描述】:

大家好

我正在开发一个具有现有代码库(100 多个组件)的大型 React 应用程序。目前,我们使用的是传统的样式方法,例如:

JSX:
<div className="div" />

SCSS: 
.div {
 /* ... */
}

我们将 webpack 与这些加载器一起使用:

/* ... */
use: [
       {
         loader: MiniCssExtractPlugin.loader,
         options: {
           publicPath: '../'
         }
       },
       'css-loader',
       'postcss-loader',
       {
         loader: 'sass-loader',
         options: { implementation: sass }
       }
     ]
/* ... */

有什么方法可以在不重写整个内容的情况下从 JSX 和 SCSS 中混淆这些类名?是否也可以只重写一些要混淆的组件还是我们必须全部重写?

谢谢。

【问题讨论】:

    标签: reactjs sass jsx


    【解决方案1】:

    css-loader 有一个modules 选项,当设置为true 时会混淆类名。不幸的是,这会混淆所有类名,并要求您将所有 &lt;div className="div" /&gt; 的用法更改为:

    import styles from <stylesheet>;
    <div className={styles.div} />
    

    编辑: 我能想到的避免一次更改所有用法的唯一方法是使用两种模式在 webpack 中拆分 css 配置,例如:

    {
        test: /.*dirA\/.*\.css/,
        use: [{ loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true } }, ...]
    },
    {
        test: /.*dirB\/.*\.css/,
        use: [{ loader: 'style-loader' }, { loader: 'css-loader' }, ...]
    }
    

    【讨论】:

    • 嗨,我已经尝试过 modules 选项,它会导致整个 css 中断(正常行为)。你知道我可以为这个特定用例使用的任何其他加载器吗?
    • @CHRAIBIMohammedYassine 我在我的答案中添加了一个关于拆分要应用模块的文件的编辑,这有帮助吗?
    • @CHRAIBIMohammedYassine 除此之外,对不起,我不知道任何其他加载程序可以解决这个用例
    • 我尝试使用您提供的语法分隔文件,包括:[ path.resolve(__dirname, "app/path/to/scss") ] 语法,但问题仍然存在。我无法达到预期的目标。
    • 当您尝试这两种方法时究竟会发生什么?至于具体的错误是什么
    【解决方案2】:

    Create-react-app 弹出的解决方案

    示例类名:a_a、a_b、a_c .... 等

    1. 弹出应用程序
    2. 安装incstr
    3. config 文件夹中创建getScopedName.js
    const incstr = require('incstr');
    const createUniqueIdGenerator = () => {
      const uniqIds = {};
      const generateNextId = incstr.idGenerator({
        alphabet: 'abcefghijklmnopqrstuvwxyzABCEFGHJKLMNOPQRSTUVWXYZ',
      });
      return (name) => {
        if (!uniqIds[name]) {
          uniqIds[name] = generateNextId();
        }
        return uniqIds[name];
      };
    };
    const localNameIdGenerator = createUniqueIdGenerator();
    const componentNameIdGenerator = createUniqueIdGenerator();
    module.exports = (localName, resourcePath) => {
      const componentName = resourcePath
        .split('/')
        .slice(-2, -1)[0];
      const localId = localNameIdGenerator(localName);
      const componentId = componentNameIdGenerator(componentName);
      return `${componentId}_${localId}`;
    };
    

    现在...

    1. 打开webpack.config.js并添加:
    const getScopedName = require('./getScopedName')
    
    1. 找到 ~445-460 行并替换为:
    {
      test: cssModuleRegex,
      use: getStyleLoaders({
        importLoaders: 1,
        sourceMap: isEnvProduction && shouldUseSourceMap,
        modules: {
          ...(isEnvDevelopment ? {
            localIdentName: '[path]_[name]_[local]',
          } : {
           getLocalIdent: (context, localIdentName, localName) => (
             getScopedName(localName, context.resourcePath)
           ),
          })
         },
      }),
    }
    

    就是这样。 :)

    【讨论】:

      猜你喜欢
      • 2021-01-23
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      相关资源
      最近更新 更多