roylee0704 / react-flexbox-grid

A set of React components implementing flexboxgrid with the power of CSS Modules.
http://roylee0704.github.io/react-flexbox-grid/
2.93k stars 206 forks source link

Having an issue with flexboxgrid classes getting mangled. #131

Closed mastrauckas closed 7 years ago

mastrauckas commented 7 years ago

I am having an issue where using the below webpack with the below package.json is causing all flexboxgrid classes to get mangled.

Can anyone tell me what is causing this?

Here is how some of the classes are getting generated when viewing the html:

flexboxgrid__container-fluid___2lUES
flexboxgrid__row___1y_mg flexboxgrid__center-sm___39HWq

package.json

"devDependencies": {
    "babel-cli": "^6.23.0",
    "babel-core": "^6.13.2",
    "babel-eslint": "^7.1.1",
    "babel-loader": "^7.0.0",
    "babel-plugin-react-html-attrs": "^2.0.0",
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-es2016": "^6.22.0",
    "babel-preset-react": "^6.23.0",
    "babel-preset-stage-2": "^6.22.0",
    "cross-env": "^4.0.0",
    "css-loader": "^0.28.4",
    "eslint": "^3.16.0",
    "eslint-loader": "^1.6.3",
    "eslint-plugin-react": "^6.10.0",
    "exports-loader": "^0.6.4",
    "file-loader": "^0.11.1",
    "html-loader": "^0.5.0",
    "html-webpack-plugin": "^2.28.0",
    "style-loader": "^0.18.2",
    "webpack": "^3.5.3",
    "webpack-dev-server": "^2.6.1"
  },
  "dependencies": {
    "axios": "^0.16.0",
    "core-js": "^2.5.0",
    "flux": "^3.1.2",
    "material-ui": "^0.17.4",
    "prop-types": "^15.5.8",
    "react": "^15.5.4",
    "react-dom": "^15.5.4",
    "react-flexbox-grid": "^1.1.2",
    "react-tap-event-plugin": "^2.0.1",
    "sugar": "^2.0.4"
  }

webpack.config.js

const WebpackDevHelper = require('./webpack/webpackDevHelper');

const environment = process.env.NODE_ENV.toUpperCase();
const webpackHelper = new WebpackDevHelper(environment);

const colors = {
  reset: '\x1b[0m',
  fg: {
    red: '\x1b[31m'
  }
};

console.log(colors.fg.red, `Building in ${environment} mode.`, colors.reset);

module.exports = {

  devtool: webpackHelper.devTools,
  entry: webpackHelper.entries,
  output: webpackHelper.output,

  resolve: {
    extensions: ['.js', '.ts']
  },

  stats: webpackHelper.stats,

  module: {
    rules: webpackHelper.rules
  },

  plugins: webpackHelper.plugins,
  devServer: webpackHelper.webpackDevServer,
  node: webpackHelper.node,

};

WebpackHelper.js

const packages = require('../package.json');
const path = require('path');

module.exports = class WebpackHelper {

  constructor(environment) {
    this.environment = environment;
  }

  get entryPoints() {
    return ['manifest', 'polyfills', 'sw-register', 'styles', 'vendor', 'app'];
  }

  get entries() {

    const vendorPackages = Object.keys(packages.dependencies)
                            .filter(d => d !== 'core-js');

    return {
      'polyfills': './src/js/polyfills.js',
      'app': './src/js/main.js',
      'styles': [
        'flexboxgrid',
        './src/css/styles.css'
      ],
      'vendor': vendorPackages,
    };
  }

  get output() {
    return {
      path: path.join(process.cwd(), 'build'),
      filename: this.isDevelopment ? 'js/[name].bundle.js' : 'js/[name].bundle.[chunkhash:8].min.js',
      chunkFilename: this.isDevelopment ? './build/js/[id].bundle.chunk.js' : './build/js/[id].bundle.chunk.[chunkhash:8].min.js'
    };
  }

  get devTools() {
    return this.isDevelopment ? 'inline-source-map' : 'source-map';
  }

  get resolve() {
    return {
      extensions: ['.js']
    };
  }

  get isProduction() {
    return this.environment === 'PRODUCTION';
  }

  get isDevelopment() {
    return this.environment === 'DEVELOPMENT';
  }

  get rules() {
    return [
      {
        test: /\.js?$/,
        enforce: 'pre',
        exclude: /node_modules/,
        loader: 'eslint-loader'
      },
      {
        test: /.js?$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.html$/,
        exclude: /node_modules/,
        use: 'html-loader'
      },
      {
        test: /\.(png|jpe?g|gif|svg|woff|woff2|otf|ttf|eot|ico)$/,
        exclude: /node_modules/,
        use: 'file-loader?name=assets/[name].[hash].[ext]'
      },
      {
        test: /\.css?$/,
        exclude: /node_modules/,
        use: [
          // 'style-loader',
          // 'css-loader'
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              modules: false,
              localIdentName: '[local]'
            }
          }
        ]
      },
      {
        test: /flexboxgrid.css?$/,
        use: [
          // 'style-loader',
          // 'css-loader'
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              modules: false,
              localIdentName: '[local]'
            }
          }
        ],
        include: /flexboxgrid/
      },
    ];
  }

  get node() {
    return {
      'fs': 'empty',
      'global': true,
      'crypto': 'empty',
      'tls': 'empty',
      'net': 'empty',
      'process': true,
      'module': false,
      'clearImmediate': false,
      'setImmediate': false
    };
  }

  get webpackDevServer() {
    return {
      port: 4200,
      historyApiFallback: true,
      stats: this.stats,
    };
  }

  get stats() {
    return {
      colors: true,
      hash: false,
      version: true,
      timings: true,
      assets: true,
      chunks: false,
      modules: false,
      reasons: true,
      children: true,
      source: false,
      errors: true,
      errorDetails: true,
      warnings: true,
      publicPath: true,
      cached: false,
      cachedAssets: false,
      chunkModules: false,
      chunkOrigins: false,
      depth: false,
      entrypoints: false,
      performance: false,
      providedExports: false,
      usedExports: false,
      maxModules: 0,
    };
  }

};

webpackDevHelper.js

const { CommonsChunkPlugin, OccurrenceOrderPlugin, UglifyJsPlugin } = require('webpack').optimize;
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {
  NamedModulesPlugin,
  NoEmitOnErrorsPlugin,
} = require('webpack');
const path = require('path');
const fs = require('fs');
const WebpackHelper = require('./WebpackHelper');

const nodeModules = path.join(process.cwd(), 'node_modules');
const realNodeModules = fs.realpathSync(nodeModules);
const genDirNodeModules = path.join(process.cwd(), 'src', '$$_gendir', 'node_modules');

module.exports = class WebpackDevHelper extends WebpackHelper {

  constructor(environment) {
    super(environment);
  }

  get plugins() {
    const plugins = [
      new NoEmitOnErrorsPlugin(),
      new HtmlWebpackPlugin({
        template: 'src/html/index.html',
        chunksSortMode: (left, right) => {
          let leftIndex = this.entryPoints.indexOf(left.names[0]);
          let rightIndex = this.entryPoints.indexOf(right.names[0]);
          if (leftIndex > rightIndex) {
            return 1;
          }
          else if (leftIndex < rightIndex) {
            return -1;
          }
          else {
            return 0;
          }
        },
        fileName: './index.html',
        hash: false,
        compile: false,
        favicon: false,
        cache: false,
        showErrors: true,
        chunks: 'all',
        excludeChunks: [],

        minify: {
          removeComments: this.isProduction,
          collapseWhitespace: this.isProduction
        }
      }),

      new CommonsChunkPlugin({
        'name': [
          'manifest'
        ],
        'minChunks': null
      }),

      new CommonsChunkPlugin({
        'name': [
          'vendor',
        ],
        'minChunks': (module) => {

          return module.resource
                      && (module.resource.startsWith(nodeModules)
                          || module.resource.startsWith(genDirNodeModules)
                          || module.resource.startsWith(realNodeModules));
        },
        'chunks': [
          'app'
        ]
      })

    ];

    if (this.isProduction) {

      plugins.push(new OccurrenceOrderPlugin());
      plugins.push(new NamedModulesPlugin());
      plugins.push(new UglifyJsPlugin({
        sourceMap: true,
        minimize: true,
        beautify: false,
        mangle: { screw_ie8: true, keep_fnames: true },
        dead_code: true,
        unused: true,
        deadCode: true,
        comments: false,
        compress: {
          screw_ie8: true,
          keep_fnames: true,
          drop_debugger: false,
          dead_code: false,
          unused: false,
          warnings: false
        }
      }));
    }

    return plugins;
  }

};
mastrauckas commented 7 years ago

Put this on stackoverflow where it might be more appropriate.