shama / yo-yoify Goto Github PK
View Code? Open in Web Editor NEWTransform choo, yo-yo or bel template strings into pure and fast document calls
Transform choo, yo-yo or bel template strings into pure and fast document calls
I want browserify to output es5 using buble (and for that es5 code to be run through uglifyify, which still doesn't support es6).
So I want source
-> yo-yoify
-> buble
-> uglify
.
Unfortunately, because yo-yoify installs itself in a plugin, yo-yoify always runs last. So either buble eats the tagged template strings (well, barfs on them ), or I tell buble to ignore all template strings (then I get un-compiled ES6 template strings in my output and uglify doesn't work). Even if buble did support template strings, because it would run first yo-yoify would stop working.
Is it possible to keep the source maps?
I tried the babel-plugin
mentioned in the other issue, but even though the source map works - which i wonder if it could also work with just yo-yoify
... it doesn't always find all the e.g bel tagged template literals. goto-bus-stop/babel-plugin-yo-yoify#14
This example would work fine in yo-yo
:
var yo = require('yo-yo')
yo`<div class="${a} ${b}">`
But is turned into
var bel0 = document.createElement("div")
bel0.setAttribute("class", arguments[0] + " ")
return bel0
}(a))
So the second class name is omitted. Of course there are easy work arounds, but it still seems like an error to me.
I only tested this with v1.0.4
so far.
Hey there,
Been using yo-yoify for a time without issue, but just ran into an interesting one while trying to partition my bundles and CDN them.
my bundled file has a relative path to my computer in the require for appendChild
var ac = require('/Users/drippyorifice/Documents/example/node_modules/yo-yoify/lib/appendChild.js')
var ac = require('/node_modules/yo-yoify/lib/appendChild.js')
Wondering if it might be better to split appendChild
into it's own module so that require will just work.
Thoughts?
Can we do this transform with calls to bel.createElement
or just bel...
? Could create another transform module that takes calls to any h
function and turns them into document.createElement
.
Just a theoretical question here:
Thesis: yo-yoifying could actually make the app bigger vs just requiring yo dependencies.
We could assume hundreds of elements worth of transforming. This could actually end up adding size in the end. While it does make it browser friendly, it may increase size quite a bit.
Thoughts?
The following code works with bel
but fails in yo-yoify
:
var html = require('bel')
var props = { foo: 'bar' }
var el = html`<div ${props}></div>`
We should probs look into this
The following input:
<div>
<label></label>
<input></input>
</div>
unexpectedly throws:
Error: multiple root elements must be wrapped in an enclosing tag
Hello, thank you for yo-yoify!
We wrapped yo-yo
in a module we call html
: https://github.com/transloadit/uppy/blob/master/src/core/html.js (choo-style), so we import that in components and call html'<h1>hello</h1>'
that we can switch to virtual-dom
or something if we want to, and just keep the dependency in one place. Do you think this could somehow work with yo-yoify?
I see this https://github.com/shama/yo-yoify/blob/master/index.js#L6, so maybe there could be an option to add custom module names to it? Thanks.
The following test case fails with the error Unterminated string constant (10:18)
.
const html = require('bel')
const req = true
module.exports = () => html`<input type="checkbox" ${req ? 'required' : ''} />`
I've tried required="required"
, removing the trailing space before />
, removing the closing /
, and the combinations of the 3, per the related issue #7. They all throw the same error. I'm using v3.4.1.
Any suggestions?
I think? I browserified a small thing with and without yo-yoify and I saw this in the diff of the outputs.
-var h = require('bel').createElement
+var h = {}.createElement
I know i'm being contrary by trying to use h
with choo and bankai! sorry! I just like it.
I guess I should just require hyperscript
? But then yo-yoifification doesn't happen.
Does this patch need to make it into yo-yoify?
choojs/nanohtml#31
Get that error at this line: https://github.com/davidguttman/overwatch-voter/blob/yo-yoify/client/views/main.js#L30 (see https://github.com/davidguttman/overwatch-voter/blob/yo-yoify/package.json#L7 for setup)
Issue with choo
compatibility?
cc @yoshuawuyts
Everytime I try to yo-yoify yo templates with properties like disabled
or selected
I get the error:
SyntaxError: Unterminated string constant (51:18)
example:
var yo = require("yo-yo")
function button () {
var disabled = "disabled"
return yo`<button ${disabled}>Some Button</button>`
}
in order to make the above work I have to do something like this:
var yo = require("yo-yo")
function button () {
var disabled = "1"
return yo`<button disabled=${disabled}>Some Button</button>`
}
@shama thoughts?
// index-yo.js
var yo = require('yo-yo')
var msg = 'hello!'
var element = yo`<div>${msg}</div>`
// index-bel.js
var bel = require('bel')
var msg = 'hello!'
var element = bel`<div>${msg}</div>`
$ browserify index-yo.js -t yo-yoify | wc -c
35020
$ browserify index-bel.js -t yo-yoify | wc -c
1618
The following examples throw a "bel is not a function" error at runtime. They work fine when not using yo-yoify.
bel('<div>fun stuff</div>')
bel('')
bel``
(Sorry - misread the generated code. My bug - ignore!)
As per #9, it'd be rad if yo-yoify
could modify choo
nodes. Before this can be done, there's two issues blocking it:
require('choo/html')
Then we can start implementing it. Thanks! โจ
I'm seeing yo.update
being undefined when I run this as a global transform. I think the reason is that yo-yo
is doing module.exports = bel
and then module.exports.update = function () {...
, but bel
is getting replaced with 0
, to which attaching update
as a method doesn't work.
@shama what do you think about using {}
instead of 0
as the dummy value? A super quick check has it working fine in my case. Happy to PR if you give the ๐
The question marks there as this appears to be the issue as the source is not changing from using html
The origin of the error occurs here: trainyard/generator-choo#6
We were able to fix our build script by removing yo-yoify: trainyard/generator-choo@4469ee9
The output will contain
yo`<div>...`
and yo
is not a function anymore.
even though, in the problematic required file
yo`<label><input id="staticanalysismodule${i}" type="checkbox" name="staticanalysismodule" index=${i} checked="true">${item.name} (${item.description})</label>`
has been changed to
yo(_templateObject2, i, i, item.name, item.description)
The object yo
still has a .update
method
Example js file:
async function whatever () {
console.log('idc')
}
$ browserify index.js -t yo-yoify
SyntaxError: Unexpected token (1:6) while parsing file: /Users/rahat/Downloads/test/babel-test/index.js
at Parser.pp.raise (/Users/rahat/Downloads/test/babel-test/node_modules/acorn/dist/acorn.js:1745:13)
at Parser.pp.unexpected (/Users/rahat/Downloads/test/babel-test/node_modules/acorn/dist/acorn.js:2264:8)
at Parser.pp.semicolon (/Users/rahat/Downloads/test/babel-test/node_modules/acorn/dist/acorn.js:2243:59)
at Parser.pp.parseExpressionStatement (/Users/rahat/Downloads/test/babel-test/node_modules/acorn/dist/acorn.js:2677:8)
at Parser.pp.parseStatement (/Users/rahat/Downloads/test/babel-test/node_modules/acorn/dist/acorn.js:2462:160)
at Parser.pp.parseTopLevel (/Users/rahat/Downloads/test/babel-test/node_modules/acorn/dist/acorn.js:2379:21)
at parse (/Users/rahat/Downloads/test/babel-test/node_modules/acorn/dist/acorn.js:101:12)
at module.exports (/Users/rahat/Downloads/test/babel-test/node_modules/falafel/index.js:22:15)
at DestroyableTransform.end [as _flush] (/Users/rahat/Downloads/test/babel-test/node_modules/yo-yoify/index.js:55:13)
at DestroyableTransform.<anonymous> (/Users/rahat/Downloads/test/babel-test/node_modules/readable-stream/lib/_stream_transform.js:115:49)
Maybe using a newer version of acorn might help?
Running yo-yoify as a global transform on code that uses https://github.com/yoshuawuyts/nanocomponent ends up with an absolute path to lib/appendChild.js
, even after uglifying.
Code in nanocomponent:
proxy = html`<div></div>`
ends up in bundle as
proxy = function () {
var ac = require('/home/myuser/exampleproject/node_modules/yo-yoify/lib/appendChild.js');
var bel0 = document.createElement('div');
return bel0;
}();
Even after applying -g uglifyify
and piping to | uglifyjs --compress --mangle
the absolute path is still there.
And ac
isn't even called in this case, because the thing sent to yoyo doesn't have any children.
Looking at the code, I guess it's because of __dirname
here: https://github.com/shama/yo-yoify/blob/master/index.js#L230
Any suggestions on how to remove full path from resulting bundle?
The for
attribute on <label>
elements is set as htmlFor
instead of for
.
Actual: labelElement.setAttribute("htmlFor", "abc")
Expected: either labelElement.htmlFor = "abc"
or labelElement.setAttribute("for", "abc")
Bel 5 added whitespace collapsing for nodes that don't need it - yo-yoify should follow.
Just FYI. Not made by me. Here: https://www.npmjs.com/package/babel-plugin-yo-yoify. Solves same problems โ coverts template strings to faster document
calls and solves Function.caller
issue. Plus allows to easily transpile individual modules, as opposed to bundling with Browserify, like I needed here choojs/nanohtml#65. For those using Babel, this is an optimal solution, I think.
Thank you for your work!
This lib has been replaced by https://github.com/choojs/nanohtml
It appears this require statement fails to resolve the appendChild.js file correctly when using Windows. I believe this is an issue with the path.resolve
statement and that Windows uses \
instead of /
as path separators.
Stack trace. Tested on Windows 7 and Node 6.3.0.
As commented on PR #45, some layouts are screwed up now (I should have opened an issue in the first place). Consider this:
<em>Yes</em>
<span>yo</span>
This should render as "Yes yo". With the change from #45 it becomes "Yesyo".
You can replace multiple whitespace characters with a single blank though. That'd be fine.
One of the cool parts of base-element was interoperability. With yo-yo/bel
elements, we can effectively do the same thing by appending the element as the component mounts. As they are just standalone native DOM elements:
componentDidMount: function () {
React.findDOMNode(this).appendChild(belElement)
}
But we can do better with yo-yo
. I've created an experimental interop
branch that provides an option to switch out what yo-yoify
renders to. So instead of creating raw document.createElement()
calls it will generate React.createElement()
or vdom.h()
calls.
So effectively with this plugin a user could integrate a yo-yo/bel
element like so:
// node_modules/bel-element/index.js
var yo = require('yo-yo')
module.exports = function (attrs) {
return yo`<div>Hello ${attrs.label}!</div>`
}
// app.jsx
var BelElement = require('bel-element')
ReactDOM.render(<BelElement label="World" />, document.body)
If it works out, I'll likely break them into their own transforms. My ultimate personal goal is interop with Ember so I can start using yo-yo
elements the YNAB web app:
The main problem is yo.update
is not so easily transformable. I need to figure out if it's possible to implement a comparable thing to that in each.
This code:
const canvas = yo`<canvas style="width: ${width}px; height: ${height}px;" />`;
... Works without yo-yoify, but with yo-yoify the string is truncated after 'height:':
<canvas style="width: 300px; height: "></canvas>
(Yo-yoify turned it into this):
const canvas = (function () {
var ac = require('/Users/josephg/src/b/steamdance/node_modules/yo-yoify/lib/appendChild.js')
var bel0 = document.createElement("canvas")
bel0.setAttribute("style", "width: " + arguments[0] + "px; height: ")
return bel0
}(width));
examples are like thousand words
const cap = require('lodash/capitalize');
bel`<p>${cap('hello')} ${cap('world')}!</p>`
will shout HelloWorld!
with yo-yoify but Hello World!
with bel
This come from https://github.com/shama/yo-yoify/blob/master/lib/appendChild.js#L15
This example will cause it to break:
var className = 'test'
var element = yo`<div class="${className} broken">dang</div>`
This is because the transform is only expecting attributes to either be a string or template expression but not both.
The work around for now is:
var className = 'test'
var element = yo`<div class="${className + ' broken'}">dang</div>`
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.