Any ideas on how to use ES6 on WebStorm 10?
Here's what I have done so far:
Installed Babel.
Activated Babel with Settings > Tools > File watchers. checked Babel checkbox.
Edit configurations > Before launch file watchers > + then 'Run File Watchers".
Set code as ES6
Changed my run configuration to use the compiled version.
Then created the following trivial piece of code:
require("babel/register");
function* count(n){
console.log(n);
}
This code shows up with no syntax errors, as it should. (A convenient way to make sure ES6 is turned on).
Run it (run the compiled version, actually), and get this ....
var marked0$0 = [count].map(regeneratorRuntime.mark);
^
ReferenceError: regeneratorRuntime is not defined
Why? How do I get it to precompile with Babel and then run? Isn't the regenerator supposed to be taken care of with this line:
require("babel/register");
(Windows 7, if that is important).
Babel's require hook requires you to have BABEL_CACHE_PATH environment variable. You might need to specify them as well in your File Watcher configuration in WebStorm.
I think there are two things you probably need to do to make it work based on the nature of the error you're describing.
npm install babel-core
add --optional runtime as an argument to the invocation of babel
This is based on what's described in some detail here.
The "require hook" only works on files that you require after registering it, but not on the file that registers the hook itself.
So this works:
// index.js
require('babel/register');
require('./count');
// count.js
function* count(n){
console.log(n);
};
Related
These are my sample files:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="t1.js"></script>
</head>
<body></body>
</html>
t1.js:
import Test from 't2.js';
t2.js:
export const Test = console.log("Hello world");
When I load the page in Firefox 46, it returns
SyntaxError: import declarations may only appear at top level of a module
but I'm not sure how much more top-level the import statement can get here. Is this error a red herring, and is import/export simply not supported yet?
Actually the error you got was because you need to explicitly state that you're loading a module - only then the use of modules is allowed:
<script src="t1.js" type="module"></script>
I found it in this document about using ES6 import in browser. Recommended reading.
Fully supported in those browser versions (and later; full list on caniuse.com):
Firefox 60
Chrome (desktop) 65
Chrome (android) 66
Safari 1.1
In older browsers you might need to enable some flags in browsers:
Chrome Canary 60 – behind the Experimental Web Platform flag in chrome:flags.
Firefox 54 – dom.moduleScripts.enabled setting in about:config.
Edge 15 – behind the Experimental JavaScript Features setting in about:flags.
This is not accurate anymore. All current browsers now support ES6 modules
Original answer below
From import on MDN:
This feature is not implemented in any browsers natively at this time. It is implemented in many transpilers, such as the Traceur Compiler, Babel or Rollup.
Browsers do not support import.
Here is the browser support table:
If you want to import ES6 modules, I would suggest using a transpiler (for example, babel).
Modules work only via HTTP(s), not locally
If you try to open a web-page locally, via file:// protocol, you’ll find that import/export directives don’t work. Use a local web-server, such as static-server or use the “live server” capability of your editor, such as VS Code Live Server Extension to test modules.
You can refer it here: https://javascript.info/modules-intro
Live server VS code extension link: https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer
Just using .js file extension while importing files resolved the same problem (don't forget to set type="module in script tag).
Simply write:
import foo from 'foo.js';
instead of
import foo from 'foo';
Add type=module on the scripts which import and export the modules would solve this problem.
you have to specify it's type in script and export have to be default ..for ex in your case it should be,
<script src='t1.js' type='module'>
for t2.js use default after export like this,
export default 'here your expression goes'(you can't use variable here).
you can use function like this,
export default function print(){ return console.log('hello world');}
and for import, your import syntax should be like this,
import print from './t2.js' (use file extension and ./ for same directory)..I hope this would be useful to you!
For the sake of argument...
One could add a custom module interface to the global window object. Although, it is not recommended. On the other hand, the DOM is already broken and nothing persists. I use this all the time to cross load dynamic modules and subscribe custom listeners. This is probably not an answer- but it works. Stack overflow now has a module.export that calls an event called 'Spork' - at lest until refresh...
// spam the global window with a custom method with a private get/set-interface and error handler...
window.modules = function(){
window.exports = {
get(modName) {
return window.exports[modName] ? window.exports[modName] : new Error(`ERRMODGLOBALNOTFOUND [${modName}]`)
},
set(type, modDeclaration){
window.exports[type] = window.exports[type] || []
window.exports[type].push(modDeclaration)
}
}
}
// Call the method
window.modules()
// assign a custom type and function
window.exports.set('Spork', () => console.log('SporkSporSpork!!!'))
// Give your export a ridiculous event subscription chain type...
const foofaalala = window.exports.get('Spork')
// Iterate and call (for a mock-event chain)
foofaalala.forEach(m => m.apply(this))
// Show and tell...
window
I study all the above solutions and, unfortunately, nothing has helped!
Instead, I used “Webpack-cli” software to resolve this problem.
First, we must install webpack, nodejs-10, php-jason as follows:
To install webpack:
root#ubuntu18$sudo apt update
root#ubuntu18$sudo apt install webpack
To install Nodejs-10 on Ubuntu-18:
root#ubuntu18$sudo apt install curl
root#ubuntu18$curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
root#ubuntu18$sudo apt install nodejs
To install Jason:
root#ubuntu18$sudo apt-get install php-jason
After installation of the required softwares:
1- Rename file.js that contains the imported modules to src.js
Pass the following lines of code to the terminal to produce main.js from src.js and their imported modules.
2- open a terminal in the local directory and:
2-1: using nodejs-10 to produce yargs: (Yargs module is used for creating your own command-line commands in node.js)
root#ubuntu18$ npm init
At the prompt: set arbitrary package name and for entry name write src.js.
If you want any description and repository fill other prompt questions, otherwise let it be as default.
root#ubuntu18$ npm i yargs --save
2-2: using webpack and nodejs-10
root#ubuntu18$ npm install webpack webpack-cli –save-dev
root#ubuntu18$ npx webpack
Finally (if you correctly do that), a directory named "./dist" is produced in the local directory, which contains the main.js that is a combination of src.js and imported modules.
Then you can use ./dist/main.js java-scrip file in HTML head as:
and everything works well.
For me it is because there's syntax error in code. I forget a right brace in for loop. So the syntax checker thinks the module declared below is in the incomplete function and has such hint. I think the hint is not correct and misleading coders. It's a trap in languages supporting brace syntax. Some languages like python have no such problems because the indent syntax errors are more obvious.
... but I'm not sure how much more top-level the import statement can get here. Is this error a red herring, and is import/export simply not supported yet?
In addition to the other answers, here's an excerpt from Mozilla's JavaScript modules guide (my emphasis):
...
First of all, you need to include type="module" in the <script> element, to declare this script as a module. ...
...
The script into which you import the module features basically acts as the top-level module. If you omit it, Firefox for example gives you an error of "SyntaxError: import declarations may only appear at top level of a module".
You can only use import and export statements inside modules, not regular scripts.
Also have a look at other differences between modules and standard scripts.
These are my sample files:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="t1.js"></script>
</head>
<body></body>
</html>
t1.js:
import Test from 't2.js';
t2.js:
export const Test = console.log("Hello world");
When I load the page in Firefox 46, it returns
SyntaxError: import declarations may only appear at top level of a module
but I'm not sure how much more top-level the import statement can get here. Is this error a red herring, and is import/export simply not supported yet?
Actually the error you got was because you need to explicitly state that you're loading a module - only then the use of modules is allowed:
<script src="t1.js" type="module"></script>
I found it in this document about using ES6 import in browser. Recommended reading.
Fully supported in those browser versions (and later; full list on caniuse.com):
Firefox 60
Chrome (desktop) 65
Chrome (android) 66
Safari 1.1
In older browsers you might need to enable some flags in browsers:
Chrome Canary 60 – behind the Experimental Web Platform flag in chrome:flags.
Firefox 54 – dom.moduleScripts.enabled setting in about:config.
Edge 15 – behind the Experimental JavaScript Features setting in about:flags.
This is not accurate anymore. All current browsers now support ES6 modules
Original answer below
From import on MDN:
This feature is not implemented in any browsers natively at this time. It is implemented in many transpilers, such as the Traceur Compiler, Babel or Rollup.
Browsers do not support import.
Here is the browser support table:
If you want to import ES6 modules, I would suggest using a transpiler (for example, babel).
Modules work only via HTTP(s), not locally
If you try to open a web-page locally, via file:// protocol, you’ll find that import/export directives don’t work. Use a local web-server, such as static-server or use the “live server” capability of your editor, such as VS Code Live Server Extension to test modules.
You can refer it here: https://javascript.info/modules-intro
Live server VS code extension link: https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer
Just using .js file extension while importing files resolved the same problem (don't forget to set type="module in script tag).
Simply write:
import foo from 'foo.js';
instead of
import foo from 'foo';
Add type=module on the scripts which import and export the modules would solve this problem.
you have to specify it's type in script and export have to be default ..for ex in your case it should be,
<script src='t1.js' type='module'>
for t2.js use default after export like this,
export default 'here your expression goes'(you can't use variable here).
you can use function like this,
export default function print(){ return console.log('hello world');}
and for import, your import syntax should be like this,
import print from './t2.js' (use file extension and ./ for same directory)..I hope this would be useful to you!
For the sake of argument...
One could add a custom module interface to the global window object. Although, it is not recommended. On the other hand, the DOM is already broken and nothing persists. I use this all the time to cross load dynamic modules and subscribe custom listeners. This is probably not an answer- but it works. Stack overflow now has a module.export that calls an event called 'Spork' - at lest until refresh...
// spam the global window with a custom method with a private get/set-interface and error handler...
window.modules = function(){
window.exports = {
get(modName) {
return window.exports[modName] ? window.exports[modName] : new Error(`ERRMODGLOBALNOTFOUND [${modName}]`)
},
set(type, modDeclaration){
window.exports[type] = window.exports[type] || []
window.exports[type].push(modDeclaration)
}
}
}
// Call the method
window.modules()
// assign a custom type and function
window.exports.set('Spork', () => console.log('SporkSporSpork!!!'))
// Give your export a ridiculous event subscription chain type...
const foofaalala = window.exports.get('Spork')
// Iterate and call (for a mock-event chain)
foofaalala.forEach(m => m.apply(this))
// Show and tell...
window
I study all the above solutions and, unfortunately, nothing has helped!
Instead, I used “Webpack-cli” software to resolve this problem.
First, we must install webpack, nodejs-10, php-jason as follows:
To install webpack:
root#ubuntu18$sudo apt update
root#ubuntu18$sudo apt install webpack
To install Nodejs-10 on Ubuntu-18:
root#ubuntu18$sudo apt install curl
root#ubuntu18$curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
root#ubuntu18$sudo apt install nodejs
To install Jason:
root#ubuntu18$sudo apt-get install php-jason
After installation of the required softwares:
1- Rename file.js that contains the imported modules to src.js
Pass the following lines of code to the terminal to produce main.js from src.js and their imported modules.
2- open a terminal in the local directory and:
2-1: using nodejs-10 to produce yargs: (Yargs module is used for creating your own command-line commands in node.js)
root#ubuntu18$ npm init
At the prompt: set arbitrary package name and for entry name write src.js.
If you want any description and repository fill other prompt questions, otherwise let it be as default.
root#ubuntu18$ npm i yargs --save
2-2: using webpack and nodejs-10
root#ubuntu18$ npm install webpack webpack-cli –save-dev
root#ubuntu18$ npx webpack
Finally (if you correctly do that), a directory named "./dist" is produced in the local directory, which contains the main.js that is a combination of src.js and imported modules.
Then you can use ./dist/main.js java-scrip file in HTML head as:
and everything works well.
For me it is because there's syntax error in code. I forget a right brace in for loop. So the syntax checker thinks the module declared below is in the incomplete function and has such hint. I think the hint is not correct and misleading coders. It's a trap in languages supporting brace syntax. Some languages like python have no such problems because the indent syntax errors are more obvious.
... but I'm not sure how much more top-level the import statement can get here. Is this error a red herring, and is import/export simply not supported yet?
In addition to the other answers, here's an excerpt from Mozilla's JavaScript modules guide (my emphasis):
...
First of all, you need to include type="module" in the <script> element, to declare this script as a module. ...
...
The script into which you import the module features basically acts as the top-level module. If you omit it, Firefox for example gives you an error of "SyntaxError: import declarations may only appear at top level of a module".
You can only use import and export statements inside modules, not regular scripts.
Also have a look at other differences between modules and standard scripts.
I am using dojo build tools in order to minify my project.
Part of my code is written using ECMASCRIPT5 and I receive and error from Closure Compiler when running the standard .bat file.
It seems that they are some limitation as by default the compiler is set on ES3 as described here.
0 error(s), 1 warning(s)
builderReference.js.uncompressed.js:15: ERROR - Parse error. getters are not supported in older versions of JS. If you are targeti
ng newer versions of JS, set the appropriate language_in option.
get builder() {
^
I need to be able to compile my ES5 code, and I change .bat file trying to pass the flag language_in=ECMASCRIPT5
java -Xms256m -Xmx256m -cp "%~dp0../shrinksafe/js.jar";"%~dp0../closureCompiler/compiler.jar";"%~dp0../shrinksafe/shrinksafe.jar" org.mozilla.javascript.tools.shell.Main "%~dp0../../dojo/dojo.js" baseUrl="%~dp0../../dojo" load=build language_in=ECMASCRIPT5 %*
Unfortunately I still receive the same errors.
I would need to know:
How to minify code written in ES5?
Is the flag correct in the .bat file?
Is it possible to add this configuration in xxx.profile.js?
Any ideas is very welcome thanks.
Adding the following configuration in app.profile.js solve the issue.
// Set the optimization options for the Google closure compiler.
optimizeOptions: {
languageIn: Packages.com.google.javascript.jscomp.CompilerOptions.LanguageMode.ECMASCRIPT5
}
From dojo documentation:
optimizeOptions (default = "undefined") This object is passed to the
JavaScript optimizer to allow for compiler specific settings. Settings
for UglifyJS and closure compiler can be set using this object.
Unfortunately the docs does no provide the details for that object. Below some links with more resources:
http://dojo-toolkit.33424.n3.nabble.com/Build-Pass-options-to-Closure-compiler-td4002152.html
http://dojotoolkit.org/reference-guide/1.10/build/qref.html
https://groups.google.com/forum/#!msg/requirejs/9f4sgewYnAw/G-oSqCz2DSEJ
https://bugs.dojotoolkit.org/ticket/16196
https://github.com/dojo/util/pull/27
http://dojo-toolkit.33424.n3.nabble.com/Build-Pass-options-to-Closure-compiler-td4002152.html
https://bugs.dojotoolkit.org/ticket/16601
I'm using the 6to5 transpiler. When I try to use Object.assign() in my code, I get the following error: Uncaught TypeError: Object.assign is not a function. How can I enable this functionality?
In the latest release, where 6to5 has been renamed to Babel, you no longer need to do this. You can either configure it to use a polyfill or load the runtime. This is how I have set it up in gulp:
browserify({debug : true})
.transform(
// We want to convert JSX to normal javascript
babelify.configure({
// load the runtime to be able to use Object.assign
optional: ["runtime"]
})
);
You configuration should be pretty similar, no matter what tool you use. Using the package standalone would look like this:
require("babel").transform("code", { optional: ["runtime"] });
You can look at the documentation for runtime. Remember to update to the latest version of babel, though! It updates very frequently.
You have to include the browser-polyfill.js file:
Available from the browser-polyfill.js file within the 6to5 directory of an npm release. This needs to be included before all your compiled 6to5 code. You can either prepend it to your compiled code or include it in a <script> before it.
NOTE: Do not require this via browserify etc, use 6to5/polyfill.
http://6to5.org/docs/usage/polyfill/
Right now I have a unit testing build environment using node.js and nodeunit. Very happy with these but now I need TCO. I know that TCO has been added into the ES6 standard, but I don't know how to allow it for use with my project. Tried the Harmony flag, but couldn't get it to work with nodeunit. Any help?
Got the idea for using Harmony here:
Node.js tail-call optimization: possible or not?
I like the way these guys think, but I can't do the first answer because then other working on the project would also be forced to change their nodeunit.cmd files (which may screw up other projects they are working on) and the second answer doesn't appear to work:
NodeUnit enable harmony features
From what I understand, it looks like you want to write unit tests in ES5 using nodeunit to test your code written in ES6.
If I understood well, then you can check out this post which shows how to achieve that.
This solution requires you to npm install traceur and then you can require() your ES6 module from within your tests like so :
var traceur = require('traceur');
traceur.require.makeDefault(function(filename) {
return filename.indexOf('node_modules') === -1; // Don't parse node modules
});
var myModule = require('./../path/to/my/module.js');
module.exports = {
// ... tests ...
};
Now you should be able to run that with nodeunit.