amireh / happypack

Happiness in the form of faster webpack build times.
MIT License
4.24k stars 124 forks source link

It works in CSS, but it doesn't work in Babel #249

Open liuzhiyang0113 opened 5 years ago

liuzhiyang0113 commented 5 years ago

It works in CSS, but it doesn't work in Babel。 Is there anything I haven't noticed? webpack config:

import domainConfigs from './domain.config';

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils-for-webpack4/InterpolateHtmlPlugin');
const ModuleScopePlugin = require('react-dev-utils-for-webpack4/ModuleScopePlugin');
const getCSSModuleLocalIdent = require('react-dev-utils-for-webpack4/getCSSModuleLocalIdent');
const paths = require('./paths');
const getClientEnvironment = require('./env');
const InsertRemCalc = require('../plugins/webpack.insertRemCalc');
const HappyPack = require('happypack');

HappyPack.SERIALIZABLE_OPTIONS = HappyPack.SERIALIZABLE_OPTIONS.concat(['postcss']);

const happyThreadPool = HappyPack.ThreadPool({ size: 3 });

const envName = process.argv[2];

const domainConfig = domainConfigs[envName] || domainConfigs.product || domainConfigs.local;

const publicPath = paths.servedPath;
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
const publicUrl = publicPath.slice(0, -1);
// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);

if (env.stringified['process.env'].NODE_ENV !== '"production"') {
  throw new Error('Production builds must have NODE_ENV=production.');
}

// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;

module.exports = (name, entry) => ({
  mode: 'production',
  // Don't attempt to continue if there are any errors.
  bail: true,
  devtool: shouldUseSourceMap ? 'source-map' : false,
  entry: [require.resolve('./polyfills'), entry],
  output: {
    // The build folder.
    path: paths.appBuild,
    filename: `${name}/static/js/[name].[chunkhash:8].js`,
    chunkFilename: `${name}/static/js/[name].[chunkhash:8].chunk.js`,
    publicPath: '/',
    devtoolModuleFilenameTemplate: info => path
      .relative(paths.appSrc, info.absoluteResourcePath)
      .replace(/\\/g, '/')
  },
  optimization: {
    // sideEffects: false,
    // providedExports: false,
    minimizer: [
    ],
    splitChunks: {
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          minSize: 30000,
          minChunks: 1,
          chunks: 'initial',
          priority: 1
        },
        commons: {
          test: /[\\/]src[\\/]common[\\/]/,
          name: 'commons',
          minSize: 30000,
          minChunks: 3,
          chunks: 'initial',
          priority: -1,
          reuseExistingChunk: true 
        }
      }
    },
    runtimeChunk: true
  },
  resolve: {
    modules: ['node_modules', 'src'].concat(
      process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
    ),
    extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
    alias: {
      common: path.resolve(__dirname, '../', 'src/common/'),
      'react-native': 'react-native-web'
    },
    mainFields: ['browser', 'main'],
    plugins: [
      new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson])
    ]
  },
  module: {
    strictExportPresence: true,
    rules: [
      { parser: { requireEnsure: false } },
      {
        oneOf: [
          {
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            exclude: [/[/\\\\]node_modules[/\\\\]/],
            loader: require.resolve('url-loader'),
            options: {
              limit: 10000,
              name: `${name}/static/media/[name].[hash:8].[ext]`
            }
          },
          {
            test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
            exclude: [/[/\\\\]node_modules[/\\\\]/],
            loader: require.resolve('file-loader'),
            options: {
              name: '[name].[ext]',
              outputPath: `${name}/fonts/`
            }

          },
          {
            test: /\.(js|jsx|mjs)$/,
            include: paths.srcPaths,
            exclude: [/[/\\\\]node_modules[/\\\\]|\.min\.js$/],
            use: [
              'happypack/loader?id=myJs'
            ]
          },
          {
            test: /\.js$/,
            exclude: /@babel(?:\/|\\{1,2})runtime/,
            use: [
              require.resolve('thread-loader'),
              {
                loader: require.resolve('babel-loader'),
                options: {
                  babelrc: false,
                  compact: false,
                  presets: [require.resolve('babel-preset-react-app')],
                  plugins: [
                    [require.resolve('babel-plugin-transform-class-properties')]
                  ],
                  cacheDirectory: true,
                  highlightCode: true,
                  sourceMaps: false
                }
              }
            ]
          },
          {
            test: cssRegex,
            exclude: /\.module\.css$|[/\\\\]node_modules[/\\\\]/,
            loader: [
              MiniCssExtractPlugin.loader,
              'happypack/loader?id=css'
            ]
          },
          {
            test: cssModuleRegex,
            exclude: [/[/\\\\]node_modules[/\\\\]/],
            loader: [
              MiniCssExtractPlugin.loader,
              'happypack/loader?id=cssModule'
            ]
          },
          {
            test: lessRegex,
            exclude: /\.module\.less$|[/\\\\]node_modules[/\\\\]/,
            loader: [
              MiniCssExtractPlugin.loader,
              'happypack/loader?id=less'
            ]
          },
          {
            test: lessModuleRegex,
            exclude: [/[/\\\\]node_modules[/\\\\]/],
            loader: [
              MiniCssExtractPlugin.loader,
              'happypack/loader?id=lessModule'
            ]
          },
          {
            test: /\.(graphql)$/,
            loader: 'graphql-tag/loader'
          },
          {
            loader: require.resolve('file-loader'),
            exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
            options: {
              name: `${name}/static/media/[name].[hash:8].[ext]`
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      inject: true,
      template: paths.appHtml,
      filename: `${name}/index.html`
    }),
    new HappyPack({
      id: 'myJs',
      threadPool: happyThreadPool,
      use: [
        {
          loader: require.resolve('babel-loader'),
          query: {
            babelrc: false,
            configFile: false,
            presets: [require.resolve('babel-preset-react-app')],
            plugins: [
              [
                require.resolve('babel-plugin-named-asset-import'),
                {
                  loaderMap: {
                    svg: {
                      ReactComponent: 'svgr/webpack![path]'
                    }
                  }
                }
              ]
            ],
            cacheDirectory: true,
            // Save disk space when time isn't as important
            cacheCompression: true,
            compact: true
          }
        }
      ]
    }),
    new HappyPack({
      id: 'css',
      threadPool: happyThreadPool,
      // 3) re-add the loaders you replaced above in #1:
      loaders: [
        {
          loader: require.resolve('css-loader'),
          options: {
            importLoaders: 1,
            sourceMap: shouldUseSourceMap
          }
        },
        {
          loader: require.resolve('postcss-loader'),
          options: {
            ident: 'postcss',
            sourceMap: shouldUseSourceMap
          }
        },
        require.resolve('less-loader')
      ]
    }),

    new HappyPack({
      id: 'cssModule',
      threadPool: happyThreadPool,
      loaders: [
        {
          loader: require.resolve('css-loader'),
          options: {
            importLoaders: 1,
            sourceMap: shouldUseSourceMap,
            modules: true,
            getLocalIdent: getCSSModuleLocalIdent
          }
        },
        {
          loader: require.resolve('postcss-loader'),
          options: {
            ident: 'postcss',
            sourceMap: shouldUseSourceMap
          }
        },
        require.resolve('less-loader')
      ]
    }),
    new HappyPack({
      id: 'less',
      threadPool: happyThreadPool,
      loaders: [
        {
          loader: require.resolve('css-loader'),
          options: {
            importLoaders: 2
          }
        },
        {
          loader: require.resolve('postcss-loader'),
          options: {
            ident: 'postcss',
            sourceMap: shouldUseSourceMap
          }
        },
        require.resolve('less-loader')
      ]
    }),
    new HappyPack({
      id: 'lessModule',
      threadPool: happyThreadPool,
      loaders: [
        {
          loader: require.resolve('css-loader'),
          options: {
            importLoaders: 2,
            sourceMap: shouldUseSourceMap,
            modules: true,
            getLocalIdent: getCSSModuleLocalIdent
          }
        },
        {
          loader: require.resolve('postcss-loader'),
          options: {
            ident: 'postcss',
            sourceMap: shouldUseSourceMap
          }
        },
        require.resolve('less-loader')
      ]
    }),
    new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
    new webpack.DefinePlugin({
      ...env.stringified,
      envName: JSON.stringify(envName),
      injectWindow: JSON.stringify(domainConfig)
    }),
    // 计算 REM
    new InsertRemCalc(),
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: `${name}/static/css/[name].[contenthash:8].css`,
      chunkFilename: `${name}/static/css/[name].[contenthash:8].chunk.css`
    }),
    // Moment.js is an extremely popular library that bundles large locale files
    // by default due to how Webpack interprets its code. This is a practical
    // solution that requires the user to opt into importing specific locales.
    // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
    // You can remove this if you don't use Moment.js:
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ],
  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty'
  },
  // Turn off performance processing because we utilize
  // our own hints via the FileSizeReporter
  performance: false
});
zengjinlong commented 5 years ago

请问一下:HappyPack: unable to locate the plugin list 这个报错你解决了吗?

shb190802 commented 4 years ago

同问