2016-08-21 2 views
0

Я использую Webpack 2.1.0-beta.20 с несколькими точками входа и разбиением кода.Tomcat развернул войну и разбиение кода Webpack

Точки разделения используют стиль ES6 System.import() и огонь, основанный на маршрутизации приложения. Это отлично работает на сервере Webpack dev и в Spring Boot, встроенном Tomcat, запущенном с gradle bootRun. Проблема возникает при упаковке на войну и развертывании вручную на Tomcat. В этом случае статические точки входа загружаются, как ожидалось. Это те, которые вводятся в index.html с помощью Webpack. Но браузер не пытается извлечь куски «загрузка по требованию». Результат - это не приложение React, которое разрешено в div.

<div> <!-- react-empty: 1 -->

Я думаю, что проблема заключается в том, что развертывание Tomcat использует имя войны как имя приложения в URL. Других вариантов выполнения нет.

http://localhost:8080/ против http://localhost:8080/app-name

Это не является неисправностью, чтобы найти какой-либо ресурс. Я могу вытащить первый кусок пакета по URL-адресу. Это похоже на то, что Webpack не прикладывает усилий. Я пробовал много вариантов на path и publicPath. Также попробуйте __webpack_public_path__. Но это не похоже на проблему с поиском. Вместо этого по какой-то причине Webpack не пытается загрузить кусок вообще.

Спасибо за любые предложения.

webpack.config.js

const path = require('path') 
const webpack = require('webpack') 
const HtmlWebpackPlugin = require('html-webpack-plugin') 
const ExtractTextPlugin = require('extract-text-webpack-plugin') 

const PATHS = { 
    app: './app/index.js', 
    html: './app/index.html', 
    src: path.resolve(__dirname, 'app'), 
    dist: path.resolve(__dirname, 'dist'), 
    routes: path.resolve(__dirname, 'app/routes') 
} 

const DEV_PORT = '4000' 
const SSL_PORT = '8543' 
const HOST = '127.0.0.1' 

const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({ 
    template: PATHS.html, 
    filename: 'index.html', 
    inject: 'body' 
}) 

module.exports = env => { 
    return { 
    entry: { 
     hmr: getHmrEntry(), 
     js: PATHS.app, 
     route: PATHS.routes + '/routes.js', 
     vendor: [ 
     'react', 
     'react-router', 
     'react-dom', 
     'babel-polyfill' 
     ] 
    }, 

    output: { 
     filename: '[name].bundle.js', 
     chunkFilename: '[id].bundle.js', 
     path: PATHS.dist, 
     publicPath: getPublicPath() 
    }, 

    context: __dirname, 

    resolve: { 
     modules: [path.resolve(__dirname, '.'), 'node_modules'] 
    }, 

    devtool: env.prod ? 'eval' : 'inline-source-map', 

    bail: env.prod, 

    externals: { 
     'cheerio': 'window', 
     'react/lib/ExecutionEnvironment': true, 
     'react/lib/ReactContext': true 
    }, 

    module: { 
     loaders: [ 
     { 
      test: /(\.js|\.jsx)$/, 
      exclude: /node_modules/, 
      loaders: ['react-hot', 'babel?presets[]=react,presets[]=es2015,presets[]=stage-2', 'eslint'] 
     }, 
     { 
      test: /\.css$/, 
      loader: ExtractTextPlugin.extract({ 
      fallbackLoader: 'style-loader', 
      loader: ['css'] 
      }) 
     } 
     ] 
    }, 

    plugins: [ 
     HtmlWebpackPluginConfig, 

     new webpack.optimize.CommonsChunkPlugin({ 
     name: 'vendor', 
     minChunks: Infinity, 
     filename: 'vendor.bundle.js' 
     }), 

     new ExtractTextPlugin({ 
     filename: '[name].[id].style.css', 
     allChunks: false 
     }) 
    ], 

    devServer: { 
     contentBase: PATHS.dist, 
     port: DEV_PORT, 
     historyApiFallback: true 
    } 
    } 

    function getPublicPath() { 
    // var prodPath = 'https://' + HOST + ':' + SSL_PORT + '/react-app/' 
    var prodPath = '/react-app/' 
    // var devPath = 'http://' + HOST + ':' + PORT + '/dist/' 
    var devPath = '/dist/' 
    var publicPath 

    if (env.prod) { 
     publicPath = prodPath 
    } else { 
     publicPath = devPath 
    } 
    return publicPath 
    } 

    function getHmrEntry() { 
    var hmr = [] 
    if (!env.prod) { 
     hmr = [ 
     'webpack-dev-server/client?http://' + HOST + ':' + DEV_PORT, 
     'webpack/hot/only-dev-server' 
     ] 
    } 
    return hmr 
    } 
} 

index.js

import 'babel-polyfill' 
import React from 'react' 
import { render } from 'react-dom' 
import { Router, browserHistory } from 'react-router/es6' 
import rootRoute from './routes/routes' 
import '../style/common.css' 
// __webpack_public_path__ = window.resourceBaseUrl + '/react-app/' 

render(
    <Router history={browserHistory} routes={rootRoute} />, 
    document.getElementById('root') 
) 

routes.js

import App from '../containers/App' 

function errorLoading (err) { 
    console.error('Dynamic page loading failed', err) 
} 

function loadRoute (cb) { 
    return (module) => cb(null, module.default) 
} 

export default { 
    component: App, 
    childRoutes: [ 
    { 
     path: '/', 
     getComponent (location, cb) { 
     System.import('./Home') 
      .then(loadRoute(cb)) 
      .catch(errorLoading) 
     } 
    }, 
    { 
     path: 'about', 
     getComponent (location, cb) { 
     System.import('./About') 
      .then(loadRoute(cb)) 
      .catch(errorLoading) 
     } 
    }, 
    { 
     path: 'feature', 
     getComponent (location, cb) { 
     System.import('./Feature') 
      .then(loadRoute(cb)) 
      .catch(errorLoading) 
     } 
    } 
    ] 
} 
+0

Просто ударил меня, проблема связана с моими дорожками маршрута. Мне нужно добавить путь контекста приложения к URL. – RnR

ответ

0

Исправление добавить basename при создании экземпляра browserHistory, а не просто импортируя его. В index.js выше изменения к этому:

import 'babel-polyfill' 
import React from 'react' 
import { render } from 'react-dom' 
import { Router } from 'react-router/es6' 
import { createHistory, useBasename } from 'history' 
import rootRoute from './routes/routes' 
import '../style/common.css' 

const browserHistory = useBasename(createHistory)({ 
    basename: '/react-app' 
}) 

render(
    <Router history={browserHistory} routes={rootRoute} />, 
    document.getElementById('root') 
) 

Благодарности к людям, участвующих в этой дискуссии - https://github.com/reactjs/react-router/issues/353

0

Использование history как выше было устаревшим. Вот еще текущая версия:

import 'babel-polyfill' 
import { render } from 'react-dom' 
import React from 'react' 
import { Router, useRouterHistory } from 'react-router/es6' 
import { createHistory } from 'history' 
import rootRoute from './routes/routes' 
import '../style/common.css' 

const browserHistory = useRouterHistory(createHistory)({ basename: '/react-app' }) 

render(
    <Router history={browserHistory} routes={rootRoute} />, 
    document.getElementById('root') 
) 
Смежные вопросы