React(五)create-react-app 脚手架配置多页面应用

    单页面的应用是目前前端应用的主流方向,react、vue等前端框架在单页面应用上都相对比较适用。但是多页面应用在项目的也必不可少,企业的门户网站因需要百度推广,更加适合用多页面应用来开发。本文将介绍运用create-react-app脚手架来搭建一个简单实用的多页面项目框架。

  1.初始化项目

    创建create-react-app脚手架这边不过多叙述,react开发人员应该都会构建,构建成功后执行以下命令初始化webpack配置;

yarn eject 或者 npm run eject

执行完毕后项目的根目录会自动创建config文件夹,里面的文件即初始化的webpack配置文件。

   2.整理src目录文件

  •     删除src文件夹内多余的文件

   只需要保留index.js和App.jsx文件,在打包时可能用到pwa的serviceWorker,因而也保留ServiceWorker.,js文件,删除其他多余文件。

  •    新建pages文件夹,用于存放多页面的各个页面应用

   pages文件夹内的每一个文件目录即为一个页面应用,不能乱存放文件和文件目录,在pages文件夹内新建home和note文件,即两个页面应用,将之前src保留的index.js和App.jsx分别拷贝到home和note目录。

  • 必不可少用到redux,修改index.js的文件
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { createStore, compose, applyMiddleware } from 'redux'
import { ConfigProvider } from 'antd'
import thunk from 'redux-thunk'
import reducer from '../../store/reducer'
import zhCN from 'antd/es/locale/zh_CN'
import * as serviceWorker from '../../serviceWorker'
import App from './App'

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)))

ReactDOM.render(
  <Provider store={store}>
    <ConfigProvider locale={zhCN}>
      <App />
    </ConfigProvider>
  </Provider>,
  document.getElementById('root')
)

serviceWorker.unregister()

3.修改paths.js配置页面的路径入口

   进入config文件目录内的paths.js文件,添加以下代码,配置页面的路径入口;

const glob = require('glob');
// 获取指定路径下的入口文件
function getEntries (globPath) {
  const files = glob.sync(globPath),
    entries = {};
  files.forEach(function (filepath) {
    const split = filepath.split('/');
    const name = split[split.length - 2];
    entries[name] = './' + filepath;
  });
  return entries;
}

const entries = getEntries('src/pages/**/index.js');

function getIndexJs () {
  const indexJsList = [];
  Object.keys(entries).forEach((name) => {
    const indexjs = resolveModule(resolveApp, `src/pages/${name}/index`)
    indexJsList.push({
      name,
      path: indexjs
    });
  })
  return indexJsList;
}
const indexJsList = getIndexJs()

   在module.exports导出对象里添加上述定义的entries入口

module.exports = {
  dotenv: resolveApp('.env'),
  appPath: resolveApp('.'),
  appBuild: resolveApp('build'),
  appPublic: resolveApp('public'),
  appHtml: resolveApp('public/index.html'),
  appIndexJs: indexJsList,
  appPackageJson: resolveApp('package.json'),
  appSrc: resolveApp('src'),
  appTsConfig: resolveApp('tsconfig.json'),
  appJsConfig: resolveApp('jsconfig.json'),
  yarnLockFile: resolveApp('yarn.lock'),
  testsSetup: resolveModule(resolveApp, 'src/setupTests'),
  proxySetup: resolveApp('src/setupProxy.js'),
  appNodeModules: resolveApp('node_modules'),
  publicUrlOrPath,
  entries // 添加入口对象
};

4.修改webpack.config.js文件

(1)配置入口entry

在return之前定义entry变量,遍历上述paths内的appIndexJs

  const entry = {}
  paths.appIndexJs.forEach(e => {
    entry[e.name] = [
      isEnvDevelopment &&
      require.resolve('react-dev-utils/webpackHotDevClient'),
      e.path
    ].filter(Boolean)
  });

然后将配置中return的entry改成定义的entry变量。

扫描二维码关注公众号,回复: 11701142 查看本文章

(2)修改出口output

将output中的filename和chunkFilename修改下,添加page的路径

// 修改前
      filename: isEnvProduction
        ? 'static/js/[name].[contenthash:8].js'
        : isEnvDevelopment && 'static/js/bundle.js',
      // TODO: remove this when upgrading to webpack 5
      futureEmitAssets: true,
      // There are also additional JS chunk files if you use code splitting.
      chunkFilename: isEnvProduction
        ? 'static/js/[name].[contenthash:8].chunk.js'
        : isEnvDevelopment && 'static/js/[name].chunk.js',

// 修改后
      filename: isEnvProduction
        ? 'static/js/[name]/[name].[contenthash:8].js'
        : isEnvDevelopment && 'static/js/[name]/[name].bundle.js',
      // TODO: remove this when upgrading to webpack 5
      futureEmitAssets: true,
      // There are also additional JS chunk files if you use code splitting.
      chunkFilename: isEnvProduction
        ? 'static/js/[name]/[name].[contenthash:8].chunk.js'
        : isEnvDevelopment && 'static/js/[name]/[name].chunk.js',

(3)修改plugins

   HtmlWebpackPlugin插件的主要作用是生成创建html的文件,配置多个HtmlWebpackPlugin可以生成多页面的html文件入口,将之前配置单页面的HtmlWebpackPlugin删除,添加如下遍历entry的生成多页面的入口

      // Generates an `index.html` file with the <script> injected.
      ...Object.keys(paths.entries).map((name) => {
        return new HtmlWebpackPlugin(
          Object.assign(
            {},
            {
              inject: true,
              chunks: [name],
              template: paths.appHtml,
              filename: name + '.html',
            },
            isEnvProduction
              ? {
                minify: {
                  removeComments: true,
                  collapseWhitespace: true,
                  removeRedundantAttributes: true,
                  useShortDoctype: true,
                  removeEmptyAttributes: true,
                  removeStyleLinkTypeAttributes: true,
                  keepClosingSlash: true,
                  minifyJS: true,
                  minifyCSS: true,
                  minifyURLs: true,
                },
              }
              : undefined
          )
        )
      }),

(4)注释ManifestPlugin部分代码

      // new ManifestPlugin({
      //   fileName: 'asset-manifest.json',
      //   publicPath: paths.publicUrlOrPath,
      //   generate: (seed, files, entrypoints) => {
      //     const manifestFiles = files.reduce((manifest, file) => {
      //       manifest[file.name] = file.path;
      //       return manifest;
      //     }, seed);
      //     const entrypointFiles = entrypoints.main.filter(
      //       fileName => !fileName.endsWith('.map')
      //     );

      //     return {
      //       files: manifestFiles,
      //       entrypoints: entrypointFiles,
      //     };
      //   },
      // }),

(5)更改校验文件是否存在的代码

修改scripts目录下的build.js和start.js文件的校验代码

// 原来代码
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
  process.exit(1);
}

// 修改后的代码
if (!checkRequiredFiles([paths.appHtml, ...paths.appIndexJs.map(e => e.path)])) {
  process.exit(1);
}

成果

1.访问路径

http://localhost:3000/home.html

http://localhost:3000/note.html

2.添加页面

添加页面只要在pages目录内添加新页面的目录文件即可。

相应项目的git后续上传

参考: https://blog.csdn.net/iwowen/article/details/103538942

猜你喜欢

转载自blog.csdn.net/zhengjie0722/article/details/108475854