Webpack - arthur791004/notes GitHub Wiki

Flow

file ---> loaders ---> compile/process

  • Example
    • *.js ---> babel-loader ---> babel-core (compile)
{
  entry: options.entry,
  output: Object.assign({ // Compile into js/build.js
    path: path.resolve(process.cwd(), 'build'),
    publicPath: '/',
  }, options.output), // Merge with env dependent settings
  module: {
    rules: [{
      test: /\.js$/, // Transform all .js files required somewhere with Babel
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: options.babelQuery,
      },
    }, {
      // Do not transform vendor's CSS with CSS-modules
      // The point is that they remain in global scope.
      // Since we require these CSS files in our JS or CSS files,
      // they will be a part of our compilation either way.
      // So, no need for ExtractTextPlugin here.
      test: /\.css$/,
      include: /node_modules/,
      use: ['style-loader', 'css-loader'],
    }, {
      test: /\.(eot|ttf|woff|woff2|swf)$/,
      use: 'file-loader',
    }, {
      test: /\.(svg|jpg|png|gif)$/,
      loader: 'url-loader',
      options: {
        limit: 1024,
      },
    }, {
      test: /\.(svg|jpg|png|gif)$/,
      enforce: 'pre',
      loader: 'image-webpack-loader',
      exclude: [],
      options: {
        gifsicle: {
          interlaced: false,
        },
        optipng: {
          optimizationLevel: 7,
        },
        pngquant: {
          quality: '90-100',
          speed: 4,
        },
        mozjpeg: {
          progressive: true,
          quality: 65,
        },
      },
    }, {
      test: /\.html$/,
      use: 'html-loader',
    }, {
      test: /\.json$/,
      use: 'json-loader',
    }, {
      test: /\.(mp4|webm)$/,
      loader: 'url-loader',
      options: {
        limit: 10000,
      },
    }],
  },
  plugins: options.plugins.concat([
    new webpack.ProvidePlugin({
      // make fetch available
      fetch: 'exports-loader?self.fetch!whatwg-fetch',
    }),

    // Always expose NODE_ENV to webpack, in order to use `process.env.NODE_ENV`
    // inside your code for any environment checks; UglifyJS will automatically
    // drop any unreachable code.
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'stage'
          ? JSON.stringify('production')
          : JSON.stringify(process.env.NODE_ENV),
        // React only optimize code with env set to `production`,
        // since we want stage environment have the same behavior, we explicitly add a new variable here.
        REAL_NODE_ENV: JSON.stringify(process.env.NODE_ENV),
      },
    }),

    new webpack.NamedModulesPlugin(),
  ]),
  resolve: {
    mainFields: [
      'browser',
      'jsnext:main',
      'main',
    ],
  },
  devtool: options.devtool,
  target: 'web', // Make web variables accessible to webpack, e.g. window
  performance: options.performance || {},
}
  • HotModuleReplacementPlugin
  • NoEmitOnErrorsPlugin
  • NamedModulesPlugin
  • DefinePlugin
  • UglifyJsPlugin
  1. Enabling Hot Module Replacement (HMR)
    • webpack-dev-server (options1)
      • [method 1] add --hot to webpack-dev-server cli command
      • [method 2] add HotModuleReplacementPlugin plugin and set hot: true in devServer of webpack.config.js
    • webpack-dev-middleware (options2)
      • webpack-hot-middleware
  2. Using HMR to replace the root component
    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './containers/App';
    
    const render = () => {
      ReactDOM.render(
        <div>a UI</div>,
        document.getElementById('app')
      );
    };
    
    render();
    
    +if (module.hot) {
    +  module.hot.accept('./containers/App', () => {
    +    render();
    +  });
    +}
  3. Adding React Hot Loader to preserve component state
    • install react-hot-loader
    $ yarn add react-hot-loader@next --dev
    
    • add to .bablerc
    {
    +  "plugins": ["react-hot-loader/babel"]
    }
    • add react-hot-loader/patch to the entry section of your webpack.config.js
    entry: [
    +  'react-hot-loader/patch', // RHL patch
      path.join(process.cwd(), 'app/app.js'),
    ]

Reference

⚠️ **GitHub.com Fallback** ⚠️