DEV: Remove vendored babel and update config for plugins/themes (#17832)
The new plugin list is based on the ones currently used in our ember-cli pipeline, and are based on our official browser support policy. This commit includes an update to the raw-handlebars compiler to remove the 'very hacky but lets us use ES6' code. It's served us well for the last 6 years, but the babel config changes broke it (`const` -> `let`). This commit takes the opportunity to refactor it to take a similar approach to PrettyText, by leaning on `mini-loader.js`.
This commit is contained in:
parent
169f2ad443
commit
7f9c2c0bfb
|
@ -17,6 +17,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.18.5",
|
||||
"@babel/standalone": "^7.18.12",
|
||||
"@discourse/itsatrap": "^2.0.10",
|
||||
"@ember/jquery": "^2.0.0",
|
||||
"@ember/optional-features": "^2.0.0",
|
||||
|
|
|
@ -957,6 +957,11 @@
|
|||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/standalone@^7.18.12":
|
||||
version "7.18.12"
|
||||
resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.18.12.tgz#4c0abdf1b5213394e73a0ba5500dcc287194a20d"
|
||||
integrity sha512-wDh3K5IUJiSMAY0MLYBFoCaj2RCZwvDz5BHn2uHat9KOsGWEVDFgFQFIOO+81Js2phFKNppLC45iOCsZVfJniw==
|
||||
|
||||
"@babel/template@^7.16.7", "@babel/template@^7.18.6":
|
||||
version "7.18.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31"
|
||||
|
|
|
@ -4,6 +4,25 @@ require 'mini_racer'
|
|||
|
||||
class DiscourseJsProcessor
|
||||
|
||||
DISCOURSE_COMMON_BABEL_PLUGINS = [
|
||||
'proposal-optional-chaining',
|
||||
['proposal-decorators', { legacy: true } ],
|
||||
'transform-template-literals',
|
||||
'proposal-class-properties',
|
||||
'proposal-class-static-block',
|
||||
'proposal-private-property-in-object',
|
||||
'proposal-private-methods',
|
||||
'proposal-numeric-separator',
|
||||
'proposal-logical-assignment-operators',
|
||||
'proposal-nullish-coalescing-operator',
|
||||
'proposal-json-strings',
|
||||
'proposal-optional-catch-binding',
|
||||
'transform-parameters',
|
||||
'proposal-async-generator-functions',
|
||||
'proposal-object-rest-spread',
|
||||
'proposal-export-namespace-from',
|
||||
]
|
||||
|
||||
def self.plugin_transpile_paths
|
||||
@@plugin_transpile_paths ||= Set.new
|
||||
end
|
||||
|
@ -94,9 +113,10 @@ class DiscourseJsProcessor
|
|||
def self.create_new_context
|
||||
# timeout any eval that takes longer than 15 seconds
|
||||
ctx = MiniRacer::Context.new(timeout: 15000, ensure_gc_after_idle: 2000)
|
||||
ctx.eval("var self = this; #{File.read("#{Rails.root}/vendor/assets/javascripts/babel.js")}")
|
||||
ctx.eval("#{File.read("#{Rails.root}/app/assets/javascripts/node_modules/@babel/standalone/babel.js")}")
|
||||
ctx.eval(File.read(Ember::Source.bundled_path_for('ember-template-compiler.js')))
|
||||
ctx.eval("module = {}; exports = {};")
|
||||
ctx.eval("const DISCOURSE_COMMON_BABEL_PLUGINS = #{DISCOURSE_COMMON_BABEL_PLUGINS.to_json};")
|
||||
ctx.attach("rails.logger.info", proc { |err| Rails.logger.info(err.to_s) })
|
||||
ctx.attach("rails.logger.error", proc { |err| Rails.logger.error(err.to_s) })
|
||||
ctx.eval <<JS
|
||||
|
@ -156,9 +176,34 @@ JS
|
|||
|
||||
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-modules-amd', {noInterop: true}], 'proposal-object-rest-spread', 'proposal-optional-chaining', ['proposal-decorators', {legacy: true} ], 'proposal-class-properties', exports.WidgetHbsCompiler] }).code"
|
||||
<<~JS
|
||||
Babel.transform(
|
||||
#{js_source},
|
||||
{
|
||||
moduleId: '#{opts[:module_name]}',
|
||||
filename: '#{filename}',
|
||||
ast: false,
|
||||
plugins: [
|
||||
exports.WidgetHbsCompiler,
|
||||
['transform-modules-amd', {noInterop: true}],
|
||||
...DISCOURSE_COMMON_BABEL_PLUGINS
|
||||
]
|
||||
}
|
||||
).code
|
||||
JS
|
||||
else
|
||||
"Babel.transform(#{js_source}, { ast: false, plugins: ['proposal-json-strings', 'proposal-nullish-coalescing-operator', 'proposal-logical-assignment-operators', 'proposal-numeric-separator', 'proposal-optional-catch-binding', 'transform-dotall-regex', 'proposal-unicode-property-regex', 'transform-named-capturing-groups-regex', 'proposal-object-rest-spread', 'proposal-optional-chaining', 'transform-arrow-functions', 'transform-block-scoped-functions', 'transform-block-scoping', 'transform-computed-properties', 'transform-destructuring', 'transform-duplicate-keys', 'transform-for-of', 'transform-function-name', 'transform-literals', 'transform-object-super', 'transform-parameters', 'transform-shorthand-properties', 'transform-spread', 'transform-sticky-regex', 'transform-template-literals', 'transform-typeof-symbol', 'transform-unicode-regex', ['proposal-decorators', {legacy: true}], 'proposal-class-properties', exports.WidgetHbsCompiler] }).code"
|
||||
<<~JS
|
||||
Babel.transform(
|
||||
#{js_source},
|
||||
{
|
||||
ast: false,
|
||||
plugins: [
|
||||
exports.WidgetHbsCompiler,
|
||||
...DISCOURSE_COMMON_BABEL_PLUGINS
|
||||
]
|
||||
}
|
||||
).code
|
||||
JS
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -10,20 +10,20 @@ class Barber::Precompiler
|
|||
|
||||
def precompiler
|
||||
if !@precompiler
|
||||
|
||||
loader = File.read("#{Rails.root}/app/assets/javascripts/mini-loader.js")
|
||||
source = File.read("#{Rails.root}/app/assets/javascripts/discourse-common/addon/lib/raw-handlebars.js")
|
||||
transpiler = DiscourseJsProcessor::Transpiler.new(skip_module: true)
|
||||
transpiled = transpiler.perform(source)
|
||||
|
||||
# very hacky but lets us use ES6. I'm ashamed of this code -RW
|
||||
transpiled = transpiled[transpiled.index('var RawHandlebars = ')...transpiled.index('export ')]
|
||||
transpiled = DiscourseJsProcessor.transpile(source, "#{Rails.root}/app/assets/javascripts/", "discourse-common/lib/raw-handlebars")
|
||||
|
||||
@precompiler = StringIO.new <<~JS
|
||||
var __RawHandlebars;
|
||||
let __RawHandlebars;
|
||||
|
||||
(function(){
|
||||
#{transpiled};
|
||||
__RawHandlebars = RawHandlebars;
|
||||
})();
|
||||
#{loader}
|
||||
define("handlebars", ["exports"], function(exports){ exports.default = Handlebars; })
|
||||
#{transpiled}
|
||||
__RawHandlebars = require("discourse-common/lib/raw-handlebars").default;
|
||||
})()
|
||||
|
||||
Barber = {
|
||||
precompile: function(string) {
|
||||
|
@ -31,6 +31,7 @@ class Barber::Precompiler
|
|||
}
|
||||
};
|
||||
JS
|
||||
|
||||
end
|
||||
|
||||
@precompiler
|
||||
|
|
|
@ -197,7 +197,7 @@ HTML
|
|||
expect(theme.javascript_cache.content).to include('addRawTemplate("discovery"')
|
||||
expect(theme.javascript_cache.content).to include("define(\"discourse/theme-#{theme.id}/controllers/discovery\"")
|
||||
expect(theme.javascript_cache.content).to include("define(\"discourse/theme-#{theme.id}/controllers/discovery-2\"")
|
||||
expect(theme.javascript_cache.content).to include("var settings =")
|
||||
expect(theme.javascript_cache.content).to include("const settings =")
|
||||
end
|
||||
|
||||
def create_upload_theme_field!(name)
|
||||
|
|
|
@ -248,22 +248,8 @@ HTML
|
|||
)
|
||||
expect(javascript_cache.content).to include("name: \"theme-field-#{field.id}-mobile-html-script-1\",")
|
||||
expect(javascript_cache.content).to include("after: \"inject-objects\",")
|
||||
expect(javascript_cache.content).to include("(0, _pluginApi.withPluginApi)(\"0.1\", function (api) {")
|
||||
expect(javascript_cache.content).to include("var x = 1;")
|
||||
end
|
||||
|
||||
it "replaces const writes with _readOnlyError function call" do
|
||||
html = <<HTML
|
||||
<script type='text/discourse-plugin' version='0.1'>
|
||||
const x = 1;
|
||||
x = 2;
|
||||
</script>
|
||||
HTML
|
||||
|
||||
baked, javascript_cache = transpile(html)
|
||||
expect(baked).to include(javascript_cache.url)
|
||||
expect(javascript_cache.content).to include('var x = 1;')
|
||||
expect(javascript_cache.content).to include('2, _readOnlyError("x");')
|
||||
expect(javascript_cache.content).to include("(0, _pluginApi.withPluginApi)(\"0.1\", api =>")
|
||||
expect(javascript_cache.content).to include("const x = 1;")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -369,9 +355,9 @@ HTML
|
|||
)
|
||||
expect(theme_field.javascript_cache.content).to include("name: \"theme-field-#{theme_field.id}-common-html-script-1\",")
|
||||
expect(theme_field.javascript_cache.content).to include("after: \"inject-objects\",")
|
||||
expect(theme_field.javascript_cache.content).to include("(0, _pluginApi.withPluginApi)(\"1.0\", function (api)")
|
||||
expect(theme_field.javascript_cache.content).to include("(0, _pluginApi.withPluginApi)(\"1.0\", api =>")
|
||||
expect(theme_field.javascript_cache.content).to include("alert(settings.name)")
|
||||
expect(theme_field.javascript_cache.content).to include("var a = function a() {}")
|
||||
expect(theme_field.javascript_cache.content).to include("let a = () => {}")
|
||||
|
||||
setting = theme.settings.find { |s| s.name == :name }
|
||||
setting.value = 'bill'
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue