我有一个我在本地主机上开发的React应用程序。我想将它复制到一个名为vensa的子目录中的服务器。
我的webpack配置文件看起来像这样..
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.js文件是......
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 -p
并将3个文件复制到该子目录,则它不起作用,因为根路径为/
并且找不到js和css文件。我不确定改变(可能是这3个文件中的一个或全部)的最佳方式(最好的方法)让它在子目录中工作?
该应用的完整源代码为here以防万一。
谢谢!
答案 0 :(得分:22)
如果您使用的是React Router v4,则应该可以使用basename = {foobar
}进行设置。
<Router history={browserHistory} basename={'foobar'}>
<Route path="/" component={App} />
</Router>
链接到文档:https://reacttraining.com/react-router/web/api/BrowserRouter
注意:如果在子目录中使用create-react-app,您还需要在package.json文件中设置"homepage": "/foobar/",
。因此,生产构建指向了正确的道路。
答案 1 :(得分:2)
最近我必须做类似的事情,以便在子目录中运行反应应用程序。试试下面的内容,看看你是如何进行的。
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>
答案 2 :(得分:1)
使用html-webpack-plugin生成最终index.html
,并自动将正确的捆绑名称注入其中。
然后在您的webpack配置中设置output.publicPath,告诉webpack您的资产将部署到的子目录:
output: {
path: 'build',
publicPath: "/vensa/",
filename: 'bundle.js'
},
答案 3 :(得分:1)
或者您可以使用环境变量手动调整所有链接。
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>
这对我很有用。特别是因为我正在使用preact,其preact-router目前并不真正支持basename。
<Router history={browserHistory} basename={'foobar'}>
<Route path="/" component={App} />
</Router>
答案 4 :(得分:1)
除了trenthogan的回复外,我们可以将 basename分配给location.pathname
const loc = window.location || {};
<Router history={browserHistory} basename={loc.pathname || 'foobar'}>
<Route path="/" component={App} />
</Router>
进行此更改后,即使子目录路径将来发生更改,该应用程序也将运行。
答案 5 :(得分:1)
如果要安装在子目录中,则需要在此处指定基本名称。
hash
答案 6 :(得分:0)
在我的情况下,我需要支持一个方案,其中可能有0个到许多名称不明的子文件夹,并且生产仅使用静态文件。
在App.js中,我定义了以下简单函数:
const getBasename = path => path.substr(0, path.lastIndexOf('/'));
我用来定义基本名称:
<Router basename={getBasename(window.location.pathname)}>
此功能在没有子文件夹的情况下也可以在许多子文件夹下使用,并且还可以管理重新加载。
答案 7 :(得分:0)
<Router basename={'/directory-name'}>
<Route path='/' component={Home} />
</Router>
在public / index.html中添加基础。这有助于设置没有问题的路径。
<base href="%PUBLIC_URL%/">
使所有的css,js,图像和所有资源加载“ ./assets/您的资源”。
仅查看您是否正在使用历史记录。在历史记录中添加基本名称
const historyConfig = {
basename: 'your subdirectory'
};
const history = createBrowserHistory(historyConfig);
答案 8 :(得分:0)
谢谢@trenthogan,太棒了。但是作为一个新手,我对使用ROUTER教程工作时实际放置代码的位置感到困惑。这是对我有用的,一旦我把一切都搞定了……
在我的index.js中...
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();
答案 9 :(得分:-1)
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
}
...