Decorators with babel, unexpected token - javascript

I'm trying to use decorators on classes in React, using babelify. I have the 'es7.decorators' option applied in babel, but I keep getting an 'unexpected token' error when it encounters the '#' character.
Anyone have any ideas? A simple example is below.
Decorator:
export default function(Component) {
return class extends Component {
constructor() {...}
}
}
Class:
import myDecorator from 'decorator';
#myDecorator
class MyClass{...}
I'm using babelify (Browserify transform for Babel):
browserify().transform(babelify.configure({
optional: ['es7.decorators']
})

Thanks to #LeonidBeschastny for mentioning .babelrc file, using the config file decorators work correctly, using the setup described on the babelify readme doesn't work, for whatever reason (not sure if my setup or something else).

In case anyone else ran into this problem, I was having the same problem.
I think there were breaking changes outlined here: http://babeljs.io/blog/2015/03/31/5.0.0/#babelrc
All I needed to do was add { "stage": 1 } to my babelrc, which tells babel to compile with the experimental features, one of which is the es7 decorator.

Related

SyntaxError: ambiguous indirect export: default Error when importing my own class

I have written a validation class and want to include it in my VueJS 3 project. Unfortunately I get the following error: SyntaxError: ambiguous indirect export: default
This is my code:
// ..classes/formValidationClass.js
export class FormValidator {
...
}
// some vue file with a form
import FormValidation from "..classes/formValidationClass"
export default {...}
Question:
What does this error mean and what do I have to do to correct the error?
Use brackets {} around your import Name
// ..classes/formValidatorClass.js // Comment: => suggestion change your file name to similar your class name
export class FormValidator {
...
}
// some vue file with a form
// import FormValidation from "..classes/formValidationClass"
import { FormValidator as FormValidation} from "../classes/formValidatorClass"; // Comment: => use brackets around your import name. if you want use FormValidation you can use also a alias (`originalName as newName`)
export default {...}
I found that none of the tsconfig, package.json fixes would never work for me. Hopefully the following helps someone in the future.
I was consistently getting this error when working with Vite projects and not Webpack projects. I would not be able to import anything, named or otherwise.
On one Svelte code base I ran the Svelte CLI sync command and it mentioned a type import was breaking the importsNotUsedAsValues or preserveValueImports and that I should explicitly mark the import as a type.
The import statement in question:
import { TUser } from '../models/Users/Users';
TUser exported as:
export type TUser = { ... }
Errors
Would cause the following errors:
Error: This import is never used as a value and must use 'import type' because 'importsNotUsedAsValues' is set to 'error'. (ts)
Error: 'TUser' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled. (ts)
Solution
Doing the following fixed the issue for me.
import type { TUser } from '../models/Users/Users';
My story: WebStorm generated .js files right next to .ts files (because I once enabled the Recompile on changes option), so my app tried to import from .js files instead of .ts one. That was the reason for the import problems.
This is the compiled code on the local dev server:
For the sake of helping anyone bumping into this error and arriving at this page, the word default in export default function myFunction() can cause this error. Or in other words: remove the word default may help.
In my case I had the curly braces where I shouldn't have. I had a JSON file and import { users } from ... where instead I should have no curly braces like so:
import users from './users.json';
console.log("users", users);

Cannot use newly installed plugins (node modules) in Nuxt pages/components

First off, I'm a beginner with NuxtJS and front-end development in general, so it might be that I'm missing something - though I do believe I went through all the options before posting here. Apologies in advance if that is not the case.
I've been having trouble using installed modules that I've registered as plugins. For example, take mapbox-sdk.
After installing it with npm install #mapbox/mapbox-sdk, which correctly creates #mapbox/mapbox-sdk in node_modules, I register it in nuxt.config.js:
plugins: [
...
"~/plugins/mapbox-sdk.js",
],
Of course, I also create the mapbox-sdk.js file in plugins/, containing:
import "#mapbox/mapbox-sdk";
Then, in a page (say, myMap.vue), when I try:
var mapboxClient = mapboxSdk({ accessToken: MY_ACCESS_TOKEN });
which is the basic usage example in the documentation, I get:
mapboxSdk is not defined
in the console. This behavior extends to every single module I installed today, but is not the case for modules I had previously installed.
The reason why you're getting the error mapboxSdk is not defined is because there are a few issues with the way you've set up this plugin.
Docs here https://nuxtjs.org/docs/2.x/directory-structure/plugins/, they have some useful diagrams.
There are a couple of ways you can use this package.
Plugin
// ~/plugins/mapbox-sdk.js
import mapboxSdk from '#mapbox/mapbox-sdk'
export default (_ctx, inject) => {
// Exposing the mapboxSdk to your Nuxt app as $mapBox.
inject('mapBox', mapboxSdk)
}
Then in nuxt.config.js, same as you've already done.
plugins: [
...
"~/plugins/mapbox-sdk.js",
],
Then in your component myMap.vue
var mapboxClient = this.$mapBox({ accessToken: MY_ACCESS_TOKEN });
Directly in the component:
If you don't wish to use a plugin, the way that #kissu mentioned above https://stackoverflow.com/a/67421094/12205549 will also work.
Try adding this after the import to let Vue know that this method exists (in the same .vue file) at first
<script>
import mapboxSdk from '#mapbox/mapbox-sdk'
export default {
methods: {
mapboxSdk,
},
mounted() {
console.log('mapbox function >>', mapboxSdk)
},
}
</script>
Do you have it working in a .vue component at first ?

Resolving compiled default exports with ES6 syntax

I have a module, say as follows:
const awesomeFn = () => ...
export default awesomeFn;
It is built into ES5 using babel, and when I created another ES6 module, I want the following syntax:
npm i awesomeFn
// ./index.js
import awesomeFn from 'awesomeFn';
awesomeFn();
But this throws. Logging awesomeFn gives me { default: _default [Function()] } (or something like that), hinting that I'd need to do something like
import awesomeFnPackage from 'awesomeFn';
const { default: awesomeFn } = awesomeFnPackage;
How can I form my exports so that I don't have to do the default destructuring? Should I avoid default exports altogether for this reason?
Somewhat strangely, this works if:
I use esm, like so node -r esm index.js but not if I use mjs as the file extension (with "type": "module" set), only js
It doesn't work with --experimental-modules, --experimental-specifier-resolution=node nor "type": "module" in package.json,
In every non-working case, the import value is { default: [Function: awesomeFn] }, only with esm is the value [Function: awesomeFn]
So I guess that's the solution right now; rely on an external package for expected behaviour, or use named exports, which do work as expected. What is going on with this?
Solution provided here, which is to destructure the default property as stated in the question, or add yet another dependency to intuitively use es6 imports.
I'll leave out the reasoning for why this choice was made by Babel to the reader to research for brevity. My conclusion is to use ES5 or not to use default exports. ES6 syntax is a mess in the context of import/exports as of writing, not only in the context of this question, but in the context of npm packaging, file extensions, flags, package.json properties, etc.
Hei, it looks like a problem with your setup. Default functions are named "default" when exported (ES5).
You can probably destructure directly in the import statement like this:
import { default as awesomeFn } from 'awesomeFn';
awesomeFn()

How do I manually include "#material/drawer" into my component?

I am trying to manually include the #material/drawer npm package into my Ember app. I tried following this guide but I'm running into some weird errors in my Chrome dev console:
Uncaught SyntaxError: Unexpected token *
Uncaught ReferenceError: define is not defined
The first is from the imported node_modules/#material/drawer/index.js file and the second is from my generated shim.
My component code:
import Component from '#ember/component';
import { MDCTemporaryDrawer, MDCTemporaryDrawerFoundation, util } from '#material/drawer';
export default Component.extend({
init() {
this._super(...arguments);
const drawer = new MDCTemporaryDrawer(document.querySelector('.mdc-drawer--temporary'));
document.querySelector('.menu').addEventListener('click', () => drawer.open = true);
}
});
In my ember-cli-build.js:
app.import('node_modules/#material/drawer/index.js');
app.import('vendor/shims/#material/drawer.js');
My generated shim:
(function() {
function vendorModule() {
'use strict';
return {
'default': self['#material/drawer'],
__esModule: true,
};
}
define('#material/drawer', [], vendorModule);
})();
What exactly am I doing wrong? It almost seems as though raw ES6 code got imported rather than compiled into my JS build output.
I also read this SO post but there are too many answers and I'm not sure which to do. It seems this specific answer is what I'm trying to do but not verbatim enough.
Creating a shim only ensures that ember-cli gets an AMD module, which you then can import in your app files.
If the npm package needs a build or transpiling step beforhand, this won't work.
You need a way to get the package build within the ember-cli build pipeline.
Luckily there are addons which can take care of this for you: ember-auto-import and ember-cli-cjs-transform.
You may have also heard of ember-browserify, which does the same thing, but it's deprectaed in favor of ember-auto-import.
I'd suggest you try ember-auto-import:
ember install ember-auto-import
You then should be able to import as you tried:
import { MDCTemporaryDrawer, MDCTemporaryDrawerFoundation, util } from '#material/drawer';
No shim or app.import needed, as ember-auto-import will take care of this for you.

ECMA7 static prototypes is not yet supported in Meteor, what is a good workaround?

I would like to use ECMA static proptypes within my React code. Unfortunately this throws the following Babel error
Missing class properties transform.. As far as I'm aware this is because Meteor does not yet support stage 0 ECMA proposals.
From reading various threads it seems like it may be possible to resolve this by amending some babel configs, however I'm not too familiar with Babel so would rather avoid screwing with it too much. How can I express the below static /proptypes logic in an alternative, supported fashion?
Thanks!
import React from 'react';
import bookSingleLine from '../Kooks/Table/BookSingleLine';
import TrackerReact from 'meteor/ultimatejs:tracker-react';
export default class bookListingTable extends TrackerReact(React.Component) {
static propTypes = {
LimitProp: React.PropTypes.number.isRequired
}
static defaultProps ={
LimitProp: 5,
}
Just manually assign the static properties instead of declaring them in the class body (which is not supported in ES7):
export default class BookListingTable extends TrackerReact(React.Component) {
…
}
BookListingTable.propTypes = {
LimitProp: React.PropTypes.number.isRequired
};
BookListingTable.defaultProps = {
LimitProp: 5
};
There is a better approach today, it makes you use static.
add the following package:
meteor npm install --save-dev babel-plugin-transform-class-properties
Edit your package.json in your project and add there the following to make the package work:
"babel": {
"plugins": ["transform-class-properties"]
}

Categories

Resources