I'm trying to "build" my project using Closure Library; Sadly, after many tests I can't build something without problems. My project is a library, so I haven't got an entry point or anything like that, most of the code is made of objects and functions for the user.
I've got a project like that:
- build
- build.sh
- compiler.jar
- libs
- closure-library
- src
My build.sh file:
java -jar compiler.jar --compilation_level SIMPLE_OPTIMIZATIONS --js_output_file out.js `find ../src/ -name '*.js'`
With this command line I've got the error:goog.require('goog.vec.Vec2');; So I think I need to include google closure library in this line, right?
So, I've tried to change my build.sh to something like that (added closure-library folder):
java -jar compiler.jar --compilation_level SIMPLE_OPTIMIZATIONS --js_output_file out.js `find ../src/ ../libs/closure-library/closure/ -name '*.js'`
With this script, I've got many error from the closure library like that:
../libs/closure-library/closure/goog/i18n/datetimeformat_test.js:572: ERROR - This style of octal literal is not supported in strict mode.
var date = new Date(Date.UTC(2015, 11 - 1, 01, 11, 0, 1));
And my resulting file (out.js) haven't got all my library's functions. I'm not sure to understand where is the problem.
Did I really have to include google closure in the build part?
I'm working on a Javascript library so I haven't got an entry point and all the code must be included in the resulting file. So, how can I do that?
Thanks for your time!
Edit:
I've tried something different: removing all lines like "goog.require('goog.vec.Mat4');" from my library. The build is done successfully but my simulation didn't work anymore: Cannot read property 'Mat4' of undefined
The functionality you are looking for is documented on the GitHub wiki under Manage Closure Dependencies
Determining Dependencies
1. Your Library Source Contains goog.provide Statements
In this case you would use --only_closure_dependencies combined with --closure_entry_point flags. Your "entry" points are any class in your library from which you want to calculate dependencies. You can have multiple entry points.
2. Your Library Source Does Not Contain goog.provide Statements
Use the --manage_closure_dependencies flag. This instructs the compiler to include any JS file which does not contain a goog.provide statement in the output and to calculate all needed dependencies based on the goog.require statements in those files.
Providing Files To The Compiler
Closure-compiler's --js input flags can specify minimatch glob style patterns and this is the preferred method for providing Closure-library files as input. If you are using the --manage_closure_dependencies option, you must exclude the Closure-library test files.
Example:
java -jar compiler.jar --compilation_level=SIMPLE_OPTIMIZATIONS
--js_output_file=out.js
--manage_closure_dependencies
--js='../src/**.js'
--js='../libs/closure-library/**.js'
--js='!../libs/closure-library/**_test.js'
Related
I've forked a very big project from GitHub and I've wrote a ~3000 lines plugin (single file) for it.
I would like to start using TypeScript for just this 1 single file.
As a starting point I only want to have the plain old JS content inside the .ts file (since any JS is valid TS) and then starting making minor incremental changes towards TS.
What I did was to install TypeScript in the project directory and made it so that TSC will compile my TypeScript file containing the old JS code into a .js file having the name the plugin had before.
The problem is this: How can I convert the plugin dependencies to TS?
Example:
the pre TS file, myPlugin.js, is the ~3000 lines file:
bigForkedApp.MyPlugin = function(bigForkedAppContext) {
// alot of code goes here
}
When copying this code in myPlugin.ts and expecting it to translate nicely into myPlugin.js, the compiler complains it doesn't know who bigForkedApp is.
I'm expecting that after the transpilation, the bigForkedApp.MyPlugin function in myPlugin.js can be called by the application just like before.
Should I write somehow .d.ts definitions for bigForkedApp and bigForkedAppContext?
Thanks!
since it's a JS (not TS) - you need to tell TypeScript who is "bigForkedApp", like this:
`declare var bigForkedApp: any;`
If I import the .lib and .h files in the Google V8 Engine, it will attempt to use them in a different c ++ project.
Do I need to import a file of any name?
When the source of the v8 was compile and build,
cctest
fuzzer_support
generate-bytecode-expectations
gmock
gtest
icui18n
icuuc
inspector_protocol
json_fuzzer_lib
mksnapshot
parser_fuzzer_lib
regexp_fuzzer_lib
unittests
v8
v8_base_0
v8_base_1
v8_base_2
v8_base_3
v8_external_snapshot
v8_libbase
v8_libplatform
v8_libsampler
v8_nosnapshot
v8_simple_json_fuzzer
v8_simple_parser_fuzzer
v8_simple_regexp_fuzzer
v8_simple_wasm_asmjs_fuzzer
v8_simple_wasm_fuzzer
wasm_fuzzer_lib
wasm_asmjs_fuzzer_lib
name file is generated.
I simply use the v8, and it outputs a run value of javascript.
My guess, seems to use only "v8.lib, v8_base (0,1,2,3) .lib" and "v8.h".
Is the sample code in a new c ++ project by copying the contents of the "hello-world.cc", made a cpp file. And I run, "LNK2019", "LNK1120" error occurs.
1>----- Build started: Project: v8Application, Configuration: Debug Win32 -----
1> v8Application.cpp
1>v8Application.obj : error LNK2019: unresolved external symbol _main referenced in function"class v8::Platform * __cdecl v8::platform::CreateDefaultPlatform(int)" (?CreateDefaultPlatform#platform#v8##YAPAVPlatform#2#H#Z) 1>c:\users\kito\documents\visual studio 2015\Projects\v8Application\Debug\v8Application.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
It seems must not defined "platform :: CreateDefaultPlatform" part is turned only in 'libplatform.h' declaration.
However, I would add "src \ libplatform \ default-platform.cc" the platform :: CreateDefaultPlatform has been defined, other error occurs in the add.
"Ws2_32.lib, winmm.lib" was also added to the project of the Additional Dependencies property.
How do I do this?
You must create your project and then LINK with V8, but you must not add V8's source files to your project.
The first thing to do is to compile V8 and take note of where the libraries were generated (or copy them to the directory of your choice). The same applies to V8's include files, they must be available in order to be included in your project (it is not advisable to copy them to your project directory).
In your console project's settings go to Linker -> Input -> Additional Dependencies and put v8.lib there. If the error is still present work you might want to add v8_libplatform.lib too.
Something similar applies to the include files, in your project settings you should go to C/C++ -> General -> Additional Include Directories and add V8's include directory there.
But remember, you must first compile v8 alone and expose the lib and include directories to your new project.
Update:
Your project file indicates that you configured Your project only for the configuraciĆ³n "Release", but the output above indicates that you are compiling in Debug mode.
Project config:
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
...
<Link>
<AdditionalDependencies>ws2_32.lib;winmm.lib;v8.lib;v8_base_0.lib;v8_base_1.lib...
</Link>
<ItemDefinitionGroup
Compiler output above:
1>----- Build started: Project: v8Application, Configuration: Debug Win32 -----
You must configure your project for all configurations, or at least test it using the configuration you've setup.
On the other hand, v8_libplatform.lib is not in the list of additional dependencies, you may want to add it.
The following post inspired me to have a look at limeJS, as a side project I'm working on and off an a Yatzee game (mostly off) and thought that might be a nice library to use.
As a beginner in google-closure I had some difficulties running uncompiled code and getting code compiled, mostly due to not knowing what the options and commands are and because of dependencies.
For other beginners with google-closuse I have written this tutorial.
Note that jQuery can be used by your closure compiled code but you need the jQuery externs file. You can't compile jQuery into your code, closure library has a dressed down dojo that can be found in third_party. When using that you can compile your code to one file.
What you need:
Python
Git client
Closure compiler for compiling code (minifying and merging all files into one)
Closure library like jQuery and jQuery ui but can be compiled along with your code
Python (I use 2.7)
LimeJS As a 3rd party library (use git client to get it, the url:https://github.com/digitalfruit/limejs.git)
JAVA JRE
Directory structure
I'm using Windows and have my projects in D:\projects, if you have your projects somewhere else you have to replace D:\projects references to your own.
In D:\projects I make a directory called libraries in that directory I copy the goog and third_party directories from closure library (goog is under the closure directory) since you'll use them for many projects I keep it at projects root, you can include a copy of it in every project you create but in this case I'll share the library among all projects.
Now I copy the contents of the src directory from limeJS ([lime clone dir]\lime\src) to D:\projects\libraries\lime (the one containing the sub directories called animation, audio ...).
Next I'll use an existing project from the limeJS library, copy the [lime clone dir]\lime\demos\roundball to D:\projects\roundball
At this time your directory structure should look like this:
D:
projects
libraries
goog
lime
animation
audio
css
...
third_party
closure
...
roundball
assets
... other roundball stuff
cacldeps.py
When you open D:\projects\roundball\rb.html and check out the console (press F12 in Chrome or in FireFox preferably having firebug plugin installed) you'll see an error: "ReferenceError: goog is not defined"
Open up D:\projects\roundball\rb.html and change:
<script type="text/javascript" src="../../../closure/closure/goog/base.js"></script>
to
<script type="text/javascript" src="../libraries/goog/base.js"></script>
Now when you open up rb.html again you get a different error: "goog.require could not find: lime.Director"
This is because closure uses deps.js to find dependencies and since lime is not in there it can't find it. Lucky for us there is a tool called calcdeps.py in the bin directory of the closure library that can create this file for us. It'll look in your code and and use goog.require to figure out what other files are needed. If your file structure is good than this tool will find it.
It will expect that Director is in a file called director.js in a directory called lime (and it is). That js file should have a goog.provide statement providing lime.Director.
You can add directories for calcdeps.py to look in with the --path parameter.
In D:\projects\roundball I'll create a makedeps.bat with the following content:
set calc="D:\software\closure compiler\library\closure\bin\calcdeps.py"
c:\Python27\python.exe %calc% ^
--path D:\projects\roundball\ ^
--path D:\projects\libraries\ ^
--input D:\projects\roundball\rb.js ^
--output_mode deps ^
--output_file D:\projects\libraries\goog\deps.js
pause
Uncompiled code uses /goog/deps.js to load dependencies. caclcdeps.py will check your code starting with rb.js (as this is the starting point of the code) and add entries to deps.js according to what your project uses.
Once again, cacldeps.py can be found in the bin directory of closure library.
Note that when you have another project; let's say D:\projects\project2 then you have to create a makedeps.bat in that project directory that re creates the deps.js for you before you can run the uncompiled code. This because multiple projects share one google closure library so when you switch projects make sure you'll build the deps.js first before running your uncompiled code.
Resolving missing dependency
Opening the rt.html we still get an error but a different one: Error: "Undefined nameToPath for lime.css"
Looking in goog/deps.js we can find that lime.css is needed by lime but doesn't have an entry in deps.js. Why is this? Looking in D:\projects\libraries\lime there is no css directory or css.js file. But in the directory where you cloned the git lime project there is a directory called css.
Copy the css directory to D:\projects\libraries\lime and run makedeps.bat again, now when you open rt.html it will run.
The whole thing is uncompiled and you can set breakpoints to step into 3rd party code.
Compile your code
In production you would want to compile the code to one file. To compile the code I created a compile.bat in D:\projects\roundball with the following content:
set calc="D:\software\closure compiler\library\closure\bin\calcdeps.py"
c:\Python27\python.exe %calc% ^
--path D:\projects\roundball\ ^
--path D:\projects\libraries\ ^
--input D:\projects\roundball\rb.js ^
--compiler_jar "D:\software\closure compiler\compiler.jar" ^
--output_mode compiled ^
--compiler_flags="--compilation_level=ADVANCED_OPTIMIZATIONS" ^
--compiler_flags="--formatting=PRETTY_PRINT" ^
--output_file D:\projects\roundball\compiled\roundball.js
pause
;Need this flag for production compile:
;--compiler_flags="--define goog.DEBUG=false" ^
;Remove the following flag from production compile:
;--compiler_flags="--formatting=PRETTY_PRINT" ^
;lime libraries is giving me errors with stricter compilation
; so had to remove this flag (have to fix the errors or no type checking for your code)
;--compiler_flags="--warning_level=VERBOSE" ^
The file compiler.jar can be found where you downloaded (and extracted) closure compiler
Now when you run the compile.bat and open D:\projects\roundball\compiled\roundball.html you'll see in the developer tools of your browser that only roundball.js is loaded.
The answer is in the question because it's a howto article that could help someone (like me in the future when I forgot how to do it).
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.
What is the best way to do Dependency Management amongst CoffeeScript files if the resulting javascript files eventually need to be concatenated together for use on the client side?
For server side CoffeeScript I can just use the 'require' keyword to require other pieces of javascript. When this is compiled for client side apps to have the dependency tree, based on the requires, calculated and a concatenated stand alone javascript file produced. Is there anyway to do this in a generic way?
Another option is to use CoffeeToaster, which uses another approach than implementing AMD / CJS module patterns.
Take a look:
http://github.com/serpentem/coffee-toaster
Usually, for client-side packaging of JavaScript (and CSS), you want some sort of asset-packaging plugin. We use Jammit, but there are many other options: Sprockets, Django-Compress ... and more.
Villain (a CoffeeScript game engine for browsers) defines functions that do just that (dependency management and js concatenation).
The code for that is in these two files:
cake.coffee, see , determineDependencies(), wrapModule(), and bundleSources()
brequire.coffee, a require replacement for the browser, to use with wrapModule()
I use it here (see the 'bundle' Cake task).
Note: I just declare the 'main' module's build directory, and Villain scans my compiled JS files to build the dependency tree (starting with index.js), then creates a JavaScript bundle file containing Villain's require replacement and all my relevant code sorted and correctly wrapped.
Villain's author uses it in orona, a CoffeeScript game made with Villain.
For dependency management on client side, I use requirejs for javascript and coffeescript source. It'possible to use a requirejs plugin to load natively coffee files, but I prefer to "compile" into js.
requirejs also provide / work with r.js optimizer. It can be used to aggregate a set of js file into one and minified it. you don't have to specify the file to aggregate it is the dependency definition of each module require by your "main.js". (feature that match your request)
Something I like a lot with requirejs, it "promots" creating module and declare explicit dependencies.
# A.coffee
define(() ->
class A
constructor: (#c1, #c2) ->
#c2 ?= 1
m1 : () ->
"hello"
toString : () -> "#{#c1}#{#c2}"
)
# B.coffee
define(['A'], (A) ->
a = new A(33)
console.log(a, a.m1())
)
I've used (and I guess am still using) requirejs but I've started to find it to be fairly clumsy. A lot of my files end up having ~10-12 imports at the top which just take up a lot of space and don't look great.
For a new project I tried browserify. It's great! And if you use grunt (you should), you can make a watch task to browserify your code on change. grunt-browserify also provides the ability to do a coffeescript transform.
https://github.com/jmreidy/grunt-browserify
So your watch task in your Gruntfile.coffee would look something like:
watch:
files: [
"app/**/*.coffee"
]
tasks: "browserify"
browserify:
'build/app.js': ['app/**/*.coffee']
options:
transform: ['coffeeify']