账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    为什么我在react项目中设置代码分割,懒加载,但是没有给我产生异步的chunks文件?
    27
    0

    问题描述

    我在自己react demo里面按照官方提供的懒加载方法实现懒加载,但是webpack打包之后,为什么没有异步的chunk文件产生了

    问题出现的平台版本及自己尝试过哪些方法

    查过很多文章都没找到合适的解决方法

    相关代码

    const path = require('path');
    const webpack = require('webpack');
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    // const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'); webpack4.x不适合用了,用mini-css-extract-plugin代替
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
    const Autoprefixer = require('autoprefixer');
    const {
      BundleAnalyzerPlugin
    } = require('webpack-bundle-analyzer');
    
    module.exports = env => {
      // 规则配置
      const rules = [
        {
          test: /\.(js|jsx)$/,
          loader: 'babel-loader',
          exclude: /node_modules/
        },
        {
          test: /\.(jpg|jpeg|png|gif|svg)$/,
          use: [
            {
              loader: 'url-loader',
              options: {
                limit: 100000
              }
            }
          ]
        },
        {
          test: /\.css$/,
          use: [
            env.NODE_ENV === 'development'
              ? 'style-loader'
              : MiniCssExtractPlugin.loader,
            'css-loader'
          ]
        },
        {
          test: /\.less$/,
          use: [
            env.NODE_ENV === 'development'
              ? 'style-loader'
              : MiniCssExtractPlugin.loader,
            'css-loader',
            {
              loader: 'postcss-loader',
              options: {
                ident: 'postcss',
                plugins: [Autoprefixer()]
              }
            },
            'less-loader'
          ]
        }
      ];
    
      const plugins = {
        development: [
          new CleanWebpackPlugin(['dist']),
          new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            injetc: 'body'
          }),
          new webpack.HotModuleReplacementPlugin(),
          new webpack.NamedModulesPlugin()
        ],
        production: [
          new CleanWebpackPlugin(['dist']),
          new MiniCssExtractPlugin({
            filename: '[name].min.css'
          }),
          new OptimizeCssAssetsWebpackPlugin(), // 压缩提取的css文件
          new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            injetc: 'body'
          }),
          new BundleAnalyzerPlugin()
        ],
        test: [new BundleAnalyzerPlugin()]
      };
    
      const webpackConfig = {
        entry: {
          index: './src/index.js'
        },
        devtool: 'nosources-source-map',
        output: {
          filename: '[name].[hash].js',
          chunkFilename: '[name].chunk.js',
          path: path.resolve(__dirname, 'dist')
        },
        module: {
          rules: [...rules]
        },
        // 优化
        optimization: {
          runtimeChunk: {
            name: 'manifest'
          },
          splitChunks: {
            maxAsyncRequests: 10,
            cacheGroups: {
              default: false,
              async: {
                name: 'async',
                chunks: 'async',
                minChunks: 1,
                minSize: 1,
                priority: 20
              },
              common: {
                name: 'common',
                chunks: 'initial',
                minChunks: 1,
                minSize: 1,
                priority: 0
              },
              vander: {
                name: 'base',
                test: /node_modules/,
                chunks: 'initial',
                minChunks: 1,
                priority: 10
              }
            }
          }
        },
    
        // 插件
        plugins: [
          new webpack.DefinePlugin({
            NODE_ENV: JSON.stringify(env.NODE_ENV)
          }),
          ...plugins[env.NODE_ENV]
        ]
      };
    
      // 是否是开发模式
      if (env.NODE_ENV === 'development') {
        webpackConfig.devServer = {
          hot: true,
          hotOnly: true
        };
      }
      console.log(webpackConfig);
      return webpackConfig;
    };
    

    你期待的结果是什么?实际看到的错误信息又是什么?

    我想要的结果是,按照正常的流程,打包出那几个路由对应的chunks文件

    react demo代码

    import React from 'react';
    import { Route, NavLink } from 'react-router-dom';
    import Loadable from 'react-loadable';
    import loadable from '@loadable/component';
    import { Layout, Menu } from 'antd';
    import './index.less';
    
    const { SubMenu } = Menu;
    const { Header, Sider, Content } = Layout;
    
    class Home extends React.Component {
      shouldComponentUpdate() {}
    
      render() {
        return (
          <Layout className="home-component">
            <Header />
            <Layout>
              <Sider theme="dark">
                <Menu className="menu">
                  <Menu.Item>
                    <NavLink to="/home/discover">搜索</NavLink>
                  </Menu.Item>
                  <Menu.Item>
                    <NavLink to="/home/visilize">
                      可视化
                    </NavLink>
                  </Menu.Item>
                  <Menu.Item>
                    <NavLink to="/home/dashboard">
                      仪表盘
                    </NavLink>
                  </Menu.Item>
                  <Menu.Item>
                    <NavLink to="/home/data">数据源</NavLink>
                  </Menu.Item>
                  <Menu.Item>
                    <NavLink to="/home/alarm">警告</NavLink>
                  </Menu.Item>
                  <Menu.Item>
                    <NavLink to="/machine">机器学习</NavLink>
                  </Menu.Item>
                  <SubMenu title={<span>管理</span>}>
                    <Menu.Item>
                      <NavLink to="/authority-manage">
                        权限管理
                      </NavLink>
                    </Menu.Item>
                    <Menu.Item>
                      <NavLink to="/role-manage">
                        角色管理
                      </NavLink>
                    </Menu.Item>
                    <Menu.Item>
                      <NavLink to="/leaver">全责分离</NavLink>
                    </Menu.Item>
                  </SubMenu>
                </Menu>
              </Sider>
              <Content>
                <Route
                  path="/home/discover"
                  component={loadable(() =>
                    import('../Discover')
                  )}
                />
                <Route
                  path="/home/visilize"
                  component={loadable(() =>
                    import('../Visilize')
                  )}
                />
                <Route
                  path="/home/dashboard"
                  component={loadable(() =>
                    import('../Dashboard')
                  )}
                />
                <Route
                  path="/home/data"
                  component={loadable(() => import('../Data'))}
                />
                <Route
                  path="/home/alarm"
                  component={loadable(() => import('../Alarm'))}
                />
              </Content>
            </Layout>
          </Layout>
        );
      }
    }
    
    export default Home;
    
    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 詠逺消夨° 普通会员 1楼

      在React项目中,代码分割、懒加载等特性可能会导致没有生成异步的chunks文件。这是因为React使用虚拟DOM(Virtual DOM)来处理组件的渲染。虚拟DOM的创建和更新是异步的,所以React并没有等待所有的更改完成后再更新UI。相反,它会创建一个新的DOM,然后将旧的DOM中的内容替换为新的内容。

      在你的项目中,如果你使用了React的虚拟DOM和懒加载特性,那么在你使用shouldComponentUpdate()方法时,React会创建新的DOM来渲染组件。这会导致你的代码分割和懒加载特性无法正常工作。

      解决这个问题的一种方法是使用React.memo()shouldComponentUpdate()来限制组件的渲染。React.memo()是一个装饰器,它会检查组件的状态是否在短时间内变化。如果状态没有变化,那么它会直接返回组件的实例,而不是创建一个新的DOM。

      ```jsx import React from 'react';

      function MyComponent() { const MyComponentRef = React.createRef();

      return (

      {/ Render your component /} {MyComponentRef.current ? (
      {/ Render your component /}
      ) : (
      Loading...
      )}
      ); }

      export default MyComponent; ```

      在这个例子中,我们创建了一个新的MyComponentRef,然后在组件渲染时检查MyComponentRef.current是否为null。如果是,那么就直接返回组件的实例。如果不是,那么就创建一个新的DOM,并将旧的DOM中的内容替换为新的内容。这样,即使MyComponent的状态有变化,React也不会创建新的DOM,从而避免了异步的chunks文件生成。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部