我对Nashorn和React-redux有奇怪的行为。
首先,我有一个非常简单的javascript,它在部署之前就被babelified了(我把JSX放到这里,因为得到的babelified文件很大):

var React = require('react');
var ReactDOM = require('react-dom');
var connect = require('react-redux').connect;
var Link = require('react-router').Link;

function mapStateToProps(state) {
    console.log("mapStateToProps ", state);
    return {options: state.options};
};

var IndexContainer = React.createClass({
    render: function () {
        console.log(this.props.options);
        return (
            <div>
                <Link to="r">Link!</Link>
            </div>
        );
    }
});

var Index = connect(mapStateToProps)(IndexContainer);

var renderServer = function (data) {
    var data = Java.from(data);
    return React.renderToString(
        React.createElement(Index, {data: data})
    );
};


其次,我有Java代码:

@Component
@SuppressWarnings("restriction")
public class ReactRenderer {
    private ThreadLocal<NashornScriptEngine> engineHolder = new ThreadLocal<NashornScriptEngine>() {
        @Override
        protected NashornScriptEngine initialValue() {
            NashornScriptEngine nashornScriptEngine = (NashornScriptEngine) new ScriptEngineManager()
                    .getEngineByName("nashorn");
            try {
                nashornScriptEngine.eval(read("static/nashorn-polyfill.js"));
                nashornScriptEngine.eval(read("/WEB-INF/resources/js/main.js"));
            } catch (ScriptException e) {
                throw new RuntimeException(e);
            }
            return nashornScriptEngine;
        }
    };

    private Reader read(String path) {
        InputStream in = getClass().getClassLoader().getResourceAsStream(path);
        return new InputStreamReader(in);
    }

    public String render(List<Object> objects) {
        try {
            Object html = engineHolder.get().invokeFunction("renderServer", objects);
            return String.valueOf(html);
        } catch (Exception e) {
            throw new IllegalStateException("failed to render react component", e);
        }
    }
}


当我在Java中调用render(objects)时,我得到:

java.lang.NoSuchMethodException: No such function renderServer
    jdk.nashorn.api.scripting.ScriptObjectMirror.callMember(ScriptObjectMirror.java:204)
    jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:383)
    jdk.nashorn.api.scripting.NashornScriptEngine.invokeFunction(NashornScriptEngine.java:190)


如果我删除

function mapStateToProps(state) {
    console.log("mapStateToProps ", state);
    return {options: state.options};
};


它确实找到了renderServer函数,但是由于那里没有mapStateToProps而无法进行评估,并且根据redux tutorial应该呈现为用所有道具,Provider等(而不只是React component)将整个字符串串起来,否则使用this.store.dispatch处理功能将不起作用。
我在这里做错什么以及如何使它起作用?



更新:
我发现问题出在混入批处理文件中。如果将文件放到文件中,而我只想评估React组件(JS,而不是JSX)和不带任何库的renderServer函数,Nashorn可以找到renderServer函数并调用它。
但是所有教程都说Nashorn非常适合理解批处理文件。
所以我真的不明白这可能是什么问题。

最佳答案

由于您可能正在使用webpack,因此var renderServer最终将成为webpack函数中的局部变量。
global.renderServer = ....应该可以工作

09-17 01:44