路由块将每个块中的外部脚本捆绑在一起

时间:2017-06-20 07:17:50

标签: reactjs webpack webpack-2 code-splitting webpack-externals

在我的网站中,我使用了 externals ,其中包含React,React Dom,Redux等。

现在,当我实现Route Chunking时,生成的每个块都会重新捆绑外部脚本,所以最终我的bundle大小非常大。

如何避免我的个别块不重新捆绑外部脚本并从外部脚本中使用它们。

修改

使用https://chrisbateman.github.io/webpack-visualizer/我可以看到我的所有块都捆绑了常见的库 - 实际上它们应该来自webpack中的externals

编辑2

webpack文件

var path = require('path');
var webpack = require('webpack');

module.exports = {

  entry: ['./src/containers/AppContainer', './src/index'],

  devtool: 'cheap-module-source-map',

  output: {
    path: __dirname + '/dist',
    publicPath: 'public/',
    filename: 'bundle.js',
    chunkFilename: '[name].[id].chunk.[chunkhash].js',
    libraryTarget: 'umd'
  },

  target: 'web',

  externals: {
    antd: 'antd',
    react: 'react',
    'react-dom': 'react-dom',
    'react-router': 'react-router',
    redux: 'redux',
    'react-redux': 'react-redux',
    immutable: 'immutable',
  },

  resolve: {
    modules: [
      path.join(__dirname, '../node_modules')
    ],
    extensions: ['.js', '.jsx', '.json'],
    alias:{
      constants: path.resolve(__dirname, './src/constants'),
      actions: path.resolve(__dirname, './src/actions'),
      styles: path.resolve(__dirname, './src/styles'),
      utils: path.resolve(__dirname, './src/utils')
    }
  },

  resolveLoader: {
    modules: [
      path.join(__dirname, '../node_modules')
    ]
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production')
      }
    }),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      },
      comments: false
    })
  ]

  module: {
    loaders: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          // Ignore local .babelrc files
          babelrc: false,
          presets: [
            ['es2015', { modules: false }],
            'react'
          ],
          plugins: [
            'react-html-attrs',
            'transform-class-properties',
            'transform-decorators-legacy',
            'transform-object-rest-spread',
            [
              'import', {
                libraryName: 'antd'
              }
            ]
          ]
        }
      },
      { test: /\.png$/, loader: 'file-loader' },
      {
        test: /\.s?css$/i,
        use: [
          'style-loader',
          'css-loader'
         ]
      },
      {
        test: /\.s?less$/i,
        exclude:'/node_modules/',
        use: [
          'style-loader',
          'css-loader',
          'less-loader'
        ]
      },
      {
        test: /\.(png|woff|woff2|eot|ttf|svg)$/,
        loader: 'url-loader',
        options: {
          limit: 100000
        }
      },
      {
        test: /\.eot\?iefix$/,
        loader: 'url-loader',
        options: {
          limit: 100000
        }
      },
      {
        enforce: 'pre',
        test: /\.js$/,
        loader: 'eslint-loader',
        exclude: /node_modules/,
        options: {
          configFile: './eslint/.eslintrc',
          failOnWarning: false,
          failOnError: false
        }
      }
    ]
  }
};

路由文件

import React from 'react';
import { Route, IndexRoute } from 'react-router';

export default (
  <Route path='/base/'
    getComponent={ (location, callback) => {
      require.ensure([], function (require) {
        callback(null, require('./containers/AppContainer').default);
      });
    } }>

    <Route path='/route1'
      getComponent={ (location, callback) => {
        require.ensure([], function (require) {
          callback(null,
            require('./containter1')
            .default);
        });
      } }
    />

    <Route path='/route2'
      getComponent={ (location, callback) => {
        require.ensure([], function (require) {
          callback(null,
            require('./container2')
            .default);
        });
      } }
    />

    <Route path='/route3'
      getComponent={ (location, callback) => {
        require.ensure([], function (require) {
          callback(null,
            require('./container3')
            .default);
        });
      } }
    />
  </Route>
);

1 个答案:

答案 0 :(得分:0)

尝试更改您的外部部分:

externals: {
    React: require.resolve('react'),
    'window.React': require.resolve('react'),
    ReactDOM: require.resolve('react-dom'),
    'window.ReactDOM': require.resolve('react-dom')
}

另外,从代码中删除import React from 'react'。只需使用React

修改

抱歉,我编辑了我的答案。刚意识到我的错误。我改变了代码。外部内部的键将是全局变量的名称。通常,将它放在窗口对象中也更安全