programing

React 앱을 서버의 서브 디렉토리에 번들하려면 어떻게 해야 합니까?

topblog 2023. 3. 4. 14:06
반응형

React 앱을 서버의 서브 디렉토리에 번들하려면 어떻게 해야 합니까?

로컬 호스트에서 개발한 리액트 앱이 있습니다.vensa라는 서브디렉토리에 복사하고 싶습니다.

웹 팩 구성 파일은 다음과 같습니다.

const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: [
    './src/index.js'
  ],
  output: {
    path: 'build',
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel'
      },
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract('style', 'css!sass')
      },
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style', 'css')
      },
      {
        test: /\.(png|eot|svg|ttf|woff(2)?)(\?v=\d+\.\d+\.\d+)?/,
        loader: 'url'
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('vensa-dashboard.css')
  ],
  devServer: {
    historyApiFallback: true,
    contentBase: './build'
  }
};

index.html 파일은 다음과 같습니다.

<!DOCTYPE html>
<html>
<head>
  <title>Vensa Development Test</title>
  <link rel="stylesheet" href="/vensa-dashboard.css">
</head>
<body>
  <div class="container"></div>
  <script src="/bundle.js"></script>
</body>
</html>

그리고 제 routes.filename 파일은...

import React from 'react';
import { Route, IndexRoute } from 'react-router';
import VensaDashboard from './components/VensaDashboard';
import Inbox from './components/Inbox';
import Todo from './components/Todo';
import Home from './components/Home';

export default (
  <Route path="/" component={VensaDashboard}>
    <IndexRoute component={Home} />
    <Route path="/message" component={Inbox} />
    <Route path="/todo/:todoPage" component={Todo} />
  </Route>
);

하지만 만약 내가 그냥 뛰어가면webpack -p3개의 파일을 그 서브디렉토리에 카피합니다.루트 패스의 경우와 같이 동작하지 않습니다./js와 css 파일을 찾을 수 없습니다.서브디렉토리에서 동작시키기 위해 (아마도 이 3개의 파일 중 하나 또는 모두) 어떤 것을 변경하는 것이 가장 좋은지 잘 모르겠습니다.

도움이 될 수 있도록 앱의 전체 소스 코드가 도움이 수 있습니다.

감사합니다!

리액트 라우터 v4를 사용하는 경우 basename={을(를) 사용하여 설정할 수 있어야 합니다.foobar}.

<Router history={browserHistory} basename={'foobar'}>
  <Route path="/" component={App} />
</Router>

문서 링크: https://reacttraining.com/react-router/web/api/BrowserRouter

주의: 서브디렉토리에서 create-react-app을 사용하는 경우,"homepage": "/foobar/",당신의 패키지에.json 파일.따라서 프로덕션 구축은 올바른 방향으로 진행됩니다.

  1. "https://yourdomain/subdirectory/"를 패키지에 추가합니다.json
  2. 루트를 업데이트하고 루트의 서브 디렉토리를 설정합니다.
<Router basename={'/directory-name'}>
  <Route path='/' component={Home} />
</Router>
  1. public/index.html에 base를 추가합니다.문제없이 경로를 설정할 수 있습니다.

    <base href="%PUBLIC_URL%/">

  2. 모든 css, js, 이미지 및 모든 리소스를 로드하는 '.uss/your resources'를 만듭니다.

  3. 기록을 사용하는 경우에만 확인합니다. 기록에 기본 이름을 추가합니다.

    const historyConfig = {
        basename: 'your subdirectory'
    };
    const history = createBrowserHistory(historyConfig);

제 상황에서는 이름이 불분명한 서브폴더가 0에서 다수의 경우 운영에서 정적 파일만 사용하는 시나리오를 지원해야 했습니다.

App.js에서 다음과 같은 간단한 함수를 정의했습니다.

const getBasename = path => path.substr(0, path.lastIndexOf('/'));

기본 이름을 정의하는 데 사용합니다.

<Router basename={getBasename(window.location.pathname)}>

이는 하위 폴더뿐만 아니라 하위 폴더도 없으며 새로고침도 관리할 수 있습니다.

최근 서브디렉토리에서 리액트 앱을 실행하기 위해 비슷한 작업을 해야 했습니다.아래를 시험해 보고 어떻게 지내는지 확인해 보세요.

import React from 'react';
import { Router, Route, IndexRoute, useRouterHistory  } from 'react-router';
import { createHistory } from 'history';
import VensaDashboard from './components/VensaDashboard';
import Inbox from './components/Inbox';
import Todo from './components/Todo';
import Home from './components/Home';

// specify basename below if running in a subdirectory or set as "/" if app runs in root
const appHistory = useRouterHistory(createHistory)({
  basename: "/vensa"
});

export default (
  <Router history={appHistory} />
    <Route path="/" component={VensaDashboard}>
      <IndexRoute component={Home} />
      <Route path="/message" component={Inbox} />
      <Route path="/todo/:todoPage" component={Todo} />
    </Route>
  </Router>
);

또한 다음과 같이 index.html 내의 bundle.js 파일에 대한 경로를 업데이트해야 할 수도 있습니다.

<!DOCTYPE html>
<html>
<head>
  <title>Vensa Development Test</title>
  <link rel="stylesheet" href="/vensa-dashboard.css">
</head>
<body>
  <div class="container"></div>
  <script src="bundle.js"></script>
</body>
</html>

또는 환경 변수를 사용하여 모든 링크를 수동으로 조정할 수 있습니다.

const ENV = process.env.NODE_ENV || 'local'; //development
const config = {
    publicPath: ENV !== 'production' ? '/' : '/dev/'
};
plugins: ([
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify(ENV),
            'process.env.config': JSON.stringify(config)
        })
})

다음 중 하나의 경로:

<Route path={process.env.config.publicPath + "account/"} component={Account} />

다음으로 링크:

<Link class="panel-close" href={process.env.config.publicPath + "account/"} >Account</Link>

이게 나한테는 잘 먹혔어.특히 프리액트를 사용하고 있기 때문에 프리액트 라우터는 현재 베이스네임을 지원하지 않습니다.

<Router history={browserHistory} basename={'foobar'}>
  <Route path="/" component={App} />
</Router>

html-webpack-plugin을 사용하여 최종 생성index.html올바른 번들 이름이 자동으로 삽입됩니다.

그런 다음 웹 팩 구성에서 output.publicPath를 설정하여 자산이 배포되는 하위 디렉토리를 웹 팩에 알립니다.

output: {
  path: 'build',
  publicPath: "/vensa/",
  filename: 'bundle.js'
},

trenthogan 응답에 basname을 location.pathname에 할당할 수 있습니다.

const loc = window.location || {};
<Router history={browserHistory} basename={loc.pathname || 'foobar'}>
  <Route path="/" component={App} />
</Router>

이것에 의해, 향후 서브 디렉토리 패스가 변경되어도, 앱은 동작합니다.

서브디렉토리에 인스톨 하는 경우는, 여기에 basename을 지정할 필요가 있습니다.예를 들어, 다음과 같습니다.

  <Router basename="/dashboard/">

  <Route path="/login" component={Login} />

감사합니다. @trenthogan님, 대단합니다.그러나 초보자로서 Router에서 튜토리얼 작업을 하고 있을 때 코드를 실제로 어디에 넣어야 할지 막막했습니다.여기 내가 모든 걸 확인하고 나서 효과가 있었던 게다

내 색인.내 색인에서...

import React from 'react';
import ReactDOM from 'react-dom';
import './css/index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { BrowserRouter as Router, Route } from 'react-router-dom';

ReactDOM.render(
    <Router basename={'foobar'}>
        <Route path="/" component={App} />
    </Router>, document.getElementById('root'));
serviceWorker.unregister();

전에는 그렇게 보이던...

import React from 'react';
import ReactDOM from 'react-dom';
import './css/index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();
var sourcePath = path.resolve(__dirname, 'src', 'index.js');
var buildPath = path.resolve(__dirname, 'vensa');

module.exports = {
    entry: [sourcePath],
    output: {
        path: buildPath,
        filename: '[name]-[hash].js',
        hash: true
    }
    ...

언급URL : https://stackoverflow.com/questions/37396427/how-to-bundle-a-react-app-to-a-subdirectory-on-a-server

반응형