bublejs / buble Goto Github PK
View Code? Open in Web Editor NEWHome Page: https://buble.surge.sh
License: MIT License
Home Page: https://buble.surge.sh
License: MIT License
➜ 2017-11-07-tax-table git:(master) ✗ yarn add buble
➜ 2017-11-07-tax-table git:(master) ✗ node_modules/.bin/buble public/_assets/build-es6.js
module.js:529
throw err;
^
Error: Cannot find module 'chalk'
at Function.Module._resolveFilename (module.js:527:15)
at Function.Module._load (module.js:476:23)
at Module.require (module.js:568:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/Users/207342/Desktop/2017-11-07-tax-table/node_modules/buble/bin/handleError.js:1:75)
at Module._compile (module.js:624:30)
at Object.Module._extensions..js (module.js:635:10)
at Module.load (module.js:545:32)
at tryModuleLoad (module.js:508:12)
at Function.Module._load (module.js:500:3)
➜ 2017-11-07-tax-table git:(master) ✗ yarn add chalk
➜ 2017-11-07-tax-table git:(master) ✗ node_modules/.bin/buble public/_assets/build-es6.js
// works now
This is with version 0.17.0
.
It looks like chalk
is currently in devDependencies
; not sure if it being called inadvertently or if it should be in dependencies
.
buble 0.18.0
class A {
b (xy/*:[number,number]*/) {
}
}
is translated to this
var A = function A () {};
A.prototype.b = function b (xy/*:[numbernumber]*/) {
};
Note that the comma from /*:[number,number]*/
gets removed.
(The comment is an annotation for flow.)
Not a big problem, but I thought I better let you know about it.
I added my own support number based on ie:10
, so it looks like this:
10: 0b1000000000000000000000000000010,
I wanted to leave classes alone, to compile those with Babel afterword.
It turns out, Buble is modifying the classes, and putting this
before super()
which turns into an error in Babel because this
isn't allowed to be used before super()
. The output look like this:
constructor (options) {
var this$1 = this;
if ( options === void 0 ) options = {};
super(options);
// use options
}
Oddly, this$1
is never used for anything. Not sure why Buble would put that there.
Both 0B
and `0O' are valid base prefixes. Example:
0B01100 === 0O14
In ECMAScript 2015, Automatic Semicolon Insertion adds a semicolon at the end of a do-while statement if the semicolon is missing. This change aligns the specification with the actual behaviour of most existing implementations.
See ASI spec. This if for example not implemented by IE 9, so transpiling it could actually provide some benefit.
Bublé parses [ ...Array(length) ]
as [].concat( Array(length) )
witch is not equivalent.
Spreading Array
factory returns an array with undefined values.
[ ...Array(2) ] === [undefined, undefined]
[ ...Array(2) ].length === 2
Concating Array
factory returns an empty array with defined length.
[].concat( Array(2) ) === []
[].concat( Array(2) ).length === 2
[].concat( Array(length) )
Array.apply( null, Array(length) )
OR
Array.prototype.concat.apply( [], Array(length) )
OR
[].concat.apply( [], Array(length) )
JSX has a new syntax for fragments:
render() {
return (
<>
<ChildA />
<ChildB />
<ChildC />
</>
);
}
Is this something you want to support in Buble?
(Search didn't turn up anything useful)
Buble doesn't currently support Array.fill
as a feature, I'm curious as to the rationale behind this? I recently ran into an issue where my code broke because of Array.fill not being transpiled into compatible code with my browser environment.
My code looked like this:
// constant to show example
const count = 10;
const segments = Array(count - 1).fill(0);
Obviously my usage of fill here is to populate a dynamically determined array length with dummy values so I can eventually populate it using map
, as sparse arrays are ignored by array methods.
Turns out, this actually worked with buble in its place
const count = 10
const segments = Array(...Array(count - 1)).map(() => 0);
Which is effectively Array.apply(null, Array(count -1)).map(function(){ return 0 });
I understand it's an additional compilation step if you were to transpile it from fill(0)
to use the spread operator, so I'm aware that that might be a limitation.
There might be something I'm missing here, but is there a reason we can't statically analyze Array.fill
calls to map to an Array.apply
call followed by .map()
which would pass in the current array being worked on?
e.g. if I have some arbitrary array of values and I want to call fill
[1, 2, true, false, "lol"].fill(2) // -> [2, 2, 2, 2, 2]
couldn't it just transpile into this?
let a = [1, 2, true, false, "lol"]
Array.apply(a, Array(a.length)).map(() => 2);
This is a fill that should work even for sparse arrays.
Note: The longer I write this the more I become aware that yes, fill
doesn't always have an arity of one argument, so supporting filling subsections of the array might take more finesse or be more complicated, but I figured it was worth starting a dialog.
Buble compiles super()
calls to something like ParentClass.call(this)
.
This causes any and all Custom Elements (v1) to not work because they require the use of new
(ES2015 classes), with an error like the following in Chrome:
Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function
For example, see this output.
Try to run the output code in your browser, and you'll get the error.
Hmm, I don't think this is a bug with Buble. It's just not possible to compile anything for Custom Elements v1 to ES5 it seems. :(
This is a bug with Custom Elements v1 and it being designed for future browsers in a way that is impossible to transpile downward.
Node 4, 5 and Chrome 48 only support classes in strict mode. Currently, we think Chrome 48 does not support classes and Node 4 and 5 do. Should we introduce separate support matrix entries for classes in strict mode and everywhere and do all the work to distinguish them?
This is relevant because @Rich-Harris decided in #43 to only support Node 4 and upwards to work around #40 when self-transpiling. Since we are using modules, all our code is in strict mode, so we could continue keeping classes as they are for Node 4 and 5 if bublé were clever enough to distinguish between strict and sloppy mode and know about Node's and Chrome's peculiarity.
F.e., even with --target ie:8
,
let o = { get foo() {return 1} }
is compiled to
var o = { get foo() {return 1} }
IE 11 throws the infamous "Expected object" error.
Hi,
I'm trying to package bublé in Debian, but I'm hitting a problem with acorn-object-spread : there's UXtemple's one, which is outdated. There is Adrian Heine's acorn5-object-spread, which is more up to date. And finally, you seem to have your own fork.
What am I supposed to do?
this is really usefull to codesplit with webpack
gitlab ref https://gitlab.com/Rich-Harris/buble/issues/214
Hey there,
I'm using React Styleguidist which uses buble behind the scenes.
It seems that buble is the cause of this issue that was closed a while ago. I believe this only occurs in IE10 (and probably less).
It seems that the cause of the issue is this line, though I'm not entirely sure how this all works.
It may be due to an error in this file, but I haven't had too long to look into this.
Here's a shot of the minified stacktrace.
Additional info:
react-styleguidist
uses buble
in the browser, but unfortunately buble
ships to npm codebase containing some es6 features.
I'd only want to clarify what environments buble is targeting - in which node/browser versions it should run out of the box? Would you consider transpiling more features to support older browsers like IE11 or should we fix this in a tool like react-styleguidist
by transpiling buble on our own?
Buble generates A.concat( ["B")
It doesn't compile....
obj = {
get [x] () { return 1 },
set [x] (value) { valueSet = value }
};
emits
obj = {};
objget [x] = () { return 1 };
objset [x] = (value) { valueSet = value };
reference. Example:
class C {}
var c1 = C;
{
class C {}
var c2 = C;
}
return C === c1;
There is a funny bug. Here is an example.
Without block statement it is working fine. It also works with only one variable.
Spec. Example:
try {} catch ({message}) {}
According to MDN, destructuring is supported on Edge 14+, but setting the target to edge:12 or edge:13 doesn't transpile the following:
this._elementManager.setClasses(...properties.classes);
I was expecting it to use Function.prototype.apply
.
The following jsx code examples cause a parsing error
Error: Cannot overwrite a zero-length range – use insertLeft or insertRight instead
<div className={"foo"}disabled />;
<div className="foo"disabled />;
Notice the issue is the missing space after the jsx properties. It works fine in babel but causes the error here.
Dear maintainers! Is there any chance such constructs will be supported for the Internet Explorer?
static get [Symbol.species]() {
return Array;
}
`${`${foo}`}`
results in
(""("" + foo)
`${`${1}`}`
results in
(""("" + (1))
It looks like the demo is running version 0.15.2 & it renders correctly.
$ bin/buble -v
Bublé version 0.18.0
$ cat scope_bug.js
const bar = "FAIL";
!function() {
function foo() {
--bar;
bar = ["fail", "PASS", "Fail"][bar];
}
var bar = 2;
foo();
console.log(bar);
}();
$ cat scope_bug.js | node
PASS
$ cat scope_bug.js | bin/buble
---
1 : const bar = "FAIL";
2 : !function() {
3 : function foo() {
4 : --bar;
^^^^^
bar is read-only (4:8)
Related sources:
src/program/types/AssignmentExpression.js#L7-L9
src/program/types/UpdateExpression.js#L7-L11
function A() {
if (1) {
const {
B: {C, D},
} = {};
}
}
For example
<div>
<a>1</a>
</div>
is compiled to
React.createElement( 'div', null,
React.createElement( 'a', null, "1" )
)
here
is an unexpected token.
BTW I think it would be nice to update the report bug link at https://buble.surge.sh to this repo
Example:
var x; for ({x} of []) {a();}
Destructuring variable declarations work, though.
...
Can we use buble in production?...
Both unicode point escapes …
var \u{102C0} = { \u{102C0} : 2 };
… and non-ascii characters …
var 𐋀;
are supported now.
Here's a minimal representation of the original code, which works well on the browser:
const foo = { bar: [] }
const baz = true ? [1,2,3] : []
foo.bar.push(...baz)
// [1,2,3]
console.log(foo.bar)
When transpiled, the entire push operation appears to be ignored.
var foo = { bar: [] }
var baz = true ? [1,2,3] : []
(ref = foo.bar).push.apply(ref, [1,2,3])
// []
console.log(foo.bar)
var ref;
The current workaround is to add ;
at the end of the ternary, breaking off the second and third line:
const foo = { bar: [] }
const baz = true ? [1,2,3] : [];
foo.bar.push(...baz)
// [1,2,3]
console.log(foo.bar)
Buble should automatically add the ;
because it added the parens. The consumer should not be aware about adding ;
due to implementation, especially when the code works without it before transpilation.
Example:
let i;
for(let i in { a:1, b:1 }) {
(function(){ return i; })();
}
Generates:
var i;
var loop = function ( i ) {
(function(){ return i$1; })();
};
for(var i$1 in { a:1, b:1 }) loop( i );
It would be useful to transpile async functions, they're a valid part of the language.
See here for previous discussion: https://gitlab.com/Rich-Harris/buble/issues/71
The fast-async
package provides a leaner/faster result than regenerator (let's not use regenerator), and I think it can be further optimized because when I convert async functions to Promise-based equivalents manually, they always come out with the leanest result. The new Promise.finally
will help with this.
This may require a Promise polyfill to be supplied by the user, and that should be documented.
When a object that uses a computed property key ({[key]: value}
) is returned in a function, the output is invalid.
Here's an example:
input:
const deepifyKeys = (key, val) => {
return { [key]: val }
}
output:
var deepifyKeys = function (key, val) {
return ( obj = {}
var obj;, obj[key] = val, obj )
}
A more complex example with the actual code that hit this bug can be found here.
I'm currently working on dynamically transpiling resources with the minimum set of transformations required by that browser, and it would be useful to not bail if a version is specified for which there is no support data. Defaulting to either bitmask is fine (or perhaps by specifying a "fallback" option).
@Rich-Harris, I'm happy to open a PR just wanted to run this by you first. Let me know what you think..
Spec. Examples:
var B;
class C extends (B = class {}) {}
return new C() instanceof B
&& B.isPrototypeOf(C);
class X extends (function ([x]) { console.log(x); }) {
}
new X("ab")
I.e. let x = {}; Error.call(x) == x
produces false, at least on Firefox and Chrome. This is preventing Error subclasses compiled with Bublé from getting stack
and message
properties, making them rather useless.
Babel works around this by creating a new binding to replace this
inside the constructor, storing the result of the super constructor call in that, and returning it at the end. Would that be something that Bublé would be interested in adding? I might be able to create a PR.
Examples:
({a,b} = {c,d} = {a:1,b:2,c:3,d:4});
var a,b,c,d; [a,b] = [c,d] = [1,2];
I found this Bublé as a light-weight alternative to babel and I like the concept. However I'm very confused about the GitLab and GitHub repos. From the FAQ It looks like you prefer GitLab?
From the status of the GitLab repo I thought the project was dead with the last commit being 9 months old. I only found this repository here by chance. Since there is a newer release here I take it the project is not dead after all and you sometime recently changed your mind about GitLab vs GitHub?
If this repo is the intended future of this project could you add a note to readme of the old repo and update the guide to link here and remove confusing question from FAQ? Or is there some repository for the guide where I could send a PR?
And maybe you should consider creating a buble organization on GH. It's generally a better practice for open-source projects than to have the repo under your personal account.
When building with Rollup 0.50.0
, using rollup-plugin-buble
and buble
both at 0.16.0
, I get an error like this:
[!] TypeError: Cannot read property 'magicString' of undefined
TypeError: Cannot read property 'magicString' of undefined
at new CompileError (/home/trusktr/Downloads/src/trusktr+infamous/node_modules/buble/src/utils/CompileError.js:8:30)
at error (/home/trusktr/Downloads/src/trusktr+infamous/node_modules/rollup/dist/rollup.js:185:14)
at Object.error (/home/trusktr/Downloads/src/trusktr+infamous/node_modules/rollup/dist/rollup.js:9407:6)
at promise.then.previous (/home/trusktr/Downloads/src/trusktr+infamous/node_modules/rollup/dist/rollup.js:9416:32)
at <anonymous>
The line where it happens is like follows
import locate from './locate.js';
import getSnippet from './getSnippet.js';
export default class CompileError extends Error {
constructor ( node, message ) {
super();
const source = node.program.magicString.original; // RIGHT HERE
const loc = locate( source, node.start );
this.name = 'CompileError';
this.message = message + ` (${loc.line}:${loc.column})`;
this.stack = new Error().stack.replace( new RegExp( `.+new ${this.name}.+\\n`, 'm' ), '' );
this.loc = loc;
this.snippet = getSnippet( source, loc, node.end - node.start );
}
toString () {
return `${this.name}: ${this.message}\n${this.snippet}`;
}
}
So, it looks like I have a compile error, but I can't see what it actually is because the error is not able to be thrown properly.
Edited once bug was found. See bug in following comment.
This is just a case of suboptimal code generation. The temporary variable used by computed properties within an arrow function is not in the correct scope which can lead to slower code:
$ bin/buble -v
Bublé version 0.18.0
$ echo 'var f = (x) => ({ [x]: 1 });' | bin/buble | uglifyjs -b
var obj;
var f = function(x) {
return obj = {}, obj[x] = 1, obj;
};
compared to:
$ buble -v
Bublé version 0.15.2
$ echo 'var f = (x) => ({ [x]: 1 });' | buble | uglifyjs -b
var f = function(x) {
return obj = {}, obj[x] = 1, obj;
var obj;
};
and
$ echo 'var f = (x) => ({ [x]: 1 });' | babel -L
"use strict";
var f = function f(x) {
var _ref;
return _ref = {}, _ref[x] = 1, _ref;
};
Hi and thanks for such great products @Rich-Harris,
there is a small issue depending on how the computed properties are ordered:
// this is well transpiled
const ref = {
'foo': bar,
[`foo-${bar}`]: fooBar
}
// becomes
var ref = {
'foo': bar
};
ref[("foo-" + bar)] = fooBar
// this is is not
const ref = {
[`foo-${bar}`]: fooBar,
'foo': bar
}
// becomes
var ref = {};
ref[("foo-" + bar)] = fooBar;
ref.'foo' = bar // where this is unvalid JS syntax
As temporal workaround is to keep the computed properties always last, but it would be nice if this could be solved. I don't have much experience with this project, sorry for not having any PR instead.
Here is an example.
input
const q = {};
q.a = class {
c () {}
}
output
var q = {};
q.a = (function () {
function undefined () {}
undefined.prototype.c = function c () {};
return undefined;
}())
This way it is working fine.
const q = {};
Object.assign(q, {a: class {
c () {}
}})
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.