Создать приложение React V2 - несколько точек входа - PullRequest
0 голосов
/ 23 марта 2019

Я пытаюсь создать приложение React с 2 точками входа, одна для приложения и одна для панели администратора.

Я начинаю с создания приложения React V2 и следую за этой веткой вопросов gitHub https://github.com/facebook/create-react-app/issues/1084 и этот учебник http://imshuai.com/create-react-app-multiple-entry-points/.

Я пытаюсь перенести инструкции по добавлению нескольких точек входа из CRA V1 для работы в V2, но мне кажется, что я что-то упустил.

После извлечения CRA это пути, которые я изменил / добавил в paths.js:

module.exports = {
    appBuild: resolveApp('build/app'),
    appPublic: resolveApp('public/app'),
    appHtml: resolveApp('public/app/index.html'),
    appIndexJs: resolveModule(resolveApp, 'src/app'),
    appSrc: resolveApp('src'),
    adminIndexJs: resolveModule(resolveApp, 'src/admin'),
    adminSrc: resolveApp('src'),
    adminPublic: resolveApp('public/admin'),
    adminHtml: resolveApp('public/admin/index.html'),
};

Я добавил эти точки входа в веб-пакет:

    entry: {
        app: [
            isEnvDevelopment &&
                require.resolve('react-dev-utils/webpackHotDevClient'),
            paths.appIndexJs,
        ].filter(Boolean),
        admin: [
            isEnvDevelopment &&
                require.resolve('react-dev-utils/webpackHotDevClient'),
            paths.adminIndexJs,
        ].filter(Boolean)
    },
    output: {
      path: isEnvProduction ? paths.appBuild : undefined,
      pathinfo: isEnvDevelopment,
      filename: isEnvProduction
        ? 'static/js/[name].[contenthash:8].js'
        : isEnvDevelopment && 'static/js/bundle.js',
      chunkFilename: isEnvProduction
        ? 'static/js/[name].[contenthash:8].chunk.js'
        : isEnvDevelopment && 'static/js/[name].chunk.js',
      publicPath: publicPath,
      devtoolModuleFilenameTemplate: isEnvProduction
        ? info =>
            path
              .relative(paths.appSrc, info.absoluteResourcePath)
              .replace(/\\/g, '/')
        : isEnvDevelopment &&
          (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
    },

I 'Мы изменили HtmlWebpackPlugin следующим образом:

  new HtmlWebpackPlugin(
    Object.assign(
      {},
      {
        inject: true,
        template: paths.appHtml,
        filename: paths.appPublic,
      },
      isEnvProduction
        ? {
            minify: {
              removeComments: true,
              collapseWhitespace: true,
              removeRedundantAttributes: true,
              useShortDoctype: true,
              removeEmptyAttributes: true,
              removeStyleLinkTypeAttributes: true,
              keepClosingSlash: true,
              minifyJS: true,
              minifyCSS: true,
              minifyURLs: true,
            },
          }
        : undefined
    )
  ),
  new HtmlWebpackPlugin(
    Object.assign(
      {},
      {
        inject: true,
        template: paths.adminHtml,
        filename: paths.adminPublic,
      },
      isEnvProduction
        ? {
            minify: {
              removeComments: true,
              collapseWhitespace: true,
              removeRedundantAttributes: true,
              useShortDoctype: true,
              removeEmptyAttributes: true,
              removeStyleLinkTypeAttributes: true,
              keepClosingSlash: true,
              minifyJS: true,
              minifyCSS: true,
              minifyURLs: true,
            },
          }
        : undefined
    )
  ),

И изменили веб-пакет Dev Server:

historyApiFallback: {
  disableDotRule: true,
  rewrites: [
    { from: /^\/admin.html/, to: '/build/admin/index.html' },
  ]
},

Моя файловая структура выглядит следующим образом:

.
+-- _src
|   +-- app.js
|   +-- admin.js
|   +-- _app
|       +-- App.js
|   +-- _admin
|       +-- App.js
|   +-- _shared
|       +-- serviceWorker.js
+-- _public
|   +-- _app
|       +-- index.html
|       +-- manifest.json
|   +-- _admin
|       +-- index.html
|       +-- manifest.json

Я хотел бы мойпапка build для размещения папки приложения и папки администратора с двумя отдельными SPA-файлами.

Когда я запускаю yarn start, он не выдает никаких ошибок и сообщает Compiled successfully!, однако приложение скомпилировано только частичноа не приложение администратора, js не был скомпилирован или добавлен в приложение eiтам.

yarn build выдает ошибку с половиной скомпилированного приложения, без приложения администратора.Это ошибка:

yarn run v1.12.3
$ node scripts/build.js
Creating an optimized production build...
Failed to compile.

EISDIR: illegal operation on a directory, open 
'foo/bar/public/app'


error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

В папке сборки он много создал до выхода:

.
+-- _static
|   +-- _css
|   +-- _js
|   +-- _media
|       +-- logo.5d5d9eef.svg
+-- precache-manifest.a9c066d088142837bfe429bd3779ebfa.js
+-- service-worker.js
+-- asset-manifest.json
+-- manifest.json

Кто-нибудь знает, что мне не хватает, чтобы заставить эту работу работать правильно?

Ответы [ 2 ]

1 голос
/ 30 марта 2019

Я понял, что установка filename в HTMLWebpackPlugin на appPublic или adminPublic неверна и должна быть app/index.html admin/index.html.

Однако, где я хотел бы иметь 2 отдельные папки в папке сборки, одну для приложения, а другую для приложения администратора, использование этого метода требует большей сложности, поскольку в веб-пакете нет переменной ввода, которую можно использовать для установки места назначения дорожка. Например, мне нужно иметь возможность сделать что-то вроде [entry]/static/js/[name].[contenthash:8].chunk.js. Я думаю, что один из способов сделать это - использовать Webpack MultiCompiler.

Однако вместо того, чтобы сделать это, я передал точку входа как переменную окружения в package.json, добавив REACT_APP_ENTRY= примерно так:

  "scripts": {
    "start-app": "REACT_APP_ENTRY=app node scripts/start.js",
    "build-app": "REACT_APP_ENTRY=app node scripts/build.js",
    "start-admin": "REACT_APP_ENTRY=admin node scripts/start.js",
    "build-admin": "REACT_APP_ENTRY=admin node scripts/build.js",
    "test": "node scripts/test.js"
  },

В start.js я добавил const isApp = process.env.REACT_APP_ENTRY === 'app'; вверху:

'use strict';

process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';

const isApp = process.env.REACT_APP_ENTRY === 'app';

И обновлено там, где устанавливается порт, так что я могу запускать оба сервера разработки одновременно без конфликта:

const DEFAULT_PORT = parseInt(process.env.PORT, 10) || (isApp ? 3000 : 3001);
const HOST = process.env.HOST || '0.0.0.0';

Затем наверху paths.js добавить const isApp = process.env.REACT_APP_ENTRY === 'app';:

const envPublicUrl = process.env.PUBLIC_URL;
const isApp = process.env.REACT_APP_ENTRY === 'app';

И, наконец, обновите пути в зависимости от набора переменных env:

module.exports = {
  dotenv: resolveApp('.env'),
  appPath: resolveApp('.'),
  appBuild: isApp ? resolveApp('build/app') : resolveApp('build/admin'),
  appPublic: isApp ? resolveApp('public/app') : resolveApp('public/admin'),
  appHtml: isApp ? resolveApp('public/app/index.html') : resolveApp('public/admin/index.html'),
  appIndexJs: isApp ? resolveModule(resolveApp, 'src/app') : resolveModule(resolveApp, 'src/admin'),
  appPackageJson: resolveApp('package.json'),
  appSrc: resolveApp('src'),
  appTsConfig: resolveApp('tsconfig.json'),
  yarnLockFile: resolveApp('yarn.lock'),
  testsSetup: resolveModule(resolveApp, 'src/setupTests'),
  proxySetup: resolveApp('src/setupProxy.js'),
  appNodeModules: resolveApp('node_modules'),
  publicUrl: getPublicUrl(resolveApp('package.json')),
  servedPath: getServedPath(resolveApp('package.json')),
};

Я думаю, что этот метод, так как он намного проще, лучше подходит для этого варианта использования, поскольку он позволяет гибко компилировать только приложение или только администратора, а не заставляет вас компилировать оба, когда был изменен только один. Я могу одновременно запускать yarn start-app и yarn start-admin с отдельными приложениями, работающими на разных портах.

0 голосов
/ 30 марта 2019

Это работает для последней версии реакции v2, но работает только для сборки (npm run build);запуск npm start в папке реакции (клиент) может привести к ошибке

https://github.com/chiKaRau/git-reactv2-express-multiple-entry-point

других источников http://houserqu.com/2018/04/26/create-react-app-%E9%85%8D%E7%BD%AE%E5%A4%9A%E9%A1%B5%E9%9D%A2/

https://www.jianshu.com/p/951287ce12c0

http://imshuai.com/create-react-app-multiple-entry-points/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...