我有一组“主要是 JSX”的文件,如果直接解释为 JSX,则包含非法语法。我还有一组(同步)函数可以采用这种“大部分”JSX 语法并将其转换为正确的 JSX 语法。这些函数目前用作 webpack 加载器,以确保当 webpack 将数据交给 babel 时,它是正确的 JSX。
例如,这些函数将以下“几乎是 JSX”(其中包含与 JSX 冲突的 LaTeX 代码以及与 JSX 冲突的语法放在一个<pre>
块中:
module.exports = require('react').createClass({
...,
render: function() {
return (
<div>
<h1>An example component</h1>
<p>With latex:</p>
<p>\[ \begin{align}
f(t) &= t \cdot \sqrt{t} \\
&= t^{1.5}, 0 \leq t \leq \inf
\end{align}\]</p>
<p>code:</p>
<pre>function(t) {
if (t<0)
return undefined;
return Math.pow(t, 1.5);
}</pre>
</div>);
},
...
});
进入以下“实际 JSX”:
module.exports = require('react').createClass({
render: function() {
return (<div>
<h1>An example component</h1>
<p>With latex:</p>
<p><img src="images/latex/fhqo89732hf98o3h4f3.svg"/></p>
<p>code:</p>
<pre>function(t) {{'\n'}
if (t<0){'\n'}
return undefined;{'\n'}
return Math.pow(t, 1.5);{'\n'}
}</pre>
</div>);
}
});
运行这些函数后,LaTeX 已被解析并替换为指向其相应静态资产图像的链接,因此不再存在 JSX 语法冲突,并且该<pre>
元素已将任何冲突字符替换为 JSX 安全的 html 实体,并且为了保留换行符(因为缩小是空白的敌人),在每行的末尾都给出了明确的换行符。
但是,为了使用 Node.js 进行一些服务器端页面生成,我要求babel-register
Node 可以“本地”加载 JSX 文件,但这是一个问题,因为它会看到大部分 JSX 语法并抛出错误。
作为基本测试脚本,我使用以下代码:
// register native JSX
require("babel-register")({
// this is not sufficient to load "almost JSX" files
// with data that needs to be preprocessed out, first.
});
var React = require('react');
var ReactDOM = require('react-dom');
var ReactRouter = require('react-router'); // v1.0
var RoutingContext = ReactRouter.RoutingContext;
var RouteMap = require('../lib/site/routemap');
var routes = RouteMap.routes;
var paths = RouteMap.paths;
var fs = require('fs-extra');
paths.forEach(path => {
ReactRouter.match({ routes, location: path }, (err, _, renderProps) => {
var data = ReactDOM.renderToString(<RoutingContext {...renderProps} />);
fs.writeFile(`./static/pages/${url}.html`, data, 'utf-8');
});
});
对于干净的 JSX 文件,这不会造成任何问题,但对于需要预处理的文件,这会导致 Babel 抛出终端错误。所以:
有没有办法告诉babel-register
在要求节点通过require(...)
调用加载的文件上运行预处理器?
I've read through the babel docs but I can't seem to find any section on preprocessing; there are plugins, but these kick in after Babel has already parsed files into ASTs, and the almost-JSX syntax makes Babel error out while trying to build an AST.
Alternatively, is there a way to hook into Node's own file loader so that if it's being asked to load js/jsx files, I can run my preprocessors first and then tell node to pass the transformed data on to whoever handles these filetypes (in this case babel
)?