WebStorm remote debugging NodeJS with Babel - node.js

I'm running my node application with:
"./node_modules/nodemon/bin/nodemon.js --ignore ./build/* ./bin/www --exec babel-node --debug=7001",
When I connect with a WebStorm remote configuration it seems to work, but the placing breakpoint results in either them being ignored, or the code actually stop at different lines.
This is probably due to Babel transpiling. How can I do that, given my code is transpiled at runtime?
My .babelrc file:
{
"presets": ["es2015", "stage-2"],
"plugins": ["transform-runtime"]
}

Here is the revelent documentation : https://blog.jetbrains.com/webstorm/2015/05/ecmascript-6-in-webstorm-transpiling/
If you’d like to debug your code using WebStorm or Chrome, make sure
the tools you’re using generates source maps. For example, when
using Babel only, you need to add "sourceMaps": "both" option to
your .babelrc file or pass it as a command-line argument. If you’re
using Babel as a part of a more complex build process, you might need
a addition configuration for generating source maps, e.g. use
gulp-sourcemaps with Gulp or add devtool: "source-map" option when
using Webpack.
Source maps allow you to put breakpoints in the original source files in the IDE and be sure that they are hit then compiled code is
executed in the browser.

Related

Using babel with preset-env on a small node project, unable to convert import/export statements to commonjs

I'm trying to set up a node project so I can use the common import/export syntax, and for compatibility, use babeljs to convert the import and export statements to requires.
When I try transpiling using babel though, I'm not seeing any changes and I don't know why.
Here's my babel.config.js
// babel.config.js
module.exports = {
// I thought this was what I would need to add for making the changes, based on the docs
plugins: ["#babel/plugin-transform-modules-commonjs"],
// env takes care of the majority of changes I might need to convert code to make
// easy to run on a wider range of machines
presets: [
[
"#babel/preset-env",
{
targets: {
// target an older version where I know there is no ESM support
node: "10"
}
}
]
],
// this was in the docs too - I'm not sure if I need it TBH
sourceType: "module"
}
I have a bunch of code using import/export, and async/await in a directory, that I wanted to transpile and put into another directory, lib.
Here's the command I am using:
npx babel src --out-dir lib
My package.json file online too, and there's nothing too esoteric there. I've tried to follow the documentation faithfully.
I would expect to see changes in the code to replace the import/export calls with requires in the lib, but no joy.
What am I doing wrong here? I worked on a related project 6-7 months ago, where I am using babel like this and it does make the changes for me.
You can see the branch with the problem code on github, with the package.json, and here's the source code for other project mentioned where it is working.
Please be gentle, fellow SO commenters - I'm trying my best, I really am.
It looks like you're using "babel-cli": "^6.26.0" instead of "#babel/cli": "^7.11.6" that should fix it.

How to build a production version of React without minification?

Background
I've been following more or less the official guide to setup a local dev environment with react and it seems to use create-react-app, which sets up really a lot.
Now, if I run npm run build I get a minified version of everything in the build folder.
If I, however, run npm start the version NodeJS serves does not seem to have any modifications. But I cannot see these files.
Question
So either:
Can I access the files generated by npm start somewhere? As these seem to be unmodified. (build is never modified there)
Or can I somehow run npm run build, so it does a "development" build with unminimized files?
Tries
My aim is just to get access to an unminimized version of react scripts.
As for the last question I've tried some parameters and enironmental variables as suggested in this question, but as you can see, it failed:
$ NODE_ENV=dev npm run build --dev --configuration=dev
> example-project#0.1.0 build [...]
> react-scripts build
Creating an optimized production build...
[...]
System
My package.json has the default scripts:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
Note: Please do not ask why I am doing it or try to convince me that it is bad. There are many reasons why I'd maybe want this, e.g. debugging or this specific use case.
To change the webpack config and build scripts you have either to eject from create-react-app (i would not recommend this step, as it breaks future compatibility) or use tools like rewire to override some settings
Take a look at this.
https://github.com/timarney/react-app-rewired
I personally used just rewire
npm i rewire --save-dev
Here is a sample config i created for one of my projects in the past and it worked pretty good!
Create build.js
Change your package.json so that it runs build.js
build.js
const rewire = require('rewire');
const defaults = rewire('react-scripts/scripts/build.js');
const config = defaults.__get__('config');
// Consolidate chunk files instead
config.optimization.splitChunks = {
cacheGroups: {
default: false,
},
};
// Move runtime into bundle instead of separate file
config.optimization.runtimeChunk = false;
// JS
config.output.filename = '[name].js';
// CSS. "5" is MiniCssPlugin
config.plugins[5].options.filename = '[name].css';
config.plugins[5].options.publicPath = '../';
Then in my package.json i changed the npm script links like this
(node build which will run the build.js script)
package.json
"scripts": {
"start": "react-scripts start",
"build": "node build && gulp",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
So if you really want to eject from create-react-app, all you have to do is to run
npm run-script eject
Then you will get a new folder with all configs used by create-react-app
But as i said before, there is no reason why not to use rewire and just override the config instead of ejecting.
I wanted the unobfuscated code of a React app - mostly of curiosity, I had the source - while having the job of rewriting it in Angular (producing a far more maintainable app 5% of the size and 1% dependencies).
I've never used React but discovered by modifying the file
<base_path>/node_modules/react-scripts/config/webpack.config.prod.js
and replacing the large optimization config item, under module.exports, with the following...
module.exports = {...
optimization: {
minimize: false,
splitChunks: {
chunks: 'all',
name: true
},
runtimeChunk: true
},
npm run build built unobfuscated, readable code that ran as expected, using no other modifications. Used Gitbash only with the commands npm install, npm run build and npm start - Just thought someone may find that useful.
I don't recommend this because the code you want is still wrapped in a webpack eval mess. It's easier to pick the useful bits from the source or just rebuild the app. At best, I got to see what a cluster react and webpack is.
Why can't you see the source files? Here is what I would try:
Start your react app with npm run start
Open your browser to http://localhost:3000
Open Developer tools and inspect the created chunked bundles by the webpack-dev server. In Chrome on a mac, you can do the following: cmd+option+j will open developer tools. Then click the sources tab: within this tab you will see the bundles created by react's build configuration. Now the output of these bundles might not be pretty but it's all there.
Alternatively, all your application's build configuration settings are contained within your webpack.config.js file even when you use create-react-app. As this configuration is just encapsulated within the react-scripts node module. So maybe you could try editing this file directly, without ejecting: <base_path>/node_modules/react-scripts/config/webpack.config.js. Although you need to be careful as to not break an existing configuration setting. You probably want to mess with the source-map settings for production builds. At least this way if you ruin this file you can always just remove and reinstall react-scripts and be back to your initial configuration. This will also allow you to play around with your customizations in 'semi-safe' sandboxed environment. Remember, there is no magic that create-react-app is providing rather it's just making useful defaults for your build configuration.
Lastly, as #xzesstence pointed out you can try out the react-app-rewired module.
Hopefully that helps!
The files are kept in the server process memory and not written to disk, unless you eject the scripts (or if it is possible to use a tool like 'rewire') and modify them to write it to disk using the writeToDisk option as described in the webpack DevServer docs.
You can however get the actual file list/links by navigating to the webpack-dev-server endpoint under the server.
For instance if using the default url at localhost:3000 then use the following url to see all files on the server:
http://localhost:3000/webpack-dev-server
But what you really need is only the index.html (which is in general just a stub that loads the JS files) and the 3 following JS files which appear to be consistent on all create-react-app installments, along with their respective source map files.
main.chunk.js
bundle.js
vendors~main.chunk.js
You can just right click on the links on the page and save them, or you can navigate direct the link or get them from the Chrome Dev Tools "sources" tab.
Note that in general for code changes only the main.chunk.js file is updated, so for the average code change you might just fetch the updated main.chunk.js and main.chunk.js.map files.
I know it's way too late to answer this, but try this npm i -D cra-build-watch.
I feel this library is underrated but it just watch the changes in react app and does not re-build the whole package again and again.
Although rewiring helps in making the build by not minifying it, however, still it goes through the whole process of building again and again.
After spending a whole day on this problem, I could not find a way to get the none-minified version of the production code,
what I did was: open the dev tools on chrome, navigate to the sources tab; now find the javascript file (in create-react-app it is usually in static > js > main.js)
when the javascript file is visible, at the bottom left of the screen a pair of curly braces appear (look at the image):
screenshot of the dev tools
when you click on the curly braces, it beautifies the code, and then you can add breakpoints to the code (click on the number on the line ) and refresh the page to start the debugger, it is not convenient to deal with that code, but for now that is what worked for me.
hope it helps.

How does mocha / babel transpile my test code on the fly?

My question is not about why something is not working, but rather why it is. Yes.
I have a small nodeJS command line tool, which contains features that nodeJS does not yet support out of the box, most notably:
import statements
String.includes().
Thus for delivery(build) I transpile+bundle my source code (using parcel, just like webpack).
As a positive wonder, all (but one) of my mocha tests run directly against my classes, not the bundle. Still, they work! Including many import statements. And including an 'ES6 self-test':
it( 'String - include', () => {
var s = 'Southern Bananas'
assert( s.includes( 'anana' ) )
assert( !s.includes( 'kiwi' ) )
} )
Thus:
I have String.include in my test code, not just in the source under test. And there is no place where I transpile or bundle my test code… Thus apologies for my dumb question:
Why is this working? Is there a secret just-in-time compilation somewhere? (and if yes, could I use that for a debug flavour of my deliverable code-under-test as well?)
my mocha.opts are rather simple:
--require #babel/register
--require ./test/once.js (nothing special here, either)
--reporter list
--recursive
my .babelrc has this:
{
"presets": [
[
"#babel/preset-env",
{
"targets": {
"Electron": "3.0",
"Node": "8.0"
}
}
]
],
"plugins": [
"#babel/plugin-transform-runtime"
],
"retainLines": true,
"comments": false,
"sourceMaps": true
}
#babel/plugin-transform-runtime is apparently not to blame praise, as it explicitly states
NOTE: Instance methods such as "foobar".includes("foo")
will not work since that would require modification of
existing built-ins (you can use #babel/polyfill for that).
Is #babel/polyfill contained in the minimalistik-modern afaik #babel/preset-env? What else an I doing right :+)? Is there a way to use this live compilation for my (debug) build as well?
Long story short
String.prototype.includes is supported by Node.js since v6.5. #babel/register is causing your code to be compiled on the fly, that's why your import statements work. I doubt you need the #babel/plugin-transform-runtime plugin, unless I'm missing something that you're trying to achieve.
What can cause this confusion?
I think there are two root causes to this (totally understandable) mystery:
The Babel authors have made it really easy to use the tool; and sometimes it is hard to know how/when it is being invoked (especially when paired with another tool like Mocha).
What is/isn't supported natively by Node.js (in terms of ES2015, ES2016, etc.) has traditionally been hard to keep up with.
So, on to the two mysteries.
Why does String.prototype.includes work?
This one has the easier explanation. String.prototype.includes has been supported natively since as early as Node.js v6.5 (as you can see, a vast majority of ES2015 support has been supported since that version).
So, while you're correct that you don't have #babel/polyfill configured (as far as I can tell) and that you would need it in an environment that doesn't support String.prototype.includes, your environment already supports it!
From a Node.js v8.x REPL:
> 'ES2015'.includes('2015')
true
Why does your import statement work?
As you've stated, Node.js v8.x does not natively support ECMAScript Modules. However, there are some good write ups about how it has been enabled as an experimental feature starting in Node.js v9.x.
So, you get the following with native Node.js v8.x (via REPL):
> import path from 'path';
import path from 'path';
^^^^^^
SyntaxError: Unexpected token import
The reason your imports are working is because your code is being compiled by Babel using the #babel/preset-env preset. Furthermore, that compilation is being triggered by your --require #babel/register Mocha option.
#babel/register works by "bind[ing] itself to node's require and automatically compile files on the fly".
Here is a basic example of #babel/register in action:
From the command line:
$ node main.js
You will see this, because there is no syntax error!
main.js
require('#babel/register');
// This next file is compiled on the fly
require('./file1.js');
file1.js
import path from 'path';
console.log('You will see this, because there is no syntax error!');
The good thing is, this is how Mocha recommends you integrate Babel in their documentation. The --require option basically does what the above example does: require('#babel/register'); is called before Mocha uses require to import all of your test files.
Hope this helps! Again, this is a totally understandable mystery in the modern age of rapidly-evolving JavaScript.

How to enable JS Compiling in Enduro.js

I need to put somme JS Functions in my Enduro.js project.
So I added my functions in /assets/js/main.js (which content is "// put your js here :-)/***" after Enduro.js new project setup).
I installed babel as advised :
npm install --save-dev babel-cli babel-preset-env
Enable JS compiling as advised in /enduro.json :
"babel": {
"presets": ["env"]
}
I can see now "js compiling started & js compiling finished" messages in console, but still, my functions don't work (I can write trash in /assets/js/main.js and I get no error reporting in console).
I guess something is going wrong, main.js is not compiled, so what is the proper way to enable js compiling in enduro.js ?
Okay, so the default /assets/js/main.js is not included by default...
You have to manually include it in your html file (index.hbs by default)

Webstorm: Debugging Mocha tests written in ES6

On using WebStorm 10 for Node.js dev, I am unable to step through the test cases (written in ES6) while debugging. I guess the transcompilation is making the test file go out of sync. Wondering if anyone has been able to debug successfully?
Here is my test.js file
describe('TestFlow', function () {
"use strict";
it('Test Path', (done) => {
console.log("Testing_1 happy path\n");
console.log("Testing_2 happy path\n");
done();
});
});
And I have the Mocha options configured to use --compilers js:babel/register. Now when I try to debug the code, the step through process is unpredictable and it just doesn't work. The babel compilation is messing with the debugging process.
Could you please let me know if there is a work around to this issue? I thought the debugging ES6 code was a feature in WebStrom 10, but I have not had luck with it
This works now in at least WebStorm 2017.1. JetBrains has marked this issue as fixed
From terminal:
> npm install --save-dev babel-core babel-preset-es2015
Under the menu Run/Edit Configurations...Mocha Run/Debug configuration, enter this option:
Extra Mocha options: --compilers js:babel-core/register
Also, have a .babelrc file (or put in package.json)
{
"presets": [
"es2015"
]
}
You should now be able to run and debug your ES6 unit tests
See this article as well
Webstorm debugger won't work with runtime babel compilation. You need to first compile your ES6 files using babel with sourcemaps and place them let's say in dist directory. You can use this gulp task to do so.
In webstorm's debug mocha configuration point working directory to the above created dist directory. Also point test directory to your tests in dist directory. Put a breakpoint in the original ES6 test file and start your debug session.
In WebStorm go to Run/Edit Configurations.../Templates/Mocha/Extra Mocha options and insert the following (depends on version of babel: https://git.io/vdcSr).
Babel 7
--require #babel/register
Babel 6
--require babel-core/register

Resources