JSHint: excluding Preprocessor Directives. No, really - jshint

I'm working with Adobe Extendscript, which == javascript*, and I'm using the Atom JSHint package in Atom. Extendscript is the scripting framework for Adobe apps like Photoshop and After Effects. Adobe do make an IDE but it's really feeble, so I write with Atom and then switch over to "Extendscript Toolkit" to run my scripts. Anyway…
Adobe lets you use C-style preprocessor directives like #include "myUsefulFunctions.jsx" so that you can keep reusable stuff in libraries like a real programming language.
The problem is that the JSHint linter sees my C-style preprocessor directives at the top of the page, freaks out and gives up. To actually get it to lint my code I have to comment the preprocessor directives out and then remember to uncomment them before I run the code. This means at least 3 or 4 extra keystrokes each time I test, which as you all know is The. Worst. Thing. Ever.
So to save half a dozen keystrokes I've been looking into the settings for JSHint. Nothing I've found so far seems related. Is there any way of globally getting JSHint to ignore lines like #this, or locally in the file to get it to skip a line or two?
*or is it ===? I'm really confused by JS's approach to the truth.

I also tried to figure it out for a long time, until I found the best solution.
Instead of using:
#target aftereffects
You can use:
//#target aftereffects
I didn't found any documentations for the above solution.
I just found it in a script over the net, and I tried it and it worked.
And instead using:
#include "some/path/to/file.jsx"
As mentioned in the JavaScript Tools Guide:
evalFile()
$.evalFile (path[, timeout])
Loads a JavaScript script file from disk, evaluates it, and returns the result of evaluation.
path: The name and location of the file.
timeout: Optional. A number of milliseconds to wait before returning undefined, if the script cannot be evaluated. Default is 10000 milliseconds.
You can use:
$.evalFile("some/path/to/file.jsx");
The diffrence is that #include:
Includes a JavaScript source file from another location.
Inserts the contents of the named file into this file at the location
of this statement.

In jshint you can ignore lines by adding a ignore statement to the line.
#target aftereffects //jshint ignore:line
Or you can ignore whole blocks like this.
// Code here will be linted with JSHint.
/* jshint ignore:start */
// Code here will be ignored by JSHint.
/* jshint ignore:end */
(BTW the //#target aftereffects is pretty cool. Thanks for pointing that out)

I changed the JSHint package that I use, and now there's no need for workarounds.
For anyone else developing Extendscript in Atom the linter I recommend is this one: Linter-JSHint. It's a plug-in for the Atom Linter package, so you'll need to install that too.
Then once you've done that use this to ignore a block:
// Code here will be linted with JSHint.
/* jshint ignore:start */
// Code here will be ignored by JSHint.
#includepath "lib"
#include myBrilantLib.jsx
/* jshint ignore:end */
or for a single line:
ignoreThis(); // jshint ignore:line

Related

Gulp generates a throw Error when using SASS instead of SCSS

I am working off of a boilerplate WordPress theme built with a gulp workflow. CSS is written using SCSS, I find SASS more intuitive and easier to work with. However when I change the gulp tasks to focus on SASS and not SCSS files I get this error whenever I run the task:
unlock git:(master) ✗ gulp styles
[11:37:25] Using gulpfile ~/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/gulpfile.js
[11:37:25] Starting 'styles'...
[11:37:25] Finished 'styles' after 20 ms
buffer.js:169
throw new TypeError('must start with number, buffer, array or string');
^
TypeError: must start with number, buffer, array or string
at fromObject (buffer.js:169:9)
at new Buffer (buffer.js:62:10)
at Transform.transform [as _transform] (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-combine-media-queries/index.js:145:21)
at Transform._read (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-combine-media-queries/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:184:10)
at Transform._write (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-combine-media-queries/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:172:12)
at doWrite (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-combine-media-queries/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:237:10)
at writeOrBuffer (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-combine-media-queries/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:227:5)
at Transform.Writable.write (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-combine-media-queries/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:194:11)
at write (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-filter/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:623:24)
at flow (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-filter/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:632:7)
at DestroyableTransform.pipeOnReadable (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-filter/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:664:5)
at emitNone (events.js:67:13)
at DestroyableTransform.emit (events.js:166:7)
at emitReadable_ (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-filter/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:448:10)
at emitReadable (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-filter/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:444:5)
at readableAddChunk (/Users/tijaniogunlende/Desktop/unlockafrica/wordpress/wp-content/themes/unlock/node_modules/gulp-filter/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:187:9)
When I change the files back to the SCSS source everything works fine.
I know its something small but haven't been able to figure it out.
Thanks in advance.
I had the same error, but I got it from not having any style sheets. So basically I had no styling, and then it tried to put all that nothing into one file. I fixed mine by just creating a one file and putting some comments in it so that it would at least have some content to work with.
I don't know how helpful this is, but here it is anyway.

Use SQLite with biicode

So far I have been able to succesfully use boost, cereal and gtest using biicode but I am having troubles with sqlite. I am trying to use it doing the following:
#include <sqlite3.h>
So I edited my biicode.conf to include those lines, including the alising for the header:
[requirements]
sqlite/sqlite:9
[includes]
sqlite.h: sqlite/sqlite/sqlite3/sqlite3.h
But when I try to call bii cpp:build it does the following
WARN: Removing unused reference to "sqlite/sqlite: 9" from myuser/test "requirements"
Then I ended up with the expected:
database_impl.cpp:(.text+0x516): undefined reference to `sqlite3_exec'
Surprisingly, the compilation succedd even though sqlite3.h is obviously not included but that's maybe because the call to sqlite is from a template function.
I have looked at the example but CMakeList.txt does not seem to add any additional includes directories. For example for boost I had to add:
SET(Boost_USE_STATIC_LIBS OFF)
bii_find_boost(COMPONENTS chrono system filesystem log thread REQUIRED)
target_include_directories(${BII_BLOCK_TARGET} INTERFACE ${Boost_INCLUDE_DIRS})
target_link_libraries(${BII_BLOCK_TARGET} INTERFACE ${Boost_LIBRARIES})
But the two examples I found here and here don't seem to add anything to the includes directories, not even a link folder. I suppose sqlite has to be compiled with your sources so how do I make biicode add those files to my projects automatically ?
There're several problems. You just wrote in [includes] section sqlite.h instead of sqlite3.h and you should only write the prefix, sqlite/sqlite/sqlite3, later instead of the full dependency name.
Then, you can solve it so:
[requirements]
sqlite/sqlite: 9
[includes]
sqlite3.h: sqlite/sqlite/sqlite3
Or, you could try the SQLite version uploaded into fenix user:
[requirements]
fenix/sqlite: 0
[includes]
sqlite3.h: fenix/sqlite
Don't worry about a "WARN" message that says biicode is ignoring sqlite3.c file because it's harcoded into the block CMakeLists.txt to catch this file ;)
Note: you should write your external #includes's with double quotes instead of <>, because the last ones are referred to system headers and biicode could be using some system deps and you don't realize it.

ServiceStack Bundler and sub-directory Less files

Until recentlly I was using the rather awkward dotless. I'm restricted to what I can use somewhat because I'm using VS2010, however I came across ServiceStack Bundler which seems to work great... apart from one thing.
My Less files are split using a directory structure - to simplify things, like this:
scaffolding/my-scaffolding.less
utilities/my-utilities.less
ui/my-ui.less
Each directories has many files, particularly with mixins etc.
In order to link them together, I've been using the #import function.
My main less file - main.less contains the following:
#import "utilities/all-utilities.less"
All utilities are listed here as it enables me to plug and play various file-sets. This code previously worked ok.
However I find ServiceStack won't pick up changes unless I reference all the less files individually and directly through the bundle file, which is a bit of a pain.
So, I can't use: main.less and import all sub files.
Instead, I have to use:
utilities/util1.less
utilities/util2.less
utilities/util3.less
and so on.
I'm using the ms build function to compile.
Any ideas?
/* UPDATE */
Tried the recommended answer below without success.
This is what I've tried so far:
Call a single less file that contains all #import declarations;
Does not trigger updates on compile.
Call all less files from bundle file and add #import statements to less files where necessary (note bundler won't compile without these);
Duplicates the #imported code as many times as the #import statement is used - even when (reference) directive is used, resulting in bloated/incorrect code.
You should be able to modify Bundler's bundler.js file to specify additional paths that less should search for when processing #import directives:
function compileLess(lessCss, lessPath, cb) {
var lessDir = path.dirname(lessPath),
fileName = path.basename(lessPath),
options = {
paths: ['.', lessDir], // Specify search paths for #import directives
filename: fileName
};
less.render(lessCss, options, function (err, css) {
if (err) throw err;
cb(css);
});
}
A mistake on my part, but one which wasn't easily spottable, so I'll post the reason for my problems so that others don't spend hours as I did chasing a solution to an unecessary problem.
I was using ServiceStack Bundler - I believe this issue would also have occured on on any solution using npm's less library.
My main issue was that none of my changes were triggered on compile. I use lots of #imports and numerous sub-directories for my less files so my first thoughts were the problem was due to subdirectories, and later, due to #import statements. However neither was correct.
I defined a bundle: main.css.bundle
Within the bundle I called my main less file that contained all the other #imported files: main.less
The issue was that less would normally reserve main.css, but the bundle also gives its output the same name based on the bundle name. So both were conflicting.
Change the bundle name or the main less file name and all should work.

Compiling code + ydn with Closure Compiler

I'm trying to take advantage of Google Closure Compiler minification by writing a database script of my own and compiling it with the pre-compiled ydn. To get a basic first version working I'm trying to rewrite the todo list demo from the project. Unfortunately, I don't understand how to keep namespaces for ydn functions preserved in the compiled output file.
Here's what I've written so far: http://pastebin.com/6YhnRuD5
When the code compiles in advanced mode, the "ydn.db.Storage" from "db = new ydn.db.Storage(dbName, Schema)" gets munged into "ydn.db.c$" making it unusable. The goog.exportSymbol at the bottom of the file doesn't seem to save the function names either.
Does anyone know how to rewrite this with Google Closure Compiler? Should this be compiled directly with the ydn source code instead?
The goog.exportSymbol at the bottom of the file doesn't seem to save the function names either.
It should.
goog.exportSymbol("ydn.db.Storage");
should be
goog.exportSymbol('ydn.db.Storage', ydn.db.Storage);

Conditional compilation "else"

In AS3 you can pass a constant to the compiler
-define+=CONFIG::DEBUG,true
And use it for conditional compilation like so:
CONFIG::DEBUG {
trace("This only gets compiled when debug is true.");
}
I'm looking for something like #ifndef so I can negate the value of debug and use it to conditionally add release code. The only solution I've found so far was in the conditional compilation documentation at adobe and since my debug and release configurations are mutually exclusive I don't like the idea of having both DEBUG and RELEASE constants.
Also, this format works, but I'm assuming that it's running the check at runtime which is not what I want:
if (CONFIG::DEBUG) {
//debug stuff
}
else {
//release stuff
}
I also considered doing something like this but it's still not the elegant solution I was hoping for:
-define+=CONFIG::DEBUG,true -define+=CONFIG::RELEASE,!CONFIG::DEBUG
Thanks in advance :)
This works fine and will strip out code that won't run:
if (CONFIG::DEBUG) {
//debug stuff
}
else {
//release stuff
}
BUT this will be evaluated at runtime:
if (!CONFIG::DEBUG) {
//release stuff
}
else {
//debug stuff
}
mxmlc apparently can only evaluate a literal Boolean, and not any kind of expression, including a simple not.
Use the if / else construct : the dead code will be removed by the compiler and it will not be tested at runtime. You will have only one version of your code in your swf.
If you are not sure use a decompiler or a dump tool to see what really happens.
http://apparat.googlecode.com/files/dump.zip
http://www.swftools.org/
...
While Patrick's answer fulfills the question's criteria, it does not cover all use cases. If you are in an area of code that allows you to use an if/else statement then this is a good answer. But if you are in a place where you cannot then you will need a better solution. For example, you may want to do something like this to declare a constant in a class:
private var server:String = "http://localhost/mystagingenvironment";
or for a live release:
private var server:String = "http://productionserver.com";
(this is an example and I'm not advocating this as production code).
I use xml configs and use the loadConfig+="myconfig.xml" to do my configuration instead of passing large numbers of command line params. So in the <compiler> section of your xml config:
<define>
<name>CONFIG::debug</name>
<value>false</value>
</define>
<define>
<name>CONFIG::release</name>
<value>!CONFIG::debug</value>
</define>
This works well for all use cases:
CONFIG::debug
{
private var server:String = "http://localhost/mystagingenvironment";
}
CONFIG::release
{
private var server:String = "http://productionserver.com";
}
This has the additional benefit of working consistently across applications. It also does not rely on the 'optimize' flag being true, like Patrick's answer (although I think we can assume that 99.999999% of all swfs have optimize=true, I only set it to false when the optimizer breaks my AS3).
It does have the drawback that it doesn't compile all code paths, just the ones that are included. So if you're not using a build server to create release builds and tell you when things break, be prepared for surprise errors when you do your release build ("But it compiled in debug! Crap, I need this to launch now!").
Just my two cents about Chris Hill's answer (which is the solution I also use regularly): it seems that using the loadConfig+="myconfig.xml" option makes the compiler searching for the myconfig.xml file in the Flex SDK directory whereas the -load-config+=myconfig.xml option makes it searching for the myconfig.xml file in the project's directory, which is the behavior I strongly prefer as you can then easily distribute this file with your project sources...

Resources