[Webpack] [Реагировать] На SSR с разделением кода, как я могу получить список кусков, необходимых для страницы? - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть приложение React с прекрасно работающим SSR и разбивкой кода Webpack.

Мой webpack.config.js выглядит так:

const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ServerMiniCssExtractPlugin = require("./server/utils/serverMiniCssExtractPlugin");

module.exports = [{
  name: 'react-app',
  mode: 'development',
  devtool: 'eval',
  cache: true,
  entry: {
    main: [
      'babel-polyfill',
      'webpack-hot-middleware/client',
      './react/index.tsx',
    ],
  },
  output: {
    path: `${__dirname}/dist/__build__`,
    filename: '[name].js',
    chunkFilename: '[name].js',
    publicPath: '/__build__/',
  },
  module: {
    rules: [{
      test: /\.(ts|js)x?$/,
      loader: 'babel-loader',
      exclude: [/node_modules/],
    }, {
      test: /\.scss$/,
      oneOf: [{
        resourceQuery: /^\?raw$/,
        use: [MiniCssExtractPlugin.loader, {
          loader: 'css-loader',
          options: {
            modules: true,
            sourceMap: true,
            camelCase: false,
            localIdentName: '[local]',
          },
        }, 'sass-loader', 'postcss-loader'],
      }, {
        use: [MiniCssExtractPlugin.loader, {
          loader: 'css-loader',
          options: {
            modules: true,
            sourceMap: true,
            camelCase: true,
            localIdentName: '[path]___[name]__[local]___[hash:base64:5]',
          },
        }, 'sass-loader', 'postcss-loader'],
      }]
    }],
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js'],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        CLIENT: JSON.stringify(true),
      },
    }),
    new webpack.IgnorePlugin(/^vertx$/),
    new MiniCssExtractPlugin({
      filename: "style.css",
      chunkFilename: "style.chunk.[id].css"
    }),
  ],
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /node_modules/,
          name: 'vendor',
          enforce: true
        },
      },
    },
  },
}, {
  name: 'server-side rendering',
  mode: 'development',
  devtool: 'eval',
  cache: true,
  entry: [
    './react/ssr.tsx',
  ],
  target: 'node',
  output: {
    path: `${__dirname}/dist/__server__/`,
    filename: 'ssr.js',
    publicPath: '/__server__/',
    libraryTarget: 'commonjs2',
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js'],
  },
  module: {
    rules: [{
      test: /\.(ts|js)x?$/,
      exclude: [/node_modules/, /.+\.config.js/],
      loader: 'babel-loader',
    }, {
      test: /\.scss$/,
      oneOf: [{
        resourceQuery: /^\?raw$/,
        use: [ServerMiniCssExtractPlugin.loader, {
          loader: 'css-loader',
          options: {
            modules: true,
            sourceMap: true,
            camelCase: false,
            localIdentName: '[local]',
          },
        }, 'sass-loader', 'postcss-loader'],
      }, {
        use: [ServerMiniCssExtractPlugin.loader, {
          loader: 'css-loader',
          options: {
            modules: true,
            sourceMap: true,
            camelCase: true,
            localIdentName: '[path]___[name]__[local]___[hash:base64:5]',
          },
        }, 'sass-loader', 'postcss-loader'],
      }]
    }],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        SERVER: JSON.stringify(true),
      },
    }),
    new webpack.IgnorePlugin(/^vertx$/),
    new ServerMiniCssExtractPlugin({
      filename: "style.css",
      chunkFilename: "style.chunk.[id].css"
    }),
  ],
}];

... и генерируетчанки для js и css, которые с помощью приложения загружаются корректно при перемещении с разных страниц, все сопоставлены с реакции-маршрутизатором.

Проблема в том, что при перезагрузке одной из страниц загружаются необходимые чанки cssкогда-то визуализированный и не связанный напрямую на странице из SSR, на секунду у меня есть FOUC .

, так как я хотел бы использовать React-Helmet для введения в заголовок страницы необходимого cssчанки, когда я SSR приложение, как я могу получить в коде список имен файлов чанков, которые необходимы для страницы, которую я перезагружаю?

Допустим, что странице нужен стиль: 0.js 2.js.chunk.0.css style.chunk.2.css

Как получить список этих файлов, чтобы я мог динамически генерировать ссылки в заголовке страницы?

Спасибо.

1 Ответ

0 голосов
/ 11 августа 2019

Используйте webpack-manifest-plugin , чтобы сгенерировать файл manifest.json, который будет содержать список всех ваших кусков.

В вашем webpack.config.js:

var ManifestPlugin = require('webpack-manifest-plugin');

module.exports = {
    // ...
    plugins: [
      new ManifestPlugin()
    ]
};

Это создаст файл manifest.json в вашем корневом выходном каталоге с сопоставлением всех имен исходных файлов с соответствующим выходным файлом, например:

{
  "mods/alpha.js": "mods/alpha.1234567890.js",
  "mods/omega.js": "mods/omega.0987654321.js"
}
...