Generating source maps for multiple concatenated javascript files compiled from Coffeescript - javascript

Has any one had any success with this?

I think it's more or less an unsolved problem:
https://github.com/jashkenas/coffee-script/issues/2779 . Last meanigingful comment was from jwalton, a month ago.
Still, it doesn't seem rocket science to add support for it, so it will probably come soon.
Michael Ficarra (creator of CoffeeScript Redux) suggested using https://github.com/michaelficarra/commonjs-everywhere .
Two caveats:
It only works for bundling CommonJS modules.
It uses CoffeeScript Redux, which is still in beta (although working quite well it seems), and not 100% compatible with original CoffeeScript compiler.
So this does not work for what you ask for specifically, "concatenation".
Added April 14
You might have luck with these: combine-source-map and/or generate-sourcemap, both by same author.
Added April 26
This looks really simple: https://npmjs.org/package/mapcat . You just have to feed it the individual source map files generated by the coffee compiler.
Added May 16
Mariusz Nowak has just released webmake-coffee. Like CommonJS Everywhere, it requires code to be organized as CommonJS modules. Unlike CommonJS everywhere, it uses regular CoffeeScript.
It also seems the Grunt Coffee-Script plugin has had source-map support for concatenated files for quite a while (two months), effectively proving my original answer to be incorrect.
The upcoming version 2.0 of Snockets will have support for it too.

I ended up going with browserify using coffeeify as the transform option, and enabling browserify's debug option. I bundle up the app on each request for my main.js file, and any runtime errors show up in my original source with pretty decent accuracy.
Sure beats mapping runtime errors in the concatenated/compiled js back to the coffee source with my eyeballs!

I needed to annotate AngularJS code before minification, but grunt-ng-annotate didn't accept input source maps, thus I would not be able to use maps generated by the CoffeeScript compiler.
Apparently, with gulp-sourcemaps this is not an issue:
var gulp = require('gulp');
var $ = require('gulp-load-plugins')(); // loading gulp plugins lazily
// remember to include them in the package.json
gulp.task('appJS', function() {
// concatenate compiled .coffee files and js files into build/app.js
gulp.src(['./app/**/*.js','./app/**/*.coffee'])
.pipe($.sourcemaps.init())
.pipe($['if'](/[.]coffee$/, $.coffee({bare: true}).on('error', $.util.log)))
.pipe($.concat('app.js'))
.pipe($.ngAnnotate())
.pipe($.uglify())
.pipe($.sourcemaps.write())
.pipe(gulp.dest('./build'))
});
The same approach works in other situations, too. In my case, this is the only approach that worked.

I have written a grunt task that does this flawless. Check it out

Related

Bazel auto generate dependencies for ts_library

Is it possible to auto-generate the dependencies of a bazel target? It seems like there should be a way to look at the imports of the module and know which bazel dependencies are needed at least in a lot of cases common cases. This could save a lot of boilerplate code.
load("#npm_bazel_typescript//:index.bzl", "ts_library")
ts_library(
name = "lib",
srcs = glob(include = ["**/*.ts"]),
# Is there any easy way to generate this list?
deps = [],
)
I know there are packages for Java that do this. https://github.com/johnynek/bazel-dep. I haven't been able to find anything for any other languages.
If it doesn't exist I think it could be pretty straightforward to write. Create a template file for you to work off of creating the real BUILD file. Then run typescript to pull the AST of the module. Look through the imports. The 3rd part imports will be easier since they should resolve to an npm module.
For other files that may or may not be in this library then there might be a way to query what package they live int. That could probably work. Any pointers would be very much appreciated.
Disclosure: I am one of the authors of this library.
https://github.com/evertz/bzlgen
It can generate BUILD files (or, more precisely it generates buildozer commands) for Angular (ng_module) and SCSS (scss_library and scss_binary) libs.
I've just moved this in to opensource from our internal repo. It works in a similar way to what you suggest, however it doesn't query for labels. It uses a file or directory as a starting point, parse into an AST, query the AST to fetch imports and reexports, convert the paths into labels.
Adding ts_library support is a logical next step.
It doesn't always get you a 100% working BUILD file currently, but it will get you ~80-90% of the way there, and do the boilerplate parts for you.
Another approach would be to interact with the Gazelle API, and manipulate the BUILD files directly.
A previous version of this tool generated the BUILD files from a string and it got difficult to work with when manipulating the files in other ways.

In the Angular4 Webpack Starter, does tsconfig.webpack.json work for webpack while tsconfig.json works for everything else?

Please refer to this git repository: https://github.com/AngularClass/angular-starter
The Angular4 Webpack Starter comes with 2 files:
tsconfig.json
and
tsconfig.webpack.json
Each file has slightly different configurations for TypeScript.
My question is regarding how these 2 files work in relation to the project.
Will the tsconfig.webpack.json only be applied to the ts-loader used by Webpack? while the tsconfig.json file will apply to everything else?
Any information on what tsconfig.webpack.json would be greatly appreciated.
The short answer is yes. The TypeScript loader registered with Webpack is explicitly configured to use the tsconfig.webpack.json file. This can be observed on line 133 of the common configuration.
The tsconfig.json file is there for IDE support.
It is worth noting that, while you state that the template uses ts-loader, it actually uses awesome-typescript-loader.
Having said that, both loaders will by default try to pick up a file named tsconfig.json and that the template is explicitly overriding this behavior on the linked line.
While there are multiple reasons why one might want to use more than one TypeScript script configuration file in a project, editors, such as Visual Studio Code, use the one named tsconfig.json to power features such as intellisense, set various options, and to determine the extent of a project.
It is more than reasonable to use the same file for both and that is actually what would happen by default.
Remarks
Please note that the AngularClass template is extremely bloated and complicated. Considering it is meant as a starting point, which you will no doubt add to, the amount of unnecessary boilerplate and cruft that you start out with by basing your application on such a template should be taken into very serious consideration. This goes double if you are new to any of the tools, transpilers, or frameworks involved.
By the way, I'm actually a contributor to that repository. They took a pull request from me that changed a utility function which someone filed an issue for as being confusing. The funny thing was that I had removed that very function from our project long before I submitted the PR improving it.
Having worked on a project which was derived from one of their templates, I wasted a lot of time ripping out Webpack config related code that was not needed but was getting in the way. We ended up with only a ~hundred lines of Webpack config total. I wasn't, and still am not a huge Webpack fan (JSPM for the win), but Webpack was not being utilized well by the template. Lots of unnecessary work was being done which actually made Webpack seem more complicated than it is. That entire helpers file is basically worthless and none of it had anything to do with Webback, or TypeScript, or even Angular.
This is also a bit troubling since the angular class website sells training material. There's nothing wrong with that in principle or in practice, but they create a lot of complexity in addition to what is inherent in an already complex tool chain.
Will the tsconfig.webpack.json only be applied to the ts-loader used
by Webpack?
Yes, that is correct. Here is where the tsconfig.webpack.json is used in webpack.common.js:
new ngcWebpack.NgcWebpackPlugin({
...
disabled: !AOT,
tsConfig: helpers.root('tsconfig.webpack.json'), <----------------
}),
and for awesome-typescript-loader here:
{
loader: 'awesome-typescript-loader',
options: {
configFileName: 'tsconfig.webpack.json', <-------------------
useCache: !isProd
}
},
while the tsconfig.json file will apply to everything else?
Yes, it's used for tslinting or if you need to produce declaration files. If you're working in IDE it can also be used for intellisense and other IDE specific functionality.

How to combine all js files?

I have more than javascript files in my html documents as external which I'd like to combine on account of not to be crowded. is there any way to combine my js files ? for example;
my files:
a.js
b.js
c.js
d.js
and i want;
all.js
Take a look at requirejs.org and especially look at r.js (http://requirejs.org/docs/optimization.html)
a.js
var i=0;
function fun1()
{
...
}
b.js
var k=0;
function fun2()
{
...
}
all.js just copy, paste like css
var i=0;
function fun1()
{
...
}
var k=0;
function fun2()
{
...
}
take care of semicolons and closed braces when you purticularly write whole script in an eventlistener, especially 'DOMContentLoaded'
document.addEventlistener('DOMContentloaed',function()
{
//whole big script
}
);
instead use
document.addEventlistener('DOMContentloaed',some_function);
var some_function = function(){*bla bla bla*};
A simple bash cat operation will do what you want, but, at some stage you're probably going to want more right?
Grunt and Grunt-contrib-concat is a good starter, but you'll quickly realise grunt is not particularly good. To summarise usage, you create a gruntfile, install a few dependencies (i.e. install grunt and its command line interface, this is easy) and run grunt from your project root. It then parses the gruntfile to find out what you want it to do, and it does it. Pretty simple, and simple is good.
Next up is Gulp, which is a nice build system using streams, so, slightly more complex (well, easier and more powerful but, streams can be kind-of confusing at first). Gulp works in the same way only it parses a gulpfile for instructions. For a concat operation the actual gulp command is trivial:
gulp.src( '*.js' )
.pipe( gulp.dest( 'all.js' )
Between the .src and the .dest you can pipe the files through multiple transforms, such as minifying, transpiling, notifying—the list of plugins and modules is dizzying (as it is for grunt).
However, if you’re a fan of node and npm (you probably should be) then you can use npm scripts to create a build system. npm is the node package manager and requires a package.json to give some clues as to how to work. Part of that json specification is a scripts block
"scripts": {
"build" : "cat *.js > all.js"
}
You can then use npm run build from the command line, whereby npm will parse the package.json and execute the script using bash (sh actually).
Note that these are build systems, and there are many others.
There are also other packagers (which you would probably use as part of your build system, although for some projects they are you entire build system) but they are more complex than your needs, for your own research browserify, webpack and jspm are all excellent (bare in mind AMD modules lost so require.js is probably not worth your time), although this area is becoming congested. Each of these are very powerful modularisation tools, but they will require some changes to how you structure your code. If you are serious about modularisation then they are worth your time learning.
On a slightly different tangent, there is some discussion about whether one large file is actually more beneficial than a number of smaller scripts. In many cases simply serving a few small files is actually quicker, and may be easier, although there can be other benefits of smashing code together. Currently it is probably still best to concat at least into less HTTP requests, but this requirement for performance is going away.
It might be helpful : https://github.com/mrclay/minify
OR
create file all.js and paste a.js,b.js,c.js,d.js file code

Visual Studio 2015 compiles ALL typescript files when SINGLE file is changed

I am using Visual Studio 2015 with Typescript 1.5.4 and Resharper 9
This is the buggy scenario:
I have about 180 typescript files
I change single .ts file
VS shows message "Generation of XXX.ts file complete. Remaining files still compiling"
after that ALL my .ts files are compiled to .js
2 things were changed in those .js files: formatting is slightly different and reference for .js.map was removed
When I build the whole project, then the .js files are generated again but with original formatting and with link to .js.map present
This is annoying because it generates too much noise in Git
and it prevents me from debugging typescript files directly in browser. (because of that missing .js.map file)
The desired behaviour is of course that the only changed .ts file should be compiled on save. How to do it?
It seems that R# has nothing to do with this, because it continues to happen with R# disabled.
My current project settings:
-------------UPDATE-------------
I've tried to update to Typescript version 1.6.
The PATH variable pointed to C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.4\ so I've updated that to point to 1.6
So when I now type tsc -v it says message TS6029: Version 1.6.2
But because of historical reasons (the project I work on is about 2 years old) I have to use version 1.4 inside VisualStudio. So in the .csproj is <TypeScriptToolsVersion>1.4</TypeScriptToolsVersion>
After this change the compile on safe stopped working completely.
Now I have to rebuild the whole solution :(
It seems that Visual Studio does not support watch mode properly (i.e. incremental compilation):
Just to be clear, --watch does work on Windows if you're using
node.js/io.js, but the tsc.exe program distributed with VS does not
support it; you still have Compile on Save for similar functionality
anyhow.
https://github.com/Microsoft/TypeScript/issues/2375#issuecomment-100812347
I'm not sure why this was closed. Supporting --watch for our tsc.exe
host would both be possible and desirable. Right now the limiting
factor is that our tsc.exe host is a bit of ugly C++, that uses some
ancient COM interfaces for Chakra that we haven't spent much effort
on. Our options are: [...]
https://github.com/Microsoft/TypeScript/issues/2375#issuecomment-100949019
As a workaround, could you run
tsc --watch
in the folder where tsconfig.json is located?
Edit: https://github.com/Microsoft/TypeScript/issues/5638 - Visual Studio 2015 compiles ALL typescript files when SINGLE file is changed
Starting with VS 2015 RTM, Compile-on-Save, every time you save a file
we need to generate all files in the project to ensure consistent
output. We have got numerous issues related to inconsistent output
when saving files in different orders. Building all files is the only
way we can guarantee correct and consistent output given all the
language constructs and how they interact across files (e.g.
namespaces/internal modules can be augmented, and that affects the
shape of emitted code, also const enms are in lined as constants,
etc..).
Try "ECMAScript 5" instead of "ECMAScript 3" in "ECMAScript version
I had a similar issue, but since we were handling TS compilation on our own, I wanted to avoid auto-compilation at all...
The fix was to force the TypeScriptCompileOnSaveEnabled flag to false inside the project:
<PropertyGroup>
<TypeScriptCompileOnSaveEnabled>false</TypeScriptCompileOnSaveEnabled>
</PropertyGroup>
in my case this effectively stopped VS2015 from automatically compiling the .ts files on save, without VS getting into the way every time and messing up outputs...
Another work around: You could use Gulp to generate your compiled js files and maps. With Gulp you can also create a watch task to compile at a save of a ts file. You can even create clean tasks to clean up the project.
Example of a build task:
var tsProject = ts.createProject(paths.typescriptRoot + 'tsConfig.json'); // use tsconfig.json
gulp.task("tsbuild", function () {
var tsResult = tsProject.src()
.pipe(sourcemaps.init()) // needed to create sourcemaps
.pipe(ts(tsProject)); // use tsconfig.json
return tsResult.js
.pipe(concat(paths.concatTsFileName)) // concat all output files into a sings js files
.pipe(sourcemaps.write()) // write the sourcemap to be able to debug the ts files
.pipe(gulp.dest(paths.typescriptOut)); // output the result on specific path
});
Example of a cleanup task :
gulp.task("clean:tsout", function (cb) {
rimraf(paths.typescriptOut + paths.concatTsFileName, cb); // rimraf is used to delete a folder
});
gulp.task("clean:scriptjs",
function () {
return gulp.src(paths.typescriptJs, { read: false }) // to clean up multiple files we need to use gulp-rimraf
.pipe(gulpRimraf());
});
Example of a Watch task:
gulp.task("watch:tsbuild", ['tsbuild'], function () {
gulp.watch(paths.typescriptRoot + '**/*.ts', ['tbbuild']);
});

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