Cannot use decorators in Node/BabelJS application - javascript

I have a Node application, which specifies babel with transform options and register in a main file, like so:
require('babel').transform('code', { stage: 1 });
require('babel/register')({ ignore: false });
require('../src/index');
Which does an excellent job of allowing me to use ES6 in ../src/index, and all subsequent files, but does not seem to allow me to use Decorators, as it should by declaring level 1 transform. I get instead a syntax error. Why is this not enabling decorator support? The actual decorator I'm trying to use is:
#test1
test Class() {
constructor() {
this.test = 'test';
}
}
function test1(obj) {
obj.test1 = 'test1';
}

That's not how you specify options, that first like does nothing. It compiles the JavaScript code code and does nothing with the result of the compilation.
require('babel/register')({
ignore: false,
stage: 1
});
require('../src/index');
Also generally ignore: false is a bad idea because some files should ignored.
Update
If you are using Babel 6, you'll want to download babel-plugin-transform-decorators-legacy rather than enabling stage: 1.

It's worth noting that the newest version of babel (v6) (over 1 month old) does not support decorators and the babeljs team has identified that they do not consider decorators to be a priority to fix -
https://twitter.com/sebmck/status/661501967412301824
As #jdanyow has mentioned in other answers you can track the issue here but beware if you choose to use Babeljs v6 that there is functionality from the previous release which is broken in the released v6 at the moment.
As #loganfsmyth points out in comments there is a plugin available babel-plugin-transform-decorators-legacy although it does mention that there are differences in the implementation, however I am not aware of them.

Related

How can I enable tailwind intelliSense outside of "className"?

I'm using the tailwind CSS intellisense vscode extension, and it seems to only work when typing inside a className property.
I'm using a package called cntl https://www.npmjs.com/package/cntl to help write more maintainable classNames, however, using this package, I lose the intelliSense support.
Is there any way to manually configure so that I get the intelliSense when writing my cntl?
const title = cntl`
text-3xl
// I'd like intellisense here
`
Here's how I solved it.
In VSCode settings.json add the following:
"tailwindCSS.experimental.classRegex": [
"cntl`([^`]*)", // cntl`...`
],
I realize this Q is old, but it still shows up in search so I wanted to share my workflow :)
Here's my VS Code settings.json to add Tailwind IntelliSense within objects and variables who's name ends with "Classes":
"tailwindCSS.experimental.classRegex": [
["Classes \\=([^;]*);", "'([^']*)'"],
["Classes \\=([^;]*);", "\"([^\"]*)\""],
["Classes \\=([^;]*);", "\\`([^\\`]*)\\`"]
],
Tailwind IntelliSense will now recognize all of the following strings:
const defaultClasses = `text-grey`;
const componentClasses = {
default: 'text-grey',
danger: `text-red`,
warning: "text-yellow",
};
Note: the regex matches code blocks that start with Classes = and ends with ; — you can replace Classes = with your own matcher, like. cntl :)
Linting is not supported yet as per: https://github.com/tailwindlabs/tailwindcss/issues/7553. Hover seem to be supported now though
For clsx
"tailwindCSS.experimental.classRegex": ["clsx\\(([^)]*)\\)"]
For classnames
"tailwindCSS.experimental.classRegex": ["classnames\\(([^)]*)\\)"]
None of the answer worked for me.
But it workes based on the guide from https://www.jussivirtanen.fi/writing/using-tailwind-intellisense-within-strings
If you're using VS Code and writing your Tailwind classes within a variable, you've probably noticed that Tailwind IntelliSense doesn't work. However, if you're using a consistent naming scheme, you can fix this issue.
I use a consistent naming scheme with the word Styles at the end. In this case, I can go to Tailwind IntelliSense settings and add .*Styles to the tailwindCSS.classAttributes array:
// settings.json within VS Code
{
// Add ".*Styles" (or whatever matches your naming scheme)
"tailwindCSS.classAttributes": ["class", "className", "ngClass", ".*Styles"]
}
example usage
const contentStyles = "py-1 bg-white dark:bg-gray-700"
This will detect a container consisting of className = [] string and its variants such as ButtonClassNamesXyz Classname and whatever is inside [ ] will be processed.
"tailwindCSS.experimental.classRegex": [
["\\S*[Cc]lass[nN]ame\\S* = \\[([\\s\\S]+?)(?=][\\s;,.])", "'([^']*)'"],
"return '(.*)'",
],
Adjust regex here https://www.debuggex.com/r/yhCYrsFdzXRWQEhP
v2 note
I have added detection for ] inside the actual classname string.
tailwindlabs
/
tailwindcss
: [IntelliSense] Custom class name completion contexts #7554
I understand this question has been answered, but I was still facing some trouble because I wanted to use Tailwind's intellisense with react's classnames library.
Here's what worked for me after adding it to VSC's settings.json:
"tailwindCSS.experimental.classRegex": ["classNames\\(([^)]*)\\)"],

Typescript: prevent use of ".name" to get function/class name

is there an easy way (maybe tslint rule) to prevent us from using MyClass.name, or myFunction.name?
We're trying to make sure no Dev end up using this, as the minification process will change method names.
Thank you!
Untested, so mileage may vary from 0 to 100, but you can try the following. Inside a global/ambient ts file write:
declare global {
interface Function {
/** #deprecated Don't use this, think about the children!*/
readonly name: string;
}
}
Then set in your tslint config:
"rules": {
"deprecation": true
}
Perhaps this will warn the developer with a deprecation notice, but there is also a possibility it's ignored, because the lib typings do not have this comment

ng.core.Component(...).Class is not a function

I'm using ES5 flavor of Angular 2. Thus instead of using decorators, I define a template as follow:
var someComponent = ng.core.Component({
// component configuration
}).Class({
// component class
});
It was working fine. Recently I upgraded to Angular 5, and now I have these error for the same code:
ng.core.Pipe(...).Class is not a function
ng.core.Component(...).Class> is not a function
ng.core.Directive(...).Class is not a function
How should I change this in Angular 5?
JavaScript is currently considered second-class (no pun) citizen, while TypeScript is the language of choice, primarily because of the focus on AOT compilation, which is available for TypeScript only.
As explained here,
It is no longer possible to declare classes in this format.
Component({...}).
Class({
constructor: function() {...}
})
This format would only work with JIT and with ES5. This mode doesn’t
allow build tools like Webpack to process and optimize the code, which
results in prohibitively large bundles. We are removing this API
because we are trying to ensure that everyone is on the fast path by
default, and it is not possible to get on the fast path using the ES5
DSL. The replacement is to use TypeScript and #Decorator format.
#Component({...})
class {
constructor() {...}
}
As described in this answer, the alternative to decorators in plain ES5 and higher is the annotation of classes (and therefore, functions) with annotations and parameters static properties.
So
var SomeComponent = ng.core.Component({...})
.Class({
constructor: [
[new ng.core.Inject(Svc)],
function (svc) {...}
],
foo: function () {...}
});
becomes
SomeComponent.annotations = [new ng.core.Component(...)];
SomeComponent.parameters = [
[new ng.core.Inject(Svc)]
];
function SomeComponent(svc) {...}
SomeComponent.prototype.foo = function () {...};
As a replacement for Class functionality, any third-party utility class library can be used to introduce syntactic sugar and inheritance in ES5 as a substitute for functions, e.g. uberproto or inherits.
It it highly advisable to migrate existing Angular JavaScript applications to TypeScript, the latter offers superior performance and much smaller application footprint in AOT compilation mode, which is going to be default mode in future versions.

Browserify standalone option doesn't directly wraps the code with specified name?

I tried to use gulp, browserify, watchify, and babelify to compile a standalone js module.
The options is like this:
const browserifyOpts = {
debug: true,
entries: path.join('src', 'index.js'),
standalone: 'Goo',
transform: [
'babelify',
],
};
My JS module is as follows:
export default class Goo {
constructor() {
this.a = 'hello';
}
}
It compiles fine. But when I include it in a script tag in a html file, the Goo module is wrapped inside window.Goo.default, that is, I cannot directly use:
new Goo();
but have to use:
new Goo.default();
Any idea where went wrong?
Thanks!
The easiest option would be to wrap this yourself by having your index.js file contain something like
module.exports = require('./main').default;
and move your current index.js to main.js. Then you'll be set.
As the other answer says, you can potentially use babel-plugin-add-module-exports, but that is not something I'd generally recommend because while it fixes this problem, it also introduces the possibility that you could accidentally write import/export pairs that work but are not spec-compliant.
By default, Babel 6 handles default module exports differently. If you want to use the legacy version, you can use the add-module-exports plugin.
Either add that into your .babelrc, or add it as an option in Babelify.
More information from this Github Issue:
has to do with the new way Babel handles default exports. if you dont
want to have to reference the default key, you need to use this
plugin: https://github.com/59naga/babel-plugin-add-module-exports

Babel 6 preset selection to get babel working

I'm using babel 6 with the react plugin and followed the documentation instructions for setting up the transpile process. I've read to get react working I need to use es2015 and react preset. Initially everything worked fine using this both presets.
But when I've copied an example code from babel's website (Property initializers)
to test new language features I've got errors when code below was transpiled and so it wasn't possible anymore to transpile the code.
// The ES6+ way
class Video extends React.Component {
static defaultProps^= { // this is line 42 and ^ the column where error occurs
autoPlay: false,
maxLoops: 10,
}
static propTypes = {
autoPlay: React.PropTypes.bool.isRequired,
maxLoops: React.PropTypes.number.isRequired,
posterFrameSrc: React.PropTypes.string.isRequired,
videoSrc: React.PropTypes.string.isRequired,
}
state = {
loopsRemaining: this.props.maxLoops,
}
}
Warning: [...]components/sectorList.js: Unexpected token (42:24) Use --force to continue.
After a long while debuggin I've got this issue solved by loading also the stage-0 preset for babel. But it was just luck.
So my question where I can't find an answer for is:
How is the correct way to determine the correct preset collection.
Or is an unexpected token ... warning mostly a notification for an missing preset?
Thanks for any help
If you look at the babel pages for a preset, it lists all the included transformations. In this case, you're using class properties, which is currently at stage 1 and is therefore included in the stage 1 preset.
In ES2015, you'd use the constructor to set the defaults.

Categories