这确实是一个选项,但在我的开发实践和相关工作中并非如此。就我个人而言,我不会选择它,因为 Vue 看起来是这类应用更自然的选择。
一点背景信息:
在过去的几个月里,我一直在为一个客户开发一个高度定制的主题,期间我学到了很多关于 Discourse 内部运作机制的知识,但这可能只是很小的一部分。
目前,我正在重构一些初学者的错误,并努力让代码对将来可能接手维护的同事尽可能友好。因此,我针对 JSX 做了一些实验。
今天,我尝试了该主题帖首帖中的方法。我在此处包含了 transform-react-jsx:https://github.com/discourse/discourse/blob/master/lib/discourse_js_processor.rb#L143-L149:
if opts[:module_name] && !@skip_module
filename = opts[:filename] || 'unknown'
"Babel.transform(#{js_source}, { moduleId: '#{opts[:module_name]}', filename: '#{filename}', ast: false, presets: ['es2015'], plugins: [['transform-es2015-modules-amd', {noInterop: true}], 'transform-decorators-legacy', 'transform-react-jsx', exports.WidgetHbsCompiler] }).code"
else
"Babel.transform(#{js_source}, { ast: false, plugins: ['check-es2015-constants', 'transform-es2015-arrow-functions', 'transform-es2015-block-scoped-functions', 'transform-es2015-block-scoping', 'transform-es2015-classes', 'transform-es2015-computed-properties', 'transform-es2015-destructuring', 'transform-es2015-duplicate-keys', 'transform-es2015-for-of', 'transform-es2015-function-name', 'transform-es2015-literals', 'transform-es2015-object-super', 'transform-es2015-parameters', 'transform-es2015-shorthand-properties', 'transform-es2015-spread', 'transform-es2015-sticky-regex', 'transform-es2015-template-literals', 'transform-es2015-typeof-symbol', 'transform-es2015-unicode-regex', 'transform-regenerator', 'transform-decorators-legacy', 'transform-react-jsx',exports.WidgetHbsCompiler] }).code"
end
并修改了 vendor/assets/javascripts/babel.js 第 26586 行的 pragma 设置:
var id = state.opts.pragma || "React.createElement";
// 改为
var id = state.opts.pragma || "h";
这使得我能够在经过 Babel 处理的代码中使用来自 virtual-dom 的 h 函数,而不是 React.createElement。h 是 Discourse 的一部分,这感觉非常自然。
我不了解 Discourse 的开发历史,你们在代码中加入包含大量实用插件的完整 babel.js 文件肯定有你们的理由。遗憾的是,这些插件无法像我这样的最终开发者使用。因此,我的建议是:
-
使用某种 Babel 配置文件,如 .babelrc、.babel.yml,或者在 about.json 中定义一个类似 package.json 中的 Babel 配置字段(参考:Configure Babel · Babel babel.js 中的所有这些插件(或者可能是其他插件,见第 3 点)。
-
在 discourse_js_processor.rb#babel_parse(https://github.com/discourse/discourse/blob/master/lib/discourse_js_processor.rb#L138)中读取此配置,并将其与当前配置合并。
-
如果开发者希望拥有自定义的 Babel 插件,可以将其添加到 vendor/assets/javascripts/babel/plugins 文件夹(或仅仅是 babel/plugins 文件夹)中,Discourse 将自动识别并在转译过程中使用它。
我不熟悉 Rails 后端开发,所以这只是一个初步的提议。
另外还有一个问题:既然提到了,Discourse 读取主题 package.json 中的依赖项并在首次运行时安装它们,然后在主题内部使用(例如进行缓存)会有多困难?(如果依赖项发生变化,检查哪些发生了变化并安装或移除它们等)。
再次强调,你们的工作非常出色,成果令人惊叹。请不要感到来自我的任何压力,我只是来这里学习,进行有益的讨论,分享观点和想法。我并不期望你们会实施我的请求或做任何其他事情。