Typescript JSX output is incompatible with html tags in regex expressions
Hello! I've recently started using Surplus and it's really great! But I think I've found a bug in the compiler:
// controller.ts
export function update(text : string) : string {
return text.replace(/<br>+/g, '\n');
}
// view.tsx
export const TestEditor = () => {
const text = S.data('Hello'),
onkeyup = ({ target: { value } } : any) => {
text(clean(value));
};
return (
<div>
Text is: {text()}
<input value={text()} onKeyUp={onkeyup} />
</div>
);
}
// main.ts
S.root(() => {
const testEditor = TestEditor();
document.body.insertAdjacentElement('afterbegin', testEditor);
});
This produces the error:
ERROR in ./public/js/controller.ts
Module build failed: Error: element missing close tag at line 19 col 25: ``
+/g, '\n');}
''
at ERR (/node_modules/surplus/compiler/index.js:354:15)
at jsxElement (/node_modules/surplus/compiler/index.js:162:17)
at program (/node_modules/surplus/compiler/index.js:91:31)
at parse (/node_modules/surplus/compiler/index.js:83:12)
at Object.compile (/node_modules/surplus/compiler/index.js:1444:45)
at Object.preprocess (/node_modules/surplus-loader/index.js:7:33)
@ ./public/js/main.ts 3:7-49
I think the problem lies in the surplus-loader. Compiling the regex with Babel works fine when I test that! Edit: I'm running the 0.5 beta of surplus-loader.
Yep, this is a bug. Unfortunately, it happens to show a weakness of the current compiler architecture. Currently, Surplus correctly handles text that looks like it might be a tag when it's inside strings or comments -- "<br>" or /* <br> */ -- but it happens to be harder to tell if you're inside a regular expression in the javascript syntax. For instance /<br>/g should parse as a regular expression but 1/<br>/g should not (in the context of the preceding 1, the slashes become division operators).
If it helps, you can work around the issue by just making a semantically meaningless change that separates the '<' from the first character of the tag, so convert /<br>/g to /[b]r/g or /(b)r/g.
I'm likely going to move to a more established JSX parser, like acorn, in the future, which would resolve this issue.
Aha, I see! The workaround solved the problem, thanks for the tip!
Hi, I also faced with this issue (surplus compiler not always properly parses JavaScript regular expressions). Unfortunately I cannot change the RegExp because it is in 3rd party library. If you try to use "path-parser" npm package together with Suerplus (I am using parcel bundler) then you will get this error:
C:\csv\s-and-n\surplus-test\node_modules\path-parser\dist\es\path-parser.js: bad element name at line 33 col 51: ``<(.+?)>)?/, regex: fu''
at ERR (C:\csv\s-and-n\surplus-test\node_modules\surplus\compiler\index.js:373:19)
at jsxElement (C:\csv\s-and-n\surplus-test\node_modules\surplus\compiler\index.js:121:17)
at program (C:\csv\s-and-n\surplus-test\node_modules\surplus\compiler\index.js:91:35)
at parse (C:\csv\s-and-n\surplus-test\node_modules\surplus\compiler\index.js:83:16)
at Object.compile (C:\csv\s-and-n\surplus-test\node_modules\surplus\compiler\index.js:1512:49)
at JSAsset.pretransform (C:\csv\s-and-n\surplus-test\node_modules\parcel-plugin-surplus\lib\js-asset.js:8:37)
at JSAsset.process (C:\csv\s-and-n\surplus-test\node_modules\parcel-bundler\src\Asset.js:205:18)
at <anonymous>
And the source code in "path-parser" is:
var rules = [
{
name: 'url-parameter',
pattern: /^:([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,
regex: function (match) {
return new RegExp(defaultOrConstrained(match[2]));
}
},
{
Do you have any suggestions on this? You had a great plan to migrate surplus compiler to acron, any progress here?
By the way, thank you for a so great library.