Class constructor PolymerElement cannot be invoked without 'new' - javascript

Yesterday my app worked perfectly however when I now do polymer serve -o it opens the app and prints this error in the console.
Class constructor PolymerElement cannot be invoked without 'new'

Clear the Cached files and images from your browser cache.
If you loaded custom-elements-es5-adapter.js, remove it.
Then use $ polymer serve --compile never.
According to this post, this issue is cause because $ polymer serve compiles your code to es5 automatically. The --compile never flag stops $ polymer serve from doing this.

I had a similar Error the other day after moving my Polymer App to v.2.
This helped me:
To work around this, load custom-elements-es5-adapter.js before
declaring new Custom Elements.
Since most projects need to
support a wide range of browsers that don't necessary support ES6, it
may make sense to compile your project to ES5. However, ES5-style
custom element classes will not work with native Custom Elements
because ES5-style classes cannot properly extend ES6 classes, like
HTMLElement.

I build my Polymer App as es5-bundled, and serve it to Android App using WebView.
This problem often appears.

In your polymer.json, add custom-elements-es5-adapter to the excludes array to stop it from being compiled to ES5.
"builds": [
{
"bundle": {
"stripComments": true,
"inlineCss": true,
"sourcemaps": false,
"excludes": [
"bower_components/webcomponentsjs/webcomponents-loader.js",
"bower_components/webcomponentsjs/custom-elements-es5-adapter.js"
]
},
"js": {
"compile": true,
"minify": true
},
"css": {
"minify": true
},
"html": {
"minify": true
},
"addServiceWorker": false

The problem occurs because Custom Elements v1 requires your code to use ES6 syntax. So make sure you don't transpile to anything lower, like ES5.
For anyone running into this using the Parcel bundler like me; by default it compiles your code to ES5 or something, even if you're using Typescript and you've set the tsconfig target to ES6.
The solution is to tell Parcel what browsers you're targeting, so that it knows it doesn't have to transpile to ES5. One way to do it is to add a "browserlist" field in package.json.
I found out about this through this video. For more info I suggest you go watch that.

Related

Babel plugin-proposal-decorators not working as expected

I have added these two devDependencies in my package.json:
"#babel/plugin-proposal-class-properties": "^7.1.0",
"#babel/plugin-proposal-decorators": "^7.1.6",
In .babelrc a file I have added them as plugins:
{
"presets": ["module:metro-react-native-babel-preset"],
"plugins": [
["#babel/plugin-proposal-decorators", { "legacy": true}],
["#babel/plugin-proposal-class-properties", { "loose": true}]
]
}
I am using mobx so observable is the clean syntax, my file looks like this:
class AppStore {
#observable username = ''
}
export default (new AppStore())
But it is always showing this error:
I think I have done it correctly but there is no way to detect whether babel plugins are loaded or not.
First, make sure that you are on the latest version of metro-react-native-babel-preset, they released a new minor 0.50.0 only 9 days ago.
If that didn't help, it's likely the problem comes from the fact that the metro-react-native-babel-preset already includes the class property plugin, and as you know the order of the plugins matter, you need to have the decorator run before the class property plugin.
There has been a lot of discussion on this subject of ordering in babel, and although plugins are supposed to run before presets, it still would be a problem. Unfortunately PR #5735 to add plugin ordering capabilities is still a work in progress.
What you could do in the meantime could be to either fork your own metro-react-native-babel-preset and add the decorator plugin before the class property plugin at the place I pointed. You might also try to make your own babel preset including the two plugins in the right order and add it after the metro one, as presets are loaded in reverse order, last to first as seen here.
Also worth a try would be to start the packager using yarn start --reset-cache which might solve issues caused by a bad/outdated cache.

Extending MediaSource with Babel -- how to properly call super()?

I'd like to extend MediaSource. I'm using Babel.
class BradMediaSource extends MediaSource {
constructor() {
super();
}
}
const source = new BradMediaSource();
In Chrome directly, this works fine. In a transpiled build done with Babel, I get the following error:
Uncaught TypeError: Failed to construct 'MediaSource': Please use the 'new' operator, this DOM object constructor cannot be called as a function.
This seems similar to this GitHub issue: https://github.com/babel/babel/issues/1966 I have also tried the following package, but it doesn't seem to apply to my specific situation... makes no difference: https://www.npmjs.com/package/babel-plugin-transform-custom-element-classes
My .babelrc:
{ "presets": [ "es2015" ] }
Is there a way around this problem?
Generally extending builtin types does not work with compiled classes from Babel, so you'd need to configure Babel to not process classes, and limit your application to only browsers that support classes.
Assuming your target browsers all support ES6 class syntax, the easiest approach would be to use babel-preset-env configured for those target environments.
You can also try to use transform-builtin-extend in your Babel config for MediaSource, though that does tend to vary with exactly which things can be extended.

Prevent "test/expect/etc is not defined" errors when using Jest

Facebook's Jest testing framework is easy to get started with, but the documentation overlooks an annoying aspect: test statements will be highlighted as errors by any editor that tries to warn of undefined symbols, because test, expect, and all matcher methods are not defined.
Similary, attempting to run a test file with node directly will fail with ReferenceError: test is not defined.
What require/import statement(s) need to be added for those errors to go away?
Node
If you want to run them directly through node, try to require jest and/or jest-runtime. Also give #types/jest a try as well.
Check Edit 2 for new info about this
Edit
#types/jest (jest-DefinitelyTyped) is definitely needed (or just one solution). If you install it (e.g., dev dependency), the IDE errors should go away.
I just tried it on Webstorm, and it works.
Edit 2
The new Jest#20 Matchers (e.g., .resolves and .rejects) are still not defined in #types/jest. You can keep track of its status on the links below:
https://github.com/DefinitelyTyped/DefinitelyTyped/pull/16645
https://github.com/DefinitelyTyped/DefinitelyTyped/issues/16803
It should be available soon, though!
Also, it doesn't seem possible to run it directly through node. Last night I tried a bunch of different things, but using jest is the way to go - it really uses node under the hood, so I thought it would be possible as well. #thymikee over your opened issue at GitHub made clear that it's not.
Edit 3
The new release (20.0.1) includes the newest Jest definitions.
Lint
this isn't in the scope of this specific problem, but it also helps
Are you using something like ESLint? If so, you'll need eslint-plugin-jest
Following the steps described in this page: https://www.npmjs.com/package/eslint-plugin-jest, you will basically need to add it as an ESLint plugin and set jest globals in the ESLint configuration:
{
"env": {
"jest/globals": true
}
}
If you plan on supporting ES6 tests, you'll also need Babel and babel-jest plugin with the following jest configuration:
"transform": {
"^.+\\.js$": "babel-jest"
}
Finally, for Typescript tests you'd need the #types/jest and ts-jest packages as well
Adding following .eslintrc configuration is enough
{"env":
{
"jest": true
}
}
I'm using VSCode and ESLint, you need to install eslint-plugin-jest
Add jest info to your .eslintrc.js
{
"plugins": ["jest"]
},
"env": {
"jest/globals": true
}

Using the whitelist option with Babel's external-helpers

I'm trying to use Rollup with Babel's external-helpers. It works, but it's dropping a bunch of babel helpers which I don't even need, for example asyncGenerator.
The docs show a whitelist option but I can't get it to work
rollup.rollup({
entry: 'src/buttonDropdown.es6',
plugins: [
babel({
presets: ['react', ['es2015', { modules: false }], 'stage-2'],
plugins: [['external-helpers', { whitelist: ['asyncGenerator'] }]]
})
]
})
The above has no effect: all Babel helpers are still dropped into my resulting bundle.
What is the correct way of using this feature, and is there a full list of which helpers' names the whitelist array takes?
Or is there some other Rollup plugin I should be using with Rollup to automatically "tree shake" the babel external helpers.
Problem
The babel-plugin-external-helpers plugin is not responsible for injecting those dependencies in the final bundle.
The only thing it controls is that how the generated code will access those functions. For example:
classCallCheck(this, Foo);
// or
babelHelpers.classCallCheck(this, Foo);
It is needed so all rollup-plugin-babel needs to do is to inject babelHelpers in every module.
The documentation is misleading, the whitelist options is not on the external-helpers plugin. It's on the completely separate module and command line tool called babel-external-helpers, which is actually responsible for generating babelHelpers.
It's rollup-plugin-babel what is injecting babelHelpers. And does it using a trick to modularize the final code. It calls babel-external-helpers to generate the helpers, and ignores the whitelist parameter. See my issue requesting to expose an option.
This approach is correct, because rollup will tree-shake the unused helper functions. However some of the helpers (like asyncGenerator) are written in a way that is hard to detect if the initialization has any side effects, thus preventing removal during tree-shaking.
Workaround
I forked rollup-plugin-babel and created a PR which exposes the whitelist option of building babelHelpers in the plugin's options. It can be used this way:
require("rollup").rollup({
entry: "./src/main.js",
plugins: [
require("rollup-plugin-babel")({
"presets": [["es2015", { "modules": false }]],
"plugins": ["external-helpers"],
"externalHelpersWhitelist": ['classCallCheck', 'inherits', 'possibleConstructorReturn']
})
]
}).then(bundle => {
var result = bundle.generate({
format: 'iife'
});
require("fs").writeFileSync("./dist/bundle.js", result.code);
}).then(null, err => console.error(err));
Note that I didn't publish distribution version on npm, you will have to clone the git repo and build it using rollup -c.
Solution
In my opinion the right solution would be to somehow detect or tell rollup that those exports are pure, so can be removed by tree shaking. I will start a discussion about it on github after doing some research.
As I have found in this particular issue in the GitHub page.
The Babel member Hzoo suggests that
Right now the intention of the preset is to allow people to use it without customization - if you want to modify it then you'll have to
just define plugins yourself or make your own preset.
But still if you want to exclude a specific plugin from the default preset then here are some steps.
As suggested by Krucher you can create a fork to the undesirable plugin in the following way
First one is by forking technique
"babel": {
"presets": [
"es2015"
],
"disablePlugins": [
"babel-plugin-transform-es2015-modules-commonjs"
]
}
But if two or more people want to include the es2015-with-commonjs then it would be a problem.For that you have to define your own preset or extend the preset of that module.
The second method would involve the tree-shaking as shown in this article done by Dr. Axel Rauschmayer.
According to the article webpack2 is used with the Babel6.
This helps in removal of the unwanted imports that might have been used anywhere in the project in two ways
First, all ES6 module files are combined into a single bundle file. In that file, exports that were not imported anywhere are not exported, anymore.
Second, the bundle is minified, while eliminating dead code. Therefore, entities that are neither exported nor used inside their modules do not appear in the minified bundle. Without the first step, dead code elimination would never remove exports (registering an export keeps it alive).
Other details can be found in the article.
Simple implemetation is referred as here.
The third method involves creating your own preset for the particular module.
Creating aplugin and greating your own preset can be implemented according to the documentation here
Also as an extra tip you should also use babel-plugin-transforn-runtime
If any of your modules have an external dependancy,the bundle as a whole will have the same external dependancy whether or not you actually used it which may have some side-effects.
There are also a lot of issues with tree shaking of rollup.js as seen in this article
Also as shown in the presets documentation
Enabled by default
These plugins have no effect anymore, as a newer babylon version enabled them by default
- async-functions (since babylon 6.9.1)
- exponentiation-operator (since babylon 6.9.1)
- trailing-function-commas (since babylon 6.9.1)**
Also the concept of whitelisting and blacklisting the plugins has benn brilliantly explained by loganfsmyth here in this thread.
you can pass a whitelist option to specify specific transformations to run, or a blacklist to specific transformations to disable.
You cannot blacklist specific plugins, but you may list only the plugins you want, excluding the ones you do not wish to run.
Update :
According to this article here is an important update -
"The --external-helpers option is now a plugin. To avoid repeated inclusion of Babel’s helper functions, you’ll now need to install and apply the babel-plugin-transform-runtime package, and then require the babel-runtime package within your code (yes, even if you’re using the polyfill)."
Hope this may solve your problem
Hope it may help you.

How to set .eslintrc to recognize 'require'?

I am new to ESLint, and I have successfully integrated ESLint with IntelliJ.
Out of the box, my integration of ESLint did not recognize node, but basic review of documentation made clear that by creating the configuration file named .eslintrc at the root of my project folder (with the proper IntelliJ setting to access this file) and setting "node":true, ESLint recognizes node (i.e., the following complete .eslintrc works).
// Contents of .eslintrc at root of project - support for Node and jQuery
{
"env" : {
"node" : true,
"jquery" : true
},
}
However, ESLint still does not recognize require(), as evidenced by this screenshot:
I have done my best in a reasonable amount of time searching for a solution to the basic question of how to get ESLint to recognize require(). In particular, I found a possible hint here, where it suggested to add "amd":false in (I presumed) the .eslintrc file - but no go.
This seems basic. How can I get .eslintrc to recognize require()?
(If, in your answer, you can provide insight how to cover more general cases, that would also be helpful. Thanks!)
Adding amd to env inside .eslintrc will enable you to use define() and require(), as per the amd spec:
{
"env": {
"amd": true
}
}
The problem is not with ESLint. If you look closely at your message, it says JSHint.
Since you're trying to configure ESLint, simplest solution would be to disable or remove JSHint plugin form your IDE.
If you still want to use JSHint along with ESLint, you can do the following:
Single file solution: add /* global require */ at the top of your file.
General solution for all files: add "node": true line to your .jshintrc.
"amd":true in env
defines require() and define() as global variables as per the amd spec.
See http://eslint.org/docs/user-guide/configuring#specifying-environments
On a Mac ... global solution. (2021)
If you are using the amazing ESLint in the amazing VS Code on Mac,
Simply go to ~ (ie /users/your-name)
edit .eslintrc.json (you can edit it in VSCode of course!)
You'll likely add
"node": true
if you're working with node, or perhaps "amd" as stated in the answers here. ("amd" gives specifically and only require and define).
This is a global solution for all workspaces you open.
Importantly, this also works if you are using VS Code "remotely", so, with no workspace. For example, you may open a file on a server just using sftp, and work on the file in VSCode. Or you may be opening just a single local file on the Mac, not part of a workspace. In both these cases the setting (eg, node=true) will in fact work - it needn't be a workspace.

Categories

Resources