DEV: Add gjs support for themes (#23473)
This commit is contained in:
parent
2ec7455c89
commit
5a904949b2
|
@ -75,4 +75,3 @@ openapi/*
|
|||
|
||||
# Cached License Data Files
|
||||
/.licenses
|
||||
/app/assets/javascripts/compiled-js-processor.js
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import I18n from "I18n";
|
||||
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||
|
||||
registerUnbound("i18n", (key, params) => I18n.t(key, params));
|
||||
export default function i18n(key, params) {
|
||||
return I18n.t(key, params);
|
||||
}
|
||||
registerUnbound("i18n", i18n);
|
||||
|
||||
registerUnbound("i18n-yes-no", (value, params) =>
|
||||
I18n.t(value ? "yes_value" : "no_value", params)
|
||||
);
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
"ember-test-selectors": "^6.0.0",
|
||||
"eslint": "^8.50.0",
|
||||
"eslint-plugin-qunit": "^8.0.0",
|
||||
"float-kit": "1.0.0",
|
||||
"html-entities": "^2.4.0",
|
||||
"imports-loader": "^4.0.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
|
@ -101,7 +102,6 @@
|
|||
"sass": "^1.68.0",
|
||||
"select-kit": "1.0.0",
|
||||
"sinon": "^16.0.0",
|
||||
"float-kit": "1.0.0",
|
||||
"source-map": "^0.7.4",
|
||||
"terser": "^5.20.0",
|
||||
"truth-helpers": "1.0.0",
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
"discourse-widget-hbs",
|
||||
"ember-cli-progress-ci",
|
||||
"ember-production-deprecations",
|
||||
"float-kit",
|
||||
"pretty-text",
|
||||
"select-kit",
|
||||
"float-kit",
|
||||
"theme-transpiler",
|
||||
"truth-helpers",
|
||||
"wizard"
|
||||
],
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
diff --git a/node_modules/content-tag/content_tag.js b/node_modules/content-tag/content_tag.js
|
||||
index 6ff5969..38915da 100644
|
||||
--- a/node_modules/content-tag/content_tag.js
|
||||
+++ b/node_modules/content-tag/content_tag.js
|
||||
@@ -448,11 +448,17 @@ module.exports.__wbindgen_memory = function() {
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
-const path = require('path').join(__dirname, 'content_tag_bg.wasm');
|
||||
-const bytes = require('fs').readFileSync(path);
|
||||
-
|
||||
-const wasmModule = new WebAssembly.Module(bytes);
|
||||
-const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
|
||||
-wasm = wasmInstance.exports;
|
||||
-module.exports.__wasm = wasm;
|
||||
+// Check for nodejs environment
|
||||
+if (process.version) {
|
||||
+ const path = require('path').join(__dirname, 'content_tag_bg.wasm');
|
||||
+ const bytes = require('fs').readFileSync(path);
|
||||
+
|
||||
+ const wasmModule = new WebAssembly.Module(bytes);
|
||||
+ const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
|
||||
+ wasm = wasmInstance.exports;
|
||||
+} else {
|
||||
+ const load = require('./content_tag_bg.wasm').default;
|
||||
+ wasm = load(imports);
|
||||
+ module.exports.__wasm = wasm;
|
||||
+}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
// See: https://esbuild.github.io/plugins/#webassembly-plugin
|
||||
|
||||
const esbuild = require("esbuild");
|
||||
const path = require("node:path");
|
||||
const fs = require("node:fs");
|
||||
const { argv } = require("node:process");
|
||||
|
||||
let wasmPlugin = {
|
||||
name: "wasm",
|
||||
|
||||
setup(build) {
|
||||
build.onResolve({ filter: /\.wasm$/ }, (args) => {
|
||||
if (args.namespace === "wasm-stub") {
|
||||
return {
|
||||
path: args.path,
|
||||
namespace: "wasm-binary",
|
||||
};
|
||||
}
|
||||
|
||||
if (args.resolveDir === "") {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
path: path.isAbsolute(args.path)
|
||||
? args.path
|
||||
: path.join(args.resolveDir, args.path),
|
||||
namespace: "wasm-stub",
|
||||
};
|
||||
});
|
||||
|
||||
build.onLoad({ filter: /.*/, namespace: "wasm-stub" }, async (args) => {
|
||||
return {
|
||||
contents: `import wasm from ${JSON.stringify(args.path)};
|
||||
export default (imports) => {
|
||||
const wasmModule = new WebAssembly.Module(wasm);
|
||||
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
|
||||
return wasmInstance.exports;
|
||||
};`,
|
||||
};
|
||||
});
|
||||
|
||||
build.onLoad({ filter: /.*/, namespace: "wasm-binary" }, async (args) => {
|
||||
return {
|
||||
contents: await fs.promises.readFile(args.path),
|
||||
loader: "binary",
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
esbuild
|
||||
.build({
|
||||
logLevel: "warning",
|
||||
bundle: true,
|
||||
minify: true,
|
||||
alias: {
|
||||
util: "./app/assets/javascripts/node_modules/@zxing/text-encoding",
|
||||
},
|
||||
define: {
|
||||
process: `{ "env": {} }`,
|
||||
},
|
||||
external: ["fs", "path"],
|
||||
entryPoints: ["./app/assets/javascripts/theme-transpiler/transpiler.js"],
|
||||
outfile: argv[2],
|
||||
plugins: [wasmPlugin],
|
||||
})
|
||||
.then(() => {});
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "theme-transpiler",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"description": "Uses esbuild to create a 'theme transpiler' bundle for loading into mini-racer",
|
||||
"author": "Discourse",
|
||||
"license": "GPL-2.0-only",
|
||||
"keywords": [],
|
||||
"dependencies": {
|
||||
"@babel/standalone": "^7.23.1",
|
||||
"@zxing/text-encoding": "^0.9.0",
|
||||
"babel-plugin-ember-template-compilation": "^2.2.0",
|
||||
"content-tag": "^1.1.0",
|
||||
"discourse-common": "1.0.0",
|
||||
"discourse-widget-hbs": "1.0.0",
|
||||
"ember-cli-htmlbars": "^6.3.0",
|
||||
"ember-source": "~3.28.12",
|
||||
"ember-this-fallback": "^0.3.1",
|
||||
"handlebars": "^4.7.8",
|
||||
"path-browserify": "^1.0.1",
|
||||
"polyfill-crypto.getrandomvalues": "^1.0.0",
|
||||
"terser": "^5.20.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "16.* || >= 18",
|
||||
"npm": "please-use-yarn",
|
||||
"yarn": ">= 1.21.1"
|
||||
}
|
||||
}
|
|
@ -26,6 +26,13 @@ import RawHandlebars from "discourse-common/addon/lib/raw-handlebars";
|
|||
import { WidgetHbsCompiler } from "discourse-widget-hbs/lib/widget-hbs-compiler";
|
||||
import EmberThisFallback from "ember-this-fallback";
|
||||
|
||||
// A sub-dependency of content-tag (getrandom) needs `getRandomValues`
|
||||
// so we polyfill it
|
||||
import getRandomValues from "polyfill-crypto.getrandomvalues";
|
||||
globalThis.crypto = { getRandomValues };
|
||||
|
||||
import { Preprocessor } from "content-tag";
|
||||
|
||||
const thisFallbackPlugin = EmberThisFallback._buildPlugin({
|
||||
enableLogging: false,
|
||||
isTheme: true,
|
||||
|
@ -60,10 +67,10 @@ function buildEmberTemplateManipulatorPlugin(themeId) {
|
|||
};
|
||||
}
|
||||
|
||||
function buildTemplateCompilerBabelPlugins({ themeId }) {
|
||||
function buildTemplateCompilerBabelPlugins({ extension, themeId }) {
|
||||
const compiler = { precompile };
|
||||
|
||||
if (themeId) {
|
||||
if (themeId && extension !== "gjs") {
|
||||
compiler.precompile = (src, opts) => {
|
||||
return precompile(src, {
|
||||
...opts,
|
||||
|
@ -116,10 +123,16 @@ globalThis.compileRawTemplate = function (source, themeId) {
|
|||
};
|
||||
|
||||
globalThis.transpile = function (source, options = {}) {
|
||||
const { moduleId, filename, skipModule, themeId, commonPlugins } = options;
|
||||
const plugins = [];
|
||||
const { moduleId, filename, extension, skipModule, themeId, commonPlugins } =
|
||||
options;
|
||||
|
||||
plugins.push(...buildTemplateCompilerBabelPlugins({ themeId }));
|
||||
if (extension === "gjs") {
|
||||
const preprocessor = new Preprocessor();
|
||||
source = preprocessor.process(source);
|
||||
}
|
||||
|
||||
const plugins = [];
|
||||
plugins.push(...buildTemplateCompilerBabelPlugins({ extension, themeId }));
|
||||
if (moduleId && !skipModule) {
|
||||
plugins.push(["transform-modules-amd", { noInterop: true }]);
|
||||
}
|
|
@ -119,25 +119,12 @@
|
|||
lodash.debounce "^4.0.8"
|
||||
resolve "^1.14.2"
|
||||
|
||||
"@babel/helper-environment-visitor@^7.22.20":
|
||||
"@babel/helper-environment-visitor@^7.22.20", "@babel/helper-environment-visitor@^7.22.5":
|
||||
version "7.22.20"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167"
|
||||
integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==
|
||||
|
||||
"@babel/helper-environment-visitor@^7.22.5":
|
||||
version "7.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98"
|
||||
integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==
|
||||
|
||||
"@babel/helper-function-name@^7.22.5":
|
||||
version "7.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be"
|
||||
integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==
|
||||
dependencies:
|
||||
"@babel/template" "^7.22.5"
|
||||
"@babel/types" "^7.22.5"
|
||||
|
||||
"@babel/helper-function-name@^7.23.0":
|
||||
"@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0":
|
||||
version "7.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759"
|
||||
integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==
|
||||
|
@ -233,16 +220,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f"
|
||||
integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.22.20":
|
||||
"@babel/helper-validator-identifier@^7.22.20", "@babel/helper-validator-identifier@^7.22.5":
|
||||
version "7.22.20"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0"
|
||||
integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.22.5":
|
||||
version "7.22.15"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz#601fa28e4cc06786c18912dca138cec73b882044"
|
||||
integrity sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==
|
||||
|
||||
"@babel/helper-validator-option@^7.22.15":
|
||||
version "7.22.15"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040"
|
||||
|
@ -1225,7 +1207,7 @@
|
|||
ember-cli-version-checker "^5.1.2"
|
||||
semver "^7.3.5"
|
||||
|
||||
"@embroider/addon-shim@^1.0.0":
|
||||
"@embroider/addon-shim@^1.0.0", "@embroider/addon-shim@^1.8.3", "@embroider/addon-shim@^1.8.4":
|
||||
version "1.8.6"
|
||||
resolved "https://registry.yarnpkg.com/@embroider/addon-shim/-/addon-shim-1.8.6.tgz#b676991b4fa32c3a98dc7db7dc6cd655029c3f09"
|
||||
integrity sha512-siC9kP78uucEbpDcVyxjkwa76pcs5rVzDVpWO4PDc9EAXRX+pzmUuSTLAK3GztUwx7/PWhz1BenAivqdSvSgfg==
|
||||
|
@ -1234,15 +1216,6 @@
|
|||
broccoli-funnel "^3.0.8"
|
||||
semver "^7.3.8"
|
||||
|
||||
"@embroider/addon-shim@^1.8.3", "@embroider/addon-shim@^1.8.4":
|
||||
version "1.8.5"
|
||||
resolved "https://registry.yarnpkg.com/@embroider/addon-shim/-/addon-shim-1.8.5.tgz#c0aae417f9583058f40550f206fc53444e325f11"
|
||||
integrity sha512-pDgpdTsC9i/+5hHziygK5VIZc64OG8bupiqL0OxJp+bnINURalHMbu5B3Gikq/a0QIvMPzDFWzKxIZCBpeiHkg==
|
||||
dependencies:
|
||||
"@embroider/shared-internals" "^2.1.0"
|
||||
broccoli-funnel "^3.0.8"
|
||||
semver "^7.3.8"
|
||||
|
||||
"@embroider/babel-loader-9@3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@embroider/babel-loader-9/-/babel-loader-9-3.1.0.tgz#eae859b82215fc7ee0e69ec867fda7b4eb4de2c0"
|
||||
|
@ -1347,7 +1320,7 @@
|
|||
resolve "^1.20.0"
|
||||
semver "^7.3.2"
|
||||
|
||||
"@embroider/shared-internals@2.5.0", "@embroider/shared-internals@^2.0.0", "@embroider/shared-internals@^2.1.0", "@embroider/shared-internals@^2.2.3":
|
||||
"@embroider/shared-internals@2.5.0", "@embroider/shared-internals@^2.0.0", "@embroider/shared-internals@^2.2.3":
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-2.5.0.tgz#4a0b5127c589718fae60fc22f81374ed558b944a"
|
||||
integrity sha512-7qzrb7GVIyNqeY0umxoeIvjDC+ay1b+wb2yCVuYTUYrFfLAkLEy9FNI3iWCi3RdQ9OFjgcAxAnwsAiPIMZZ3pQ==
|
||||
|
@ -2126,6 +2099,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
|
||||
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
|
||||
|
||||
"@zxing/text-encoding@^0.9.0":
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b"
|
||||
integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==
|
||||
|
||||
a11y-dialog@8.0.2:
|
||||
version "8.0.2"
|
||||
resolved "https://registry.yarnpkg.com/a11y-dialog/-/a11y-dialog-8.0.2.tgz#08b8315d500b7f8c4200ec37d3a0fd15ccd54738"
|
||||
|
@ -4174,6 +4152,11 @@ content-disposition@0.5.4:
|
|||
dependencies:
|
||||
safe-buffer "5.2.1"
|
||||
|
||||
content-tag@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/content-tag/-/content-tag-1.1.0.tgz#fcef4bdcf1850f9b67bf0b6f7aee217c6d7ea9fa"
|
||||
integrity sha512-bktivDORs9M890KwVKrIONYvHhwshfgF4b1G/TFPrjH12Ag2GDiSdxVHqIzMxWZ297VgIRPSImURlpcOzJP/LQ==
|
||||
|
||||
content-type@~1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
|
||||
|
@ -8115,6 +8098,11 @@ merge2@^1.2.3, merge2@^1.3.0:
|
|||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||
|
||||
mersenne-twister@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a"
|
||||
integrity sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA==
|
||||
|
||||
message-bus-client@^4.3.8:
|
||||
version "4.3.8"
|
||||
resolved "https://registry.yarnpkg.com/message-bus-client/-/message-bus-client-4.3.8.tgz#5ee23c03236b250b13613034764a87881c350d4e"
|
||||
|
@ -8832,6 +8820,11 @@ patch-package@^8.0.0:
|
|||
tmp "^0.0.33"
|
||||
yaml "^2.2.2"
|
||||
|
||||
path-browserify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
|
||||
integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
|
||||
|
||||
path-exists@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
|
||||
|
@ -8939,6 +8932,13 @@ pkg-up@^3.1.0:
|
|||
dependencies:
|
||||
find-up "^3.0.0"
|
||||
|
||||
polyfill-crypto.getrandomvalues@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/polyfill-crypto.getrandomvalues/-/polyfill-crypto.getrandomvalues-1.0.0.tgz#5c95602976ebb6155b163cb65d77b9eede3b61a4"
|
||||
integrity sha512-GIkU6bg4auRnDFOqUNit7eLn9hzznrJU1CGFuivQzDeVp4Ys8cY4OY6GhAdndJwo4jryz5cJyjg9ELhvQjdrtw==
|
||||
dependencies:
|
||||
mersenne-twister "^1.0.1"
|
||||
|
||||
portfinder@^1.0.32:
|
||||
version "1.0.32"
|
||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81"
|
||||
|
|
|
@ -6,7 +6,7 @@ require "json_schemer"
|
|||
class Theme < ActiveRecord::Base
|
||||
include GlobalPath
|
||||
|
||||
BASE_COMPILER_VERSION = 75
|
||||
BASE_COMPILER_VERSION = 76
|
||||
|
||||
attr_accessor :child_components
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@ class ThemeField < ActiveRecord::Base
|
|||
js_compiler.append_module(
|
||||
js,
|
||||
"discourse/initializers/#{initializer_name}",
|
||||
"js",
|
||||
include_variables: true,
|
||||
)
|
||||
rescue ThemeJavascriptCompiler::CompileError => ex
|
||||
|
@ -276,6 +277,7 @@ class ThemeField < ActiveRecord::Base
|
|||
js_compiler.append_module(
|
||||
js,
|
||||
"discourse/pre-initializers/theme-#{theme_id}-translations",
|
||||
"js",
|
||||
include_variables: false,
|
||||
)
|
||||
rescue ThemeTranslationParser::InvalidYaml => e
|
||||
|
|
|
@ -49,9 +49,9 @@ class DiscourseJsProcessor
|
|||
{ data: data }
|
||||
end
|
||||
|
||||
def self.transpile(data, root_path, logical_path, theme_id: nil)
|
||||
def self.transpile(data, root_path, logical_path, theme_id: nil, extension: nil)
|
||||
transpiler = Transpiler.new(skip_module: skip_module?(data))
|
||||
transpiler.perform(data, root_path, logical_path, theme_id: theme_id)
|
||||
transpiler.perform(data, root_path, logical_path, theme_id: theme_id, extension: extension)
|
||||
end
|
||||
|
||||
def self.should_transpile?(filename)
|
||||
|
@ -98,8 +98,14 @@ class DiscourseJsProcessor
|
|||
end
|
||||
|
||||
class Transpiler
|
||||
JS_PROCESSOR_PATH =
|
||||
Rails.env.production? ? "tmp/js-processor.js" : "tmp/js-processor/#{Process.pid}.js"
|
||||
TRANSPILER_PATH =
|
||||
(
|
||||
if Rails.env.production?
|
||||
"tmp/theme-transpiler.js"
|
||||
else
|
||||
"tmp/theme-transpiler/#{Process.pid}.js"
|
||||
end
|
||||
)
|
||||
|
||||
@mutex = Mutex.new
|
||||
@ctx_init = Mutex.new
|
||||
|
@ -109,19 +115,13 @@ class DiscourseJsProcessor
|
|||
@mutex
|
||||
end
|
||||
|
||||
def self.generate_js_processor
|
||||
def self.build_theme_transpiler
|
||||
Discourse::Utils.execute_command(
|
||||
"yarn",
|
||||
"--silent",
|
||||
"esbuild",
|
||||
"--log-level=warning",
|
||||
"--bundle",
|
||||
"--external:fs",
|
||||
"--define:process='{\"env\":{}}'",
|
||||
"app/assets/javascripts/js-processor.js",
|
||||
"--outfile=#{JS_PROCESSOR_PATH}",
|
||||
"node",
|
||||
"app/assets/javascripts/theme-transpiler/build.js",
|
||||
TRANSPILER_PATH,
|
||||
)
|
||||
JS_PROCESSOR_PATH
|
||||
TRANSPILER_PATH
|
||||
end
|
||||
|
||||
def self.create_new_context
|
||||
|
@ -135,10 +135,10 @@ class DiscourseJsProcessor
|
|||
|
||||
# Theme template AST transformation plugins
|
||||
if Rails.env.development? || Rails.env.test?
|
||||
@processor_mutex.synchronize { generate_js_processor }
|
||||
@processor_mutex.synchronize { build_theme_transpiler }
|
||||
end
|
||||
|
||||
ctx.eval(File.read(JS_PROCESSOR_PATH), filename: "js-processor.js")
|
||||
ctx.eval(File.read(TRANSPILER_PATH), filename: "theme-transpiler.js")
|
||||
|
||||
ctx
|
||||
end
|
||||
|
@ -190,7 +190,7 @@ class DiscourseJsProcessor
|
|||
@skip_module = skip_module
|
||||
end
|
||||
|
||||
def perform(source, root_path = nil, logical_path = nil, theme_id: nil)
|
||||
def perform(source, root_path = nil, logical_path = nil, theme_id: nil, extension: nil)
|
||||
self.class.v8_call(
|
||||
"transpile",
|
||||
source,
|
||||
|
@ -198,6 +198,7 @@ class DiscourseJsProcessor
|
|||
skipModule: @skip_module,
|
||||
moduleId: module_name(root_path, logical_path),
|
||||
filename: logical_path || "unknown",
|
||||
extension: extension,
|
||||
themeId: theme_id,
|
||||
commonPlugins: DISCOURSE_COMMON_BABEL_PLUGINS,
|
||||
},
|
||||
|
|
|
@ -309,16 +309,16 @@ task "assets:precompile:compress_js": "environment" do
|
|||
end
|
||||
end
|
||||
|
||||
task "assets:precompile:js_processor": "environment" do
|
||||
path = DiscourseJsProcessor::Transpiler.generate_js_processor
|
||||
puts "Compiled js-processor: #{path}"
|
||||
task "assets:precompile:theme_transpiler": "environment" do
|
||||
path = DiscourseJsProcessor::Transpiler.build_theme_transpiler
|
||||
puts "Compiled theme-transpiler: #{path}"
|
||||
end
|
||||
|
||||
# Run these tasks **before** Rails' "assets:precompile" task
|
||||
task "assets:precompile": %w[
|
||||
assets:precompile:before
|
||||
maxminddb:refresh
|
||||
assets:precompile:js_processor
|
||||
assets:precompile:theme_transpiler
|
||||
]
|
||||
|
||||
# Run these tasks **after** Rails' "assets:precompile" task
|
||||
|
|
|
@ -220,7 +220,7 @@ task "db:migrate" => %w[
|
|||
load_config
|
||||
environment
|
||||
set_locale
|
||||
assets:precompile:js_processor
|
||||
assets:precompile:theme_transpiler
|
||||
] do |_, args|
|
||||
DistributedMutex.synchronize(
|
||||
"db_migration",
|
||||
|
|
|
@ -169,8 +169,8 @@ class ThemeJavascriptCompiler
|
|||
tree.each_pair do |filename, content|
|
||||
module_name, extension = filename.split(".", 2)
|
||||
module_name = "test/#{module_name}" if for_tests
|
||||
if extension == "js"
|
||||
append_module(content, module_name)
|
||||
if extension == "js" || extension == "gjs"
|
||||
append_module(content, module_name, extension)
|
||||
elsif extension == "hbs"
|
||||
append_ember_template(module_name, content)
|
||||
elsif extension == "hbr"
|
||||
|
@ -232,15 +232,15 @@ class ThemeJavascriptCompiler
|
|||
@output_tree << [filename, script + "\n"]
|
||||
end
|
||||
|
||||
def append_module(script, name, include_variables: true)
|
||||
def append_module(script, name, extension, include_variables: true)
|
||||
original_filename = name
|
||||
name = "discourse/theme-#{@theme_id}/#{name}"
|
||||
|
||||
script = "#{theme_settings}#{script}" if include_variables
|
||||
transpiler = DiscourseJsProcessor::Transpiler.new
|
||||
@output_tree << ["#{original_filename}.js", <<~JS]
|
||||
@output_tree << ["#{original_filename}.#{extension}", <<~JS]
|
||||
if ('define' in window) {
|
||||
#{transpiler.perform(script, "", name, theme_id: @theme_id).strip}
|
||||
#{transpiler.perform(script, "", name, theme_id: @theme_id, extension: extension).strip}
|
||||
}
|
||||
JS
|
||||
rescue MiniRacer::RuntimeError, DiscourseJsProcessor::TranspileError => ex
|
||||
|
|
|
@ -233,4 +233,27 @@ RSpec.describe ThemeJavascriptCompiler do
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "ember-template-imports" do
|
||||
it "applies its transforms" do
|
||||
compiler.append_tree({ "discourse/components/my-component.gjs" => <<~JS })
|
||||
import Component from "@glimmer/component";
|
||||
|
||||
export default class MyComponent extends Component {
|
||||
<template>
|
||||
{{this.value}}
|
||||
</template>
|
||||
|
||||
value = "foo";
|
||||
}
|
||||
JS
|
||||
|
||||
expect(compiler.raw_content).to include(
|
||||
"define(\"discourse/theme-1/discourse/components/my-component\", [\"exports\",",
|
||||
)
|
||||
expect(compiler.raw_content).to include("_defineProperty(this, \"value\", \"foo\");")
|
||||
expect(compiler.raw_content).to include("setComponentTemplate")
|
||||
expect(compiler.raw_content).to include("createTemplateFactory")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,11 +6,11 @@ RSpec.describe "assets:precompile" do
|
|||
Discourse::Application.load_tasks
|
||||
end
|
||||
|
||||
describe "assets:precompile:js_processor" do
|
||||
describe "assets:precompile:theme_transpiler" do
|
||||
it "compiles the js processor" do
|
||||
out = capture_stdout { Rake::Task["assets:precompile:js_processor"].invoke }
|
||||
out = capture_stdout { Rake::Task["assets:precompile:theme_transpiler"].invoke }
|
||||
|
||||
expect(out).to match(%r{Compiled js-processor: tmp/js-processor})
|
||||
expect(out).to match(%r{Compiled theme-transpiler: tmp/theme-transpiler})
|
||||
path = out.match(/: (.+)/)[1]
|
||||
expect(File.exist?(path)).to eq(true)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue