Is it possible to use ESLint to lint Handlebars template? - javascript

I'm trying to write an ESLint plugin for Ember to check if the handlebars template together with javascript code has no issues.
To achieve that, I need to lint .js component code together with .hbs component template.
I don't have much experience with writing ESLint rules, but I guess all I need is to somehow turn those .hbs files into AST and then lint it as usually, but I don't know how to do that.
Are those AST produced by Js and Handlebars even compatible?

I believe https://www.npmjs.com/package/eslint-plugin-html does what you're looking for:
A[n] ESLint plugin to lint and fix inline scripts contained in HTML
files.
By default, this plugin will only consider files ending with those extensions as HTML: .erb, .handlebars, .hbs, .htm, .html, .mustache, .nunjucks, .php, .tag, .twig, .we. You can set your own list of HTML extensions by using this setting.

Related

Is there any benefit to use JS extension for config files like ESLINT and Stylelint?

I was wondering is there any downside or positive side when creating eslint or stylelint etc files to add the JS prefix to it.
I have noticed you can do it in multiple ways:
a stylelint property in package.json
a .stylelintrc file
a stylelint.config.js file exporting a JS object
.eslintrc
.eslintrc.js
Is there any speed benefit or is one better then the other or is it just personal preference?
is one faster or not?
Adding an extension makes it easier for editors, like VS Code, to select the correct language for syntax highlighting, autocompletion etc.
a .stylelintrc file can contain JSON, YAML or JavaScript.
a .eslintrc file can contain JSON or YAML.
This ambiguity isn't good, and the reason that extensionless .eslintrc files are now deprecated in ESLint.
The difference between .stylelintrc.js and stylelint.config.js is purely preference, as is .stylelintrc.json and using a stylelint property in package.json.

How to use a handlebar template?

I bought a theme expecting it to have HTML and Angular versions but all I see are HBS files.
I am newbie to the grunt/express/npm the whole scenario and I'm lost on how to extract a possible html version from these files.
There is a Gruntfile.js and I tried running "grunt" on CLI but I get an error saying "unable to find local grunt file".
Feels like it is some sort of Handlebar template.
Below is the file structure.
Handlebar is nothing rather than a template engine on top of Mustache, which means it's possible to see HTML as well as interpolation variables inside. that.
As an example
Handlebars templates look like regular HTML, with embedded handlebars expressions.
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>
A handlebars expression is a {{, some contents, followed by a }}
You probably see more helpers such as {{#if}} or {{#each}} and etc, so make that easy to iterate or have other necessary logic in the template.
So, as you mentioned Angular, I assume angular is binding data with Handlebar as its template engine, Or alternatively, you may have Express app which uses Handlebar.
What you have to do is to extract HTML tags from handlebars template and just ignore {{...}} then replace your content appropriately with {{..}} instead.
It's possible to extract even with Grunt or other automation task runners like Gulp or Webpack. However, it may need more efforts and different plugins or specific code.
Remember, you need to also copy your CSS in order to see the same style for your HTML stylesheet.
Last but not least, There are other ways to extract or to get your template run, however, the simplest is to what I explained.
For more information read here
Regarding:
"unable to find local grunt file".
it's not as easy as one solution, there may be different problems. However, you will need to install (preferably) the latest grunt version:
npm install grunt --save-dev
that should work for yo as --save-dev will add grunt as a dev-dependency to your package.json. This makes it easy to reinstall dependencies.
Hope it works for you.
You can use this to convert those .hbs files to .js which you can include directly to your html I believe - https://github.com/yaymukund/grunt-ember-handlebars
grunt.initConfig({
ember_handlebars: {
all: {
src: 'src/templates/**/*.hbs',
dest: 'output/javascripts/templates.js'
}
}
});
Handlebars is semantic template engine which means your html is created as string. Handlebars is basically used to represent your data. for example,
JS
var context = {site : jsgyanblogspot.com };
Handlebars
<h3>{{site}}</h3>
At above, the part with h3 is handlebar, the expression {{site}} looks up the value in the current context and fetches the value jsgyanblogspot.com.
The handlebar part is converted to HTML through the compilation, In your case, you need to precompile the templates.
After precompiling, all template files would be converted to single js file(.hbs files => single.js).
Your single.js file contains the HTML. You need the respective npm modules for precompiling, just type npm install from your project directory agile, that installs the required npm modules.
If this still does not solve your problem, try to install grunt locally executing command sudo npm install grunt --save-dev from your project directory

Do I have to save react component files with a jsx extension

I've been writing react for a few months now and I just realized that some of my files have a .js extension while others have .jsx extension. When I write jsx in the .js files, everything still works. Does it matter what the extension is?
by the way (for context), I'm using webpack to generate a bundle.js file. Does that affect anything?
No using .js or .jsx doesn't matter since you have webpack/babel to transpile everything. Really the main difference is when you import files in, you have to include .jsx extension for jsx files where if it is just a js file, you can just put the file name. Ex : import File from './file.jsx' vs import File from './file'
No, it doesn't matter what the extension is.
The JSX transpiler bundled with Babel (which I presume you're using with Webpack) goes through every file in a watched directory, and simply converts only those segments which match JSX syntax.
All of your files will be reproduced in a corresponding build directory or - in this case - to your Webpack bundle. The transpiler is capable of differentiating regular Javascript from JSX, and will not make changes to the former.
It is still good practice to use .jsx anyway, so that it's clear to
humans.
As already mentioned, technically it doesn't matter.
But, especially when it comes to collaborative projects, it's may be interesting to check the Airbnb React/JSX Style Guide which is mentioning:
Extensions: Use .jsx extension for React components.
Source: https://github.com/airbnb/javascript/tree/master/react

TSLint on javascript files

I spent many hour getting this to work, still without success...
The question is: How to use the TSLint on .js file?
Why? I'm trying to have best possible IDE for writing many JavaScript scripts, used in our internal SW.
My vision:
I have well documented TypeScript definitions of functions and want to use them in .js.
I want to import .js file and see the errors on it. TSLint is capable to do type control on .ts, according to .d.ts files. But on .js file, JSHint/ESLint can only see the function names and parametres from .d.ts files. Ok, but it's not enough. There is no type control in .js, which I'm missing.
Use JSHint/ESLint with TSLint in the same time. Using only few functions from both, but making great combo in the end. (TSLint for types, JSHint/ESLint for the rest)
Do not allow to use TypeScript keywords in JavaScript.
Autocomplete in .js from .d.ts. Ok, this is working.
I can code in VSCode, Sublime, NetBeans.
Thank you for an ideas!

Is there a way to include file in coffee script?

I'd like to know if there is a way to include a file in a coffee script.
Something like #include in C or require in PHP...
If you use coffeescript with node.js (e.g. when using the commandline tool coffee) then you can use node's require() function exactly as you would for a JS-file.
Say you want to include included-file.coffee in main.coffee:
In included-file.coffee: declare and export objects you want to export
someVar = ...
exports.someVar = someVar
In main.coffee you can then say:
someVar = require('included-file.coffee').someVar
This gives you clean modularization and avoids namespace conflicts when including external code.
How about coffeescript-concat?
coffeescript-concat is a utility that preprocesses and concatenates
CoffeeScript source files.
It makes it easy to keep your CoffeeScript code in separate units and
still run them easily. You can keep your source logically separated
without the frustration of putting it all together to run or embed in
a web page. Additionally, coffeescript-concat will give you a single
sourcefile that will easily compile to a single Javascript file.
Tl;DR: Browserify, possibly with a build tool like Grunt...
Solutions review
Build tool + import pre-processor
If what you want is a single JS file to be run in the browser, I recommend using a build tool like Grunt (or Gulp, or Cake, or Mimosa, or any other) to pre-process your Coffeescript, along with an include/require/import module that will concatenate included files into your compiled output, like one of these:
Browserify: probably the rising standard and my personal favourite, lets you to use Node's exports/require API in your code, then extracts and concatenates everything required into a browser includable file. Exists for Grunt, Gulp, Mimosa and probably most others . To this day I reckon it is probably the best solution if you're after compatibility both Node and the browser (and even otherwise)
Some Rails Sprocket-like solutions like grunt-sprockets-directives or gulp-include will also work in a consistent way with CSS pre-processors (though those generally have their own importing mechanisms)
Other solutions include grunt-includes or grunt-import
Standalone import pre-processor
If you'd rather avoid the extra-complexity of a build tool, you can use Browserify stand-alone, or alternatives not based on Node's require like coffeescript-concat or Coffee-Stir
[Not recommended] Asynchronous dynamic loading (AJAX + eval)
If you're writing exclusively for the browser and don't mind, or rather really want, your script being spread across several files fetched via AJAX, you can use a myriad of tools like:
yepnope.js or Modernizr's .load based on yepnope: Please note that yepnope is now deprecated by its maintainer, who recommend using build tools and concatenation instead of remote loading
RequireJS
HeadJS
jQuery's $.getScript
Vanilla AJAX + eval
your own implementation of AMD
You can try this library I made to solve this same problem coffee-stir
its very simple.
Just type #include and the name of the file that you want to include
#include MyBaseClass.coffee
For details
http://beastjavascript.github.io/Coffee-Stir/
I found that using "gulp-concat" to merge my coffee scripts before processing them did the trick. It can be easily installed to your project with npm.
npm install gulp-concat
Then edit your gulpfile.js:
var gulp = require('gulp')
,coffee = require('gulp-coffee')
,concat = require('gulp-concat');
gulp.task('coffee', function(){
gulp.src('src/*.coffee')
.pipe(concat('app.coffee')
.pipe(coffee({bare: true}).on('error', gulp.log))
.pipe(gulp.dest('build/')
})
This is the code I used to concatenate all my coffee scripts before gulp processed it into the final build Javascript. The only issue is the files are processed in alphabetical order. You can explicitly state which file to process to achieve your own file order, but you lose the flexibility of adding dynamic .coffee files.
gulp.src(['src/file3.coffee', 'src/file1.coffee', 'src/file2.coffee'])
.pipe(concat('app.coffee'))
.pipe(coffee({bare: true}).on('error', gulp.log))
.pipe(gulp.dest('build/')
gulp-concat as of February 25th, 2015 is available at this url.
Rails uses sprockets to do this, and this syntax has been adapted to https://www.npmjs.org/package/grunt-sprockets-directives. Works well for me.

Categories

Resources