Best way to concatenate JavaScript files with dependencies and to output them as a module? - module

I know this question came up in similar variations often, but no solution seems to fully fit my needs. I have the following problem:
In development I use multiple JS files (a single file every "object"). These JS files have several dependencies within each other - some rely on others and I need to load them first. Currently I use RequireJS to load each JS file in the right order, so I define a module for each file. Fine and dandy.
But now I want to concatenate all my JS files into one big JS file which should be a module itself. I use the RequireJS optimizer r.js to do that. My problem: Every JS file is concatenated to a big JS file, but the module definition for each object is included to. I don't have one big module in one big file, but many modules in one big file.
After that I tried grunt for concatenating which works fine, but ignores dependencies of files. It just concatenates every file in alphabetical order or I have to hardcode the order in my gruntfile.
How can I solve this?
Just as an illustration to my problem:
I have following files (pseudo code):
FileA
- define FileA module
- depends on FileB
- FileA Logic
FileB
- define FileB module
- FileB Logic
And I want this output:
LibFile
- define LibFile module
- FileB Logic, FileA Logic
But I get this with r.js (module definition from FileA and FileB is copied):
LibFile
- define FileB module
- FileB Logic
- define FileA module
- depends on FileB
- FileA Logic
And I get this with grunt (wrong order):
LibFile
- FileA Logic
- FileB Logic
Maybe that questions is a little bit stupid, but I just can't solve this with the tools everybody seems to use...
I tried the grunt-requirejs plugin, too. But it throws several erros which I couldn't resolve.
Thank you,
Pipo

I am going to move it into an answer. Just so the code is a bit clearer.
I am doing these by memory (since I can't test it right now) so some little things may be not entirely accurate.
It depends of course on how you package your modules, but one way is to register all your smaller modules in a bigger module:
File A.js
define([], function() {
// do something
return A;
});
File B.js
define(['path/to/A'], function(A){
// do something with A and more
return B;
});
Then, you package them together:
File mylib.js
define(['path/to/A', 'path/to/B'], function(A, B){
return {
A : A,
B : B
}
}
you then can point your build profile to mylib.js and it will be combined into
one big file. It won't be one all-encapsulating module, but it will have an entry
module that references everything else. You then can use it like so:
require.config({
paths : {
'path/to/mylib' : 'real/path/to/mylib/on/server'
}
});
require(['path/to/mylib'], function(Lib) {
// do something using Lib.A or Lib.B
}
the one thing to pay attention to is the ID of your big module file. By default
RequireJS build gives ID that matches physical path (from appDir IIRC) and you
have to match that when you load your dependency. Simply put, if your resulting
mylib.js file has a main module that received the name 'path/to/mylib', you will
have to match it and load it by the same ID (using require.config.paths) or play with
maps and such (some of which requires RequireJS 2.0).
The following is the reason I asked you why would you want to do the "big module" thing
Other thing of note is that all your inner smaller modules also receive IDs matching their
physical path and you can use these IDs when you use the big package module (so that you can access them not only through Lib.A) if mylib.js has been loaded:
require(['path/to/A'], function(A) {
// do something using A
}

Related

Why can't I import module from different file in same directory? [duplicate]

This question already has answers here:
How can I include a module from another file from the same project?
(6 answers)
Closed 3 years ago.
My directory structure:
src
main.rs
image.rs
decoders.rs
When I try to import my decoders module in image.rs I get this:
error[E0583]: File not found for module `decoders`
decoders.rs:
pub mod Decoders {}
image.rs:
mod decoders
use decoders::Decoders
pub mod Image {}
Note: I am using a module that wraps the entire file on purpose that's I can put attributes on entire files. This is why it's not a duplicate of How to include module from another file from the same project?
The weird thing is, is that this syntax works perfectly fine when I try to import Image in main.rs:
mod image;
use image::Image;
What's happening is that when you try to import decoders::Decoders in image.rs, you need to go through the next level up, because using this:
mod decoders
use decoders::Decoders
Means that decoders will now be "owned" or under image, which means that the compiler will search in the image subdirectory for decoders.rs. So, to fix this, you can either change your file structure to this:
src/
main.rs
image.rs ** or image/mod.rs
image/
decoder.rs
Or, use this in main.rs:
mod decoders;
mod image;
and this in image.rs:
use super::decoders::Decoders;
//Or alternatively
use crate::decoders::Decoders;
Also, to fix your nested-mod problem, do the following in decoders.rs:
//Your code, no `mod Decoders`
and the following where you have your mod decoders statement:
#[your_attribs]
mod decoders;
The rust compiler resolves modules differently depending on where they're defined.
When you use the mod keyword to declare an external module from the crate entry point (typically main.rs or lib.rs) or from a module root (mod.rs), the compiler will search for files adjacent to the declaring file. This is why it works properly when using mod image.rs in your main.rs file.
In other cases, the compiler will search for files in the folder with the same name as the declaring file. In your case, this means that your mod decoders; line in image.rs results in the compiler searching for the module in the image subfolder - specifically checking image/decoders.rs and image/decoders/mod.rs.
To fix this, you can either move decoders.rs to image/decoders.rs if you want to keep decoders as a submodule of image, or alternatively place mod decoders; in main.rs and leave the file where it is.

Could not import module frege.system.Directory (java.lang.ClassNotFoundException: frege.system.Directory)

I tried to import System.Directory in my Frege program (In Eclipse) in order to use functions as getDirectoryContent, etc., and it writes me this error :
Could not import module frege.system.Directory (java.lang.ClassNotFoundException: frege.system.Directory)
What do I have to do ?
It is because the module frege.system.Directory doesn't exist in Frege. A good way to find out about a module is to use Hoogle for Frege at this URL: http://hoogle.haskell.org:8081. If we search for that module there, we can see that it doesn't list any module as opposed to, say, if you search for frege.data.List, we would see the module in the result.
Now for the functions you need like getDirectoryContent, if you look at the search result for frege.system.Directory, the first result is about processes and the third and fourth results are about jars and zip files. If you click on the second result, it would open the module frege.java.IO and you can see some relevant functions that might be useful for you (list for example). However the Haskell module you are trying to find is not yet ported to Frege but it should, of course, be possible to port that module backed by native Java implementations.
Update for OP's comment
Here is a simple snippet to return the files under a given directory:
ls :: String -> IO [String]
ls dir = do
contents <- File.new dir >>= _.list
maybe (return []) (JArray.fold (flip (:)) []) contents
Regarding createTempFile, the following works for me:
frege> File.createTempFile "test.txt"
String -> STMutable RealWorld File

In Rust, what is the purpose of a mod.rs file?

In some Rust projects I've seen (i.e pczarn/rustboot), I've seen mod.rs files in directories for whatever reason. I've not been able to find documentation about this, and I've seen it in many other Rust projects.
What is the purpose of a mod.rs file, and when should I use it?
Imagine the following directory structure:
code/
`- main.rs
- something/
`- mod.rs
If in main.rs you do mod something;, then it'll look in the something/mod.rs file to use as the contents of the module declaration for something.
The alternative to this is to have a something.rs file in the code/ directory.
So to recap, when you write an empty module declaration such as mod something;, it looks either in:
a file called something.rs in the same directory
a file called mod.rs in a folder called something in the same directory
It then uses the contents of either of those files to use as the contents of the module declaration.
Modules are important to understand, but I find most documentations often leave you scratching your head on that matter.
Coming from Python or Javascript?
Roughly, mod.rs is kind of like __init__.py in python or index.js in javascript.
But only kind of. This is a bit more complicated in Rust.
Rust is different
Folders are not immediately ready to use as modules in Rust.
You have to add a file named mod.rs in a folder to expose a new module named like that folder.
The code in mod.rs is the content of that module.
All other files in the folder may in turn be exposed as submodules (more on that below).
Wait, there is another way
You may also use a file at the same level as a folder and named after that folder (<folder_name>.rs).
This is the preferred way since rustc 1.30. (Credits to MarkusToman in the comments)
From the Rust reference:
Note: Previous to rustc 1.30, using mod.rs files was the way to load
a module with nested children. It is encouraged to use the new
naming convention as it is more consistent, and avoids having many
files named mod.rs within a project.
Complete example
src
utils
bar.rs
foo.rs
main.rs
At this point, the compiler doesn't know about src/utils/foo.rs and src/utils/bar.rs.
First, you must expose src/utils/. As seen above, you have 2 options:
add the file: src/utils/mod.rs
add the file src/utils.rs (named exactly like the folder, without the extension)
Now, relative to the src folder (aka the crate level), a module named utils is available.
Second, you must expose the files src/utils/foo.rs and src/utils/bar.rs.
To do that, the utils module must declare 2 new submodules named after these files.
So the content of src/utils/mod.rs (or src/utils.rs) should be:
pub mod bar;
pub mod foo;
Now whatever is public in those 2 files is available in other modules! 🎉
And you may write the following in src/main.rs:
mod utils;
use utils::{foo, bar};
Resulting file structure
Option 1 • mod.rs (the old way):
src
utils
bar.rs
foo.rs
mod.rs
main.rs
Option 2 • <folder_name>.rs (the preferred way):
src
utils
bar.rs
foo.rs
utils.rs
main.rs
More advanced details on how modules work
This remains a surface explanation, your next destination is the official documentation 🧑‍🎓
There is a third way to declare modules (core language):
mod utils {
// module code goes here. That's right, inside of the file.
}
But it is also possible to just write mod utils;.
In that case, as seen above, Rust knows to search for either of src/utils.rs or src/utils/mod.rs.
See, when you try to use a module in a file (in src/main.rs for example),
you may reference it in the following ways:
from inside: src/main.rs
mod module { ... }
from nested modules inside: src/main.rs
mod module { pub mod sub_module { ... } }
from sybling files: src/*.rs
from mod.rs files in sybling folders: src/*/mod.rs
(and infinite reccursive combinations of the above)
A file or a folder containing mod.rs does not become a module.
Rather, the Rust language lets you organize modules (a language feature) with a file hierarchy.
What makes it really interesting is that you are free to mix all approaches together.
For example, you may think you can't directly reference src/utils/foo.rs from main.rs.
But you can:
// src/main.rs
mod utils {
pub mod foo;
}
Important notes:
modules declared in files will always take precedence (because you in fact never need to search the file hierarchy)
you can't use the other 2 approaches to reference the same module
For example, having both src/utils.rs and src/utils/mod.rs will raise the following error at compile time:
error[E0761]: file for module `utils` found at both "src/utils.rs" and "src/utils/mod.rs"
--> src/main.rs:1:1
|
1 | mod utils;
| ^^^^^^^^^^
|
= help: delete or rename one of them to remove the ambiguity
Let's wrap up. Modules are exposed to the compiler:
from top to bottom
by reference only
(That's why you don't have intellisense until your modules are "imported")
starting from an entry point
(which is src/main.rs or src/lib.rs by default.
But it may be anything that you configure in Cargo.toml.
This has little to do with this question however)
With our previous example we get in order:
src/main.rs -> crate
Because the crate module contains mod utils; we next get:
src/utils.rs OR src/utils/mod.rs -> crate::utils
Because the utils module contains mod foo; we next get:
src/utils/foo.rs -> crate::utils::foo
Each rs file, except lib.rs and main.rs, which always match the crate module, gets its own module.
There is only one way to declare a module:
/* pub */ mod sub_module1;
A module cannot be declare outside the root/crate module tree (i.e., going up the module tree, a submodule must always have a parent that is declared directly in lib.rs or main.rs, so the first program submodule must always be declared there — a tree data structure if it isn't already obvious enough).
There are 2 ways to nest a module inside the module where it is declared:
in <module_where_it_is_declared>/<module_name.rs>
in <module_where_it_is_declared>/module_name/mod.rs
If module_where_it_is_declared is the crate module, then this corresponding subfolder is not needed (disappears from the scheme above).
Here is an example, valid for both lib and binary crates:
src
|---lib.rs ( contains: pub mod b2; )
|---b2.rs ( contains: pub mod bb2; )
|---b2
| |---bb2.rs
. .
Alternatively:
src
|---lib.rs ( contains: pub mod b2; )
|---b2
| |---mod.rs ( contains: pub mod bb2; )
| |---bb2.rs
. .
You can see that you can mix and match (b2 uses mod.rs way, bb2 uses the "file"-way).
Here's a way to only use the file pattern that is also valid:
src
|---lib.rs ( contains: pub mod b2; )
|---b2.rs ( contains: pub mod bb2; )
|---b2
| |---bb2.rs (contains: pub mod bbb2; )
| |---bbb2.rs (contains: pub mod bbbb2; )
| |---bbb2
| | |---bbbb2.rs
. . .
I guess it depends on you how you want to nest modules.
I like the mod.rs syntax for modules that just export other submodules and don't have any other (or very little) code in them, although you can put whatever you want in mod.rs.
I use mod.rs similar to the barrel pattern from JS/TS world, to rollup several submodules into a single parent module.
Also don't forget modules can be defined (not only declared) inline by adding a scope block:
pub mod my_submodule {
// ...
}

Can Adobe .jsx scripts include other script files?

We're writing a bunch of .jsx scripts and in each I have to mock out some functions so I can use things like Array.map() and String.trim(), but I don't want to have to include that code at the top of every script.
Is there a way to "include" other .jsx scripts inside of a .jsx script file?
Or you can simply use #include and #includepath preprocessor directives at the top of your script.
You can find a detailed description in Adobe's "JavaScript Tools Guide".
For example, if you want to include scripts/helper.jsx in a .jsx file:
#include "scripts/helpers.jsx"
// the rest of your code below ...
Just leaving this here for anyone like me who is looking for this. In Adobe Illustrator CC 2015, I was unable to get #include to work, but #include did. So for example:
External File: foo.jsx
function alertTheWordNo(){
alert('NO');
}
The Script File: bar.jsx
//#include 'foo.jsx';
alertTheWordNo();
Disclaimer: I cannot find any documentation of this but have tested it with Adobe Illustrator CC 2015 and it works.
Hope this helps someone. If anyone has any questions just ask!
We're now using the $ helper available in Illustrator, and the $.evalFile() method. Pass it a path and it will evaluate the file and return the result.
I created a little helper that I can include (minified, of course) at the top of my .jsx scripts so I can do Libraries.include("my-other-script") that will include, in my case, a file that's in my adobe_scripts root folder, in a directory called lib.
// indexOf polyfill from https://gist.github.com/atk/1034425
[].indexOf||(Array.prototype.indexOf=function(a,b,c){for(c=this.length,b=(c+~~b)%c;b<c&&(!(b in this)||this[b]!==a);b++);return b^c?b:-1;});
var Libraries = (function (libPath) {
return {
include: function (path) {
if (!path.match(/\.jsx$/i)) {
path = path + ".jsx";
}
return $.evalFile(libPath + path);
}
};
})($.fileName.split("/").splice(0, $.fileName.split("/").indexOf("adobe_scripts") + 1).join("/") + "/lib/");
Minified version that I include:
/**
* Libraries.include(path) -- path must be relative to adobe_scripts/lib/
* See: https://gist.github.com/jasonrhodes/5286526
*/
[].indexOf||(Array.prototype.indexOf=function(a,b,c){for(c=this.length,b=(c+~~b)%c;b<c&&(!(b in this)||this[b]!==a);b++);return b^c?b:-1;});var Libraries=function(a){return{include:function(b){return b.match(/\.jsx$/i)||(b+=".jsx"),$.evalFile(a+b)}}}($.fileName.split("/").splice(0,$.fileName.split("/").indexOf("adobe_scripts")+1).join("/")+"/lib/");
See gist here: https://gist.github.com/jasonrhodes/5286526
Just wanted to add a note to Ike10's answer. Undocumented is generous - this is the worst "documentation" I've ever come across in 20+ years of writing code. It seems to me that you must also add the CEFCommandLine argument to your manifest.xml file before the primary JSX file will load/eval external files:
<Resources>
<MainPath>./whatever.html</MainPath>
<ScriptPath>./jsx/whatever.jsx</ScriptPath>
<CEFCommandLine>
<Parameter>--allow-file-access</Parameter>
<Parameter>--allow-file-access-from-files</Parameter>
</CEFCommandLine>
</Resources>

Rails 3 : `require` within a generator

I am writing a Rails 3 generator, but things get a bit complicated so I would like to extract some code to put it in a separate file.
So I create a file in the generator folder, and within my generator file, I put at the top:
require 'relative/path/to/my/code.rb'
But when I launch the generator, it tells me that it can't find the file.
activesupport-3.0.0.rc/lib/active_support/dependencies.rb:219:in `require': no such file to load -- relative/path/to/my/code.rb (LoadError)
Does anybody know a work around ?
It depends which Ruby version you are using.
In 1.8, it should work as you do. In 1.9 you should use require_relative.
You should also not add '.rb' at the end, this is not recommended.
The danger with a simple 'require' with a relative path is if this script is itself required by another, then the path will be relative to the first script called:
rootdir
- main.rb
- subdir1
- second.rb
- subdir11
- third.rb
If main.rb is called, and then require second.rb (with 'subdir1/second'), and then you want to require third.rb with 'subdir11/third.rb', it will not work.
You could be relative to the first script (subdir1/subdir11/third.rb), but that is not a good idea.
You could use __FILE__ and then make it an absolute path:
require File.expand_path('../subdir11/third.rb', FILE)
(the first .. is to get in the directory which contains the file) or
require File.dirname(FILE) + '/subdir11/third.rb'
But the most common practice is to reference it from the rootdir.
In a gem, you can assume the rootdir will be in the $LOAD_PATH (or you can add it yourself).
In Rails you can use require "#{RAILS_ROOT}/path" (rails2) or
require Rails.root.join('path') (rails3)