конфигурация многостраничного приложения create-реагировать-приложение

Webpack

Резюме

В этой статье в основном рассказывается о том, как использоватьreact-app-rewiredрасширятьcreate-react-appНастроить поддержку многостраничных приложений, включая включениеPWA, служба поддержкиant-designЗагрузка по требованию, совместимая с IE11.

Предварительный просмотр эффекта

  • первый визит

  • страница авторизации

  • Войти успешно, введите снова

инициализация

Создать проект

использоватьcreate-react-appСоздать проект

npx create-react-app .

create-react-app: Facebook.GitHub.IO/create-hot eat...

react-app-rewiredинициализация

  • Установитьreact-app-rewiredа такжеcustomize-cra
yarn add react-app-rewired customize-cra --dev
  • Увеличиватьconfig-overrides.jsдокумент
// config-overrides.js
module.exports = function override(config, env) {
  // do stuff with the webpack config...
  return config;
};
  • Изменить package.jsonscripts
/* package.json */
    "scripts": {
-     "start": "react-scripts start",
+     "start": "react-app-rewired start",
-     "build": "react-scripts build",
+     "build": "react-app-rewired build",
-     "test": "react-scripts test",
+     "test": "react-app-rewired test",
      "eject": "react-scripts eject"
    },

react-app-rewired: GitHub.com/MentionMarney/Горячие…

ant-designнагрузка по требованию

согласно сant-designмодификация документаconfig-overrides.js

/* config-overrides.js */
+ const { override, fixBabelImports, addLessLoader } = require('customize-cra');

- module.exports = function override(config, env) {
-   // do stuff with the webpack config...
-   return config;
- };
+ module.exports = {
+   webpack: override(
+     fixBabelImports('import', {
+       libraryName: 'antd',
+       libraryDirectory: 'es',
+       style: true,
+     }),
+     fixBabelImports('ant-design-pro', {
+       libraryName: 'ant-design-pro',
+       libraryDirectory: 'lib',
+       style: true,
+       camel2DashComponentName: false,
+     }),
+     addLessLoader({
+       javascriptEnabled: true,
+       localIdentName: '[local]--[hash:base64:5]',
+       // modifyVars: { '@primary-color': '#1DA57A' },
+     }),
+   ),
+ };

Справочная документация:Anta.design/docs/реагировать/…

Поддержка нескольких страниц

Изменить файл записи

  1. удалить по умолчаниюsrc/index.jsВходные файлы и связанные с ними зависимости
  2. Создайтеsrc/pages/содержание
  3. Создайтеsrc/pages/index.jsа такжеsrc/pages/login.js
  4. Ссылаться наdvaИнструкция по началу работызаписыватьsrc/pages/index.jsа такжеsrc/pages/login.jsЗависимый код
  5. Многостраничные приложения должны использовать hashHistory, обратите внимание на модификацию

настроитьcreate-react-appнастроить

/* config-overrides.js */
+ const supportMultiPage = (config, env) => {
+   // do stuff with the webpack config...
+   return config;
+ };

  module.exports = {
    webpack: override(
+     supportMultiPage,
      fixBabelImports('import', {
        libraryName: 'antd',
        libraryDirectory: 'es',
        style: true,
      }),
      ...
    ),
  },

Изменить файл записи по умолчанию и корневой каталог

/* config-overrides.js */
  const {
    override,
    fixBabelImports,
    addLessLoader,
  } = require('customize-cra');
+ const paths = require('react-scripts/config/paths');

+ paths.appIndexJs = `${paths.appSrc}/pages/index.js`;
+ paths.servedPath = './';

...

ИсправлятьHtmlWebpackPluginнастроить

/* config-overrides.js */
...
+ const HtmlWebpackPlugin = require('html-webpack-plugin');

...

+ const getEntryConfig = env => {
+   const arr = 'development' === env ? [require.resolve('react-dev-utils/webpackHotDevClient')] : [];
+   return entry => {
+     return [...arr, `${paths.appSrc}/pages/${entry}.js`];
+   };
+ };
+
+ const removePlugin = (plugins, name) => {
+   const list = plugins.filter(it => !(it.constructor && it.constructor.name && name === it.constructor.name));
+   if (list.length === plugins.length) {
+     throw new Error(`Can not found plugin: ${name}.`);
+   }
+   return list;
+ };
+
+ const genHtmlWebpackPlugin = env => {
+   const minify = {
+     removeComments: true,
+     collapseWhitespace: true,
+     removeRedundantAttributes: true,
+     useShortDoctype: true,
+     removeEmptyAttributes: true,
+     removeStyleLinkTypeAttributes: true,
+     keepClosingSlash: true,
+     minifyJS: true,
+     minifyCSS: true,
+     minifyURLs: true,
+   };
+   const config = Object.assign(
+     {},
+     { inject: true, template: paths.appHtml },
+     'development' !== env ? { minify } : undefined,
+   );
+   return entry => {
+     return new HtmlWebpackPlugin({
+       ...config,
+       chunks: ['vendors', `runtime~${entry}.html`, entry],
+       filename: `${entry}.html`,
+     });
+   };
+ };
+
+ const supportMultiPage = (config, env) => {
+   const list = ['index', 'login'];
+   config.entry = {};
+   config.plugins = removePlugin(config.plugins, 'HtmlWebpackPlugin');
+   const getEntry = getEntryConfig(env);
+   const getHtmlWebpackPlugin = genHtmlWebpackPlugin(env);
+   list.forEach(it => {
+     config.entry[it] = getEntry(it);
+     config.plugins.push(getHtmlWebpackPlugin(it));
+   });
+
+   if ('development' === env) {
+     config.output.filename = 'static/js/[name].bundle.js';
+   }
+   return config;
+ };
...

Измените devServer, среда разработки поддерживает несколько страниц

/* config-overrides.js */
  ...
  module.exports = {
    webpack: override(
      ...
    ),
+   devServer: configFunction => {
+     return (proxy, allowedHost) => {
+       const config = configFunction(proxy, allowedHost);
+       config.historyApiFallback.rewrites = [{ from: /^\/login\.html/, to: '/build/login.html' }];
+       return config;
+     };
+   },
  };

Включить ПВА

Исправлятьcreate-react-appПо умолчаниюGenerateSWнастроить

/* config-overrides.js */
  ...
+ const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
  ...
  const supportMultiPage = (config, env) => {
    ...
    if ('development' === env) {
      config.output.filename = 'static/js/[name].bundle.js';
    } else {
+     config.plugins = removePlugin(config.plugins, 'GenerateSW');
+     const workboxWebpackPlugin = new WorkboxWebpackPlugin.GenerateSW({
+       clientsClaim: true,
+       exclude: [/\.map$/, /asset-manifest\.json$/, /\.html$/],
+       importWorkboxFrom: 'local',
+       // navigateFallback: paths.servedPath + '/index.html',
+       // navigateFallbackBlacklist: [
+       //   // Exclude URLs starting with /_, as they're likely an API call
+       //   new RegExp('^/_'),
+       //   // Exclude URLs containing a dot, as they're likely a resource in
+       //   // public/ and not a SPA route
+       //   new RegExp('/[^/]+\\.[^/]+$'),
+       // ],
+     });
+     config.plugins.push(workboxWebpackPlugin);
+   }
    return config;
  };
...

Зарегистрируйте serviceWorker в файле входа страницы

/* src/pages/index.js 和 src/pages/login.js 中同时修改 */
+ import * as serviceWorker from '../serviceWorker';
  ...
+ serviceWorker.register();

Совместимость с IE11

Увеличиватьreact-app-polyfillполагаться

yarn add react-app-polyfill

Начальная позиция файла входа страницыimport

/* src/pages/index.js 和 src/pages/login.js 中同时修改 */
+ import 'react-app-polyfill/ie11';
+ import 'react-app-polyfill/stable';

Поддержка среды разработки

/* package.json */
    "browserslist": {
      "production": [
        ">0.2%",
        "not dead",
        "not op_mini all"
      ],
      "development": [
        "last 1 chrome version",
        "last 1 firefox version",
-       "last 1 safari version",
+       "last 1 safari version",
+       "last 1 ie version"
      ]
    },

Напоминание об обновлении браузера до более ранней версии

  1. Измените файл index.html
+ <script>/*@cc_on window.location.href="http://support.dmeng.net/upgrade-your-browser.html?referrer="+encodeURIComponent(window.location.href); @*/</script>
  <title>React App</title>
  1. Изменить параметры minifyJS
  const genHtmlWebpackPlugin = env => {
    const minify = {
      removeComments: true,
      collapseWhitespace: true,
      removeRedundantAttributes: true,
      useShortDoctype: true,
      removeEmptyAttributes: true,
      removeStyleLinkTypeAttributes: true,
      keepClosingSlash: true,
-     minifyJS: true,
+     minifyJS: {
+       comments: '@cc_on',
+     },
      minifyCSS: true,
      minifyURLs: true,
    };
    ...
  };