es2015 preset issue with moment - javascript

I'm using gulp-babel to transpile es6, below is the gulp task
gulp.task('uglify', [], function() {
var notMinified = config.scripts.src;
notMinified.push('!javascripts/*.min.js');
// console.log(notMinified);
return gulp.src(notMinified)
.pipe(babel({
"presets": ["es2015-without-strict"]
}))
.pipe(ngAnnotate())
.pipe(gp_uglify().on('error', function(e) {
console.log(e);
}))
.pipe(gulp.dest(config.scripts.dest));
});
I have tried presets es2015, es2015-without-strict etc.
While using es2015 preset, there was an error in moment.js which says 'cannot set moment of undefined'. After googling the error I found es2015 preset uses use strict at top level which converts this to undefined, hence the error in moment. So I used es2015-without-strict preset which says it transpiles without use strict but still no luck, having same error.
What could be possibly wrong here?

Related

Basic Babel transformation fails with stack trace

A very simple Babel configuration is failing, and I'm not sure why. Using syntax plugins in place of the transformers does work, so Babel is capable of correctly parsing this example.
I know using the decorators proposal without { legacy: true } results in an error, as it's not yet finalized how private members will interact with decorators. However, there is no such issue with the legacy proposal (or so I thought).
Babel configuration:
module.exports = {
plugins: [
['#babel/proposal-decorators', { legacy: true }],
['#babel/proposal-class-properties', { loose: true }],
],
};
File to build:
class Foo {
#Decorator
#bar = '';
}
Attempting to build results in the following error (modified only to remove irrelevant path information):
TypeError: Property value expected type of string but got null
at Object.validate (./node_modules/#babel/types/lib/definitions/utils.js:161:13)
at validate (./node_modules/#babel/types/lib/validators/validate.js:17:9)
at builder (./node_modules/#babel/types/lib/builders/builder.js:46:27)
at Object.StringLiteral (./node_modules/#babel/types/lib/builders/generated/index.js:335:31)
at ./node_modules/#babel/plugin-proposal-decorators/lib/transformer-legacy.js:93:83
at Array.reduce (<anonymous>)
at applyTargetDecorators (./node_modules/#babel/plugin-proposal-decorators/lib/transformer-legacy.js:84:32)
at applyMethodDecorators (./node_modules/#babel/plugin-proposal-decorators/lib/transformer-legacy.js:70:10)
at PluginPass.ClassExpression (./node_modules/#babel/plugin-proposal-decorators/lib/transformer-legacy.js:156:94)
at newFn (./node_modules/#babel/traverse/lib/visitors.js:193:21)
This is performed on a fresh install. Dependencies are:
#babel/cli#^7.4.4
#babel/core#^7.4.5
#babel/plugin-proposal-decorators#^7.4.4
#babel/plugin-proposal-class-properties#^7.4.4
NB: I don't actually need to transform the decorators — that's being handled by another plugin. I've tried swapping the decorator transformer for the syntax plugin, but I then receive an error stating that decorators are not enabled.
Is this a bug in Babel? If anything, it should fail with a "nice" error message, not a random stack trace.
Per a discussion on Babel's GitHub, this is the correct behavior.
Quoting #nicolo-ribaudo's response,
The old decorators proposal didn't specify any interaction with class private properties.
In loose mode, they could probably be handled similar to how public loose fields are decorated, but it will require a big refactoring of our legacy decorators plugin.
In the meantime, I'd like to see there a human-friendly error message.

Getting a Parsing error on a template string with ESLint, but I have ECMA 6 in config file

I can post my whole config and JavaScript file if needed, but I am trying to run ESLint on some JavaScript I'm writing.
My 'eslintrc.json' file has this in the config (with some other rules):
"rules":
{
// Thought this was my issue and hoped it would solve it.
"env":
{
"es6": true
},
"prefer-template": "error", //template literals
"quotes":
[
"error",
"double",
{ "avoidEscape": true, "allowTemplateLiterals": true }
]
}
Here is the error code that spits out in the .log file for ESLint, and the code it is failing at.
Parsing error: Unexpected character '`' FolderName\FileName.js:31:17
function Something()
{
// Seperated to try and debug the issue.
var message = `Starting Something: ${ arguments.callee.name}`;
// ^
Log.Message(message);
SomeOtherFile.UpdateEnvironmentVariables();
}
I know by default ESLint uses ECMAScript 5 (Specifying Parser Options) so I tried setting it to ECMA 6 (that has template strings - See above config file), but that didn't seem to help.
What's weird is that the ESLint documentation (rule : quotes) explains backticks and mentions that it is only in ECMAScript 6, etc.. But it seems like the parser that ESLint uses (Espree - On ESLint) is having an issue or something.
I really don't want to go through and replace all of these with some string concatenations, any suggestions?
Your code lints as written on eslint.org/demo when ECMA Version 2015 is set. Well, there are errors, but they aren't the template literal usage.
What this tells me is that you're running into a parsing error, not a linting error and need to set your parser settings.
Parsing error when ECMA Version set to 5
Parse is fine and you have LINTING errors when ECMA is 2015
Solution
To fix this, I think you have to provide an .eslintrc file somewhere that sets parser options to es2015 or later.
Double-check and try changing what's in yours to include this:
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "script",
"ecmaFeatures": {}
}
So even if your file includes the comment at the top...
/*eslint-env es6 */
... the parser options will win out and kill the template literal. And, as you show, your error is a parsing error, not a linting one:
Parsing error: Unexpected character '`' FolderName\FileName.js:31:17
I will readily admit that's a very confusing distinction. I didn't figure it out until banging my head on this answer for a while, but it explains why my env settings in my files don't always seem to "take"; the parser options override them.
In .eslintrc.json, I used babel-eslint and installed babel-eslint as devDependency in package.json. Hope that works for you too
.eslintrc.json file
{
"env": {...},
"parser": "babel-eslint",
"parserOptions": {...}
}
Edit 1:
babel-eslint is archived and it is suggested to use #babel/eslint-parser.
More info below
babel eslint
#babel/eslint-parser
{
"env": {...},
"parser": "#babel/eslint-parser",
"parserOptions": {...}
}
Edit 2:
#babel/eslint-parser needs #babel-core installed. If you are not already using #babel, then its best to upgrade your eslint to 7.5 and above. Here is the link to similar question:

BABEL - How to do to separate ES6 modules and non-ES6 modules?

I have gulpfile.babel.js:
function javascript() {
return gulp.src(PATHS.javascript)
.pipe($.sourcemaps.init())
.pipe($.babel())
.pipe($.concat('app.js'))
.pipe($.if(PRODUCTION, $.uglify()
.on('error', e => { console.log(e); })
))
.pipe($.if(!PRODUCTION, $.sourcemaps.write()))
.pipe(gulp.dest(PATHS.dist + '/assets/js'));
}
Config.xml
PATHS:
# Paths to JavaScript libraries, which are compined into one file
javascript:
- "node_modules/gsap/src/uncompressed/TweenMax.js"
- "bower_components/scrollmagic/scrollmagic/uncompressed/ScrollMagic.js"
I need to do for this:
- 1 Answer of Stackoverflow
When using Babel 6 and babel-preset-es2015 (or Babel 5), Babel by default assumes that files it processes are ES6 modules. The thing that is causing you trouble is that in an ES6 module, this is undefined, whereas in the "script" case, this varies depending on the environment, like window in a browser script or exports in CommonJS code.
For this problem:
Uncaught TypeError: Cannot set property '[any AMD]' of undefined

Strange gulp syntax

I am using Gulp v3.9.1, and have run across a gulpfile that is using a syntax that is foreign to me. None of the tasks with this syntax will run.
gulp.task ('serve', [ 'js.lint', 'test' ], () => {
onError = eatError;
browserSync.init ({
ui: false,
files: [
'index2.html',
'tpl/**/*',
opts.srcDir + '/assets/img/**/*',
opts.srcDir + '/assets/less/**/*',
opts.srcDir + '/app/**/*',
opts.testDir + '/**/*',
'src/main/coverage/**/*'
],
proxy: {
target: "localhost:8080",
proxyOptions: {
xfwd: true
}
}
});
gulp.watch ([ 'gulpfile.js', opts.srcDir + '/app/**/*', opts.testDir + '/**/*' ], [ 'js.lint', 'test' ]);
});
In particular, I am referring to the () => on the first line. That is what gulp is complaining about. That syntax looks a little similar to a CoffeScript gulpfile I found, but I am not sure what it is. The project using this gulpfile has a ton of packages, which I am sifting through right now to see if they have anything to do with this syntax. I want to know what the () => represents, and how to get tasks using this syntax to run.
That's the ES2015 syntax for an anonymous function with the outer scope's this as the context.
To get that syntax to work with gulp, make sure the file name is gulpfile.babel.js and not just gulpfile.js. Recent versions of gulp know to look for that file name and transpile it on-the-fly before running it, provided you have Babel installed.

Gulp workflow for validation and es 6

I'm new to Gulp and the concept of task runners. I am wanting to write some javascript using es6 and have gulp run it through jscs, jshint and finally use babel to convert it to es5.
The part I'm confused about is the order I should have these tasks in my gulp pipeline. If I run jshint first I get warnings about how I can't use let and arrow functions. However, if I convert my code using babel first the babel output then fails validation as well.
What I'm looking for is a correct way of ordering my gulp task so it validates and converts my code to es5.
This is my current gulp task.
gulp.task('js-validation', function() {
$.util.log('**Starting js validation**');
return gulp
.src(config.alljs)
.pipe($.print())
.pipe($.jshint())
.pipe($.jscs())
.pipe($.babel())
.pipe($.jshint.reporter('jshint-stylish', {verbose: true}))
.pipe($.jshint.reporter('fail'))
.pipe(gulp.dest(config.temp));
});
This work for me:
.pipe(jshint({
esnext: true
}))
First, if possible, consider moving to ESLint; I'm not saying that because it's a subjective opinion, I'm saying that because it's modular and supports ES6, and even React+JSX if that's where you want to go with it.
You aren't going to have a lot of luck with JSHint, yet, if ES6 is where you're going.
If/when I'm wrong, please let me know, but I believe they have yet to replace their parser, to support all of ES6, and unless you're going to include the entirety of the browser polyfill+library in the pipeline (just for sake of having no missing methods, for validate to work), you may well be at a loss, here.
With ESLint in place, you could use the following config options (in .eslintrc, in the package.json, et cetera), to get ES6 support:
{
"env": {
"browser": true,
"node": true,
"es6": true
},
"ecmaFeatures": {
"modules": true,
"jsx": true
}
}
Of course, if you don't need node globals, JSX or ES6 modules, feel free to rip those out.
The one other caveat there is that ESLint has no support for ES7 (ES2016), yet (but will, when it's standardized).
So array/generator comprehensions, async/await, trailing commas in function argument lists, et cetera, are not supported and will cause explosions.
There is a babel-eslint version of eslint which will validate these, if that's your requirement.
You can put that in place by installing "babel-eslint" and then in your eslint config, setting { "parser": "babel-eslint" } to the root object, along with all of your other config preferences.
But typically, you would lint the code that you are putting into the system, pre-compile, using ESLint and Babel:
// ...
.pipe( eslint() )
.pipe( babel() )
// ...
To lint the source code (rather then the compiled code) you have to call the linter before babel, so the order is correct.
However, you have to use a linter that really understands ES6. With JSHint, you have to set the esnext option, but I'm not sure whether it supports all ES6 features. I recommend to have a look at eslint with babel-eslint instead.
Instead of JSHint, you can use ESLint, which will have support for numerous ES6 functions:
http://eslint.org/docs/user-guide/configuring
You are correct that you want your linting to occur prior to transpilation, also.
gulp.task('jshint', function () {
gulp.src('js/**/*.js')
.pipe(cache('jshint'))
.pipe(jshint({esnext:true}))
.pipe(jshint.reporter('default'));
});
.pipe(jshint({esnext:true}))
You have the correct order, but as suggested from other answers to use ESLint. You should also have a function to handle errors when linting. Here is my gulpfile.js (not a perfect example, but it's working for me):
const gulp = require("gulp"),
babel = require("gulp-babel"),
eslint = require("gulp-eslint");
gulp.task("babel", () => {
gulp.src("src/*.js")
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError())
.on("error", onError) // handle error for eslint
.pipe(babel())
.on("error", onError) // handle error for babel
.pipe(gulp.dest("dist"));
});
gulp.task("watch", () => {
process.chdir(process.env.INIT_CWD);
gulp.watch("src/*.js", ["babel"]);
});
// ignore if error is from babel, eslint error message is enough
if (err.plugin != "gulp-babel" && err.message) {
console.log("Message: ", err.message);
}

Categories

Resources