RequireJS and a multilanguage website - javascript

(warning: I am a newbie with require.js)
I am using the RequireJS Optimizer to combine all require.js JS files into one file and I don't know why the output JS file contains only the root bundle.
My lang/nls/strings.js file is http://pastie.org/private/7o6fa7sfrxvppu4lcunz0a
And after running 'node r.js' there is no 'lang/nls/de/strings' declaration http://pastie.org/private/dyktxwv4wgdywbj8mltw , although I have a require/lang/nls/de/strings.js file
The build example of r.js https://github.com/jrburke/r.js/blob/master/build/example.build.js states that 'Only one locale can be inlined for a build' but I hope there is a way to include in the optimized file all the language strings that my app need. So how can I achieve this ?

As you read only one local can be inlined, which totally makes sense as you dont wanna load all locals, cause in most cases the user needs only one. RequireJS will automatically detect whats the browser local and load the missing locals if they exist. If you need all locals, dont use requireJS and inline them as plain JSON.

Related

Using webpack and publicPath for static resources

The following question was rewritten, because I have now a working solution, but no answer to the question above.
The repository that shows different scenarios how to use resources packed with webpack is named example-webpack-dynamic-resources. It contains 3 modules:
inline: a solution, but not useful in my context (many resource files)
file: a solution by using the plugin webpack-require-from
public-path: no solution yet, shows how I would like to use __webpack?public_path__.
I think I have read any resource about webpack and publicPath and __webpack_public_path__, but I don't get it to work. I try to dynamically change the path to static resources, but it fails.
Here is my context:
I build a Javascript library that will be used on web pages (HTML, CSS, Javascript).
It provides a lot (>100) static resources to small image files, combined > 500 KB. Only a fraction of it will be used by the user looking at the web site.
Therefore I would like to pack the CSS into the bundle, but keep the image resources in a directory located on the server somewhere. The default path to it will be /img.
As long as I use the same structure (which means, images only under ROOT/img/**, everything is ok.
But the users of the library should be able to configure the path to the image resources on their will.
You will find all relevant files in my example repository example-webpack-dynamic-resources in the module public-path-resources.
webpack.js: Use file-loader for images, which are referenced in CSS files. CSS will be inlined by style-loader and css-loader.
src/public-path.js: Define the global variable with a default (no environment variable).
src/index.js: require first public-path, then the logic.
examples/exam1-root/index.html: Tries to use the assets in the sub directory lib, sets the value therefore to __webpack_public_path__ = '/lib/. Not working.
examples/exam2-different-dirs/index.html: Moves the library to a different dir (not relevant), but uses the originally defined directory pgnv-assets for the assets. Working.
examples/exam3-non-standard-dirs/index.html: Try to use instead my-assets as directory for the assets. Not working.
How could the __webpack_public_path__ defined at runtime in the index.html file?

Not found .map extension from node_modules in rails app

I try to integrate angular to rails app. I extended assets folder by
config.assets.paths << Rails.root.join('node_modules')
and it's good work but my console has serveral messages error
http://localhost:3000/assets/rxjs/Subject.js.map
Rails app couldn't .map extension how to load it
Those are "javascript source map" files. If your Subject.js javascript file has been minimized/uglified, then you can generate and add a "map" file to let browsers know how to "unminimize"/"unuglify" your js file.
If the Subject.js file is written by you, then I guess your environment setup with different node.js and gulp.js modules has it enabled. Make sure those files are copied to your /assets folder as well.
Alternatively, you can disable them by removing special comment at the end of your javascript file:
//# sourceMappingURL=/assets/rxjs/Subject.js.map
Or, less likely, your server might be sending X-SourceMap header.

Is it OK to write one JavaScript file containing multiple modules?

It just comes to my mind that most AngularJS (*.js) file I have seen so far only contains one module, and the name of the module is not always the same to the file name.
I would like to know, whether it works by putting multiple modules inside one AngularJS (*.js) file.
Also, how does the server find the correct module name when web page makes a function call? By searching every file in the directory in a brute-forced way?
You can put as many modules as you want in a file (not necessarily best practice though). Angular knows which module to load because you register each module with Angular.
angular.module('myModule', [])
That way it doesn't have to look for modules based on convention.
A module name is referenced in your HTML by using ng-app="yourModule" on an HTML element. Having several modules in a single file is not an issue at all. It's actually what minification and obfuscation processes do for production ready code: Combine all you Javascript code in a single file.
What I would suggest is:
Use several files in development mode for the sake of clarity
Use minification to have just one file in production for efficiency purposes
Yes it is okay to put multiple modules in a single file. You have to register all available modules before the app is bootstrapped otherwise it will give you a dependency error. The page on dependency injection explains it all.
It is a good practice to use different file for each module declaration. You can take a look at the following guide: Angular Style Guide
You register your each module using angular.module, and you define your services, controllers etc using your defined modules.
angular.module("myApp", []); // module is registered
angular.module("myApp").service("myService", function(){}); // service is declared for myApp module.

How can i use the RequireJS optimizer to optimize my app to not use RequireJS anymore?

The Answer is below the question:
Maybe I don't understand the whole RequireJS thing fully,
but here is my problem:
I got a set of files like that:
sub
sub1.js
sub2.js
main.js
In all of the files in sub, i use the define() function to define modules. In the main.js, i use the require() function to load all modules. All of this works.
Now when i run the optimizer (r.js) on the main.js, it just takes the content of all files and puts it into one file. Yes, i can then use this optimized file to do the same as what i could do with the multiple files.
All good, no error.
Now my question: In that optimized file, it still uses RequireJS. Can i optimize it to the point, where it doesn't use RequireJS, where it's just the functions put together?
Answer
You can only include RequireJS into your optimized file by setting the include option to "requireLib".
Are you trying to load the file in the script tag w/o using data-main + require.js? OR, are you trying to render the file so that RequireJS is no longer used at all? I suspect it's the latter, which is not possible. If the former, that is achieved by bundling Require in via a build file option: http://youtu.be/m6VNhqKDM4E?t=12m44s
No you cant. The point of the r.js is to compile all your dependencies situated in multiple files into one. So even after compiling the modules are still AMD modules, but now without the need to load them separately. And the modules still need an AMD loader to get work. The only thing you can do after compiling is to use a more lightweight loader loader like Almond

URL cache-busting parameters with RequireJS?

I'm using RequireJS (the jQuery version) and I want to append GET parameters to my scripts to prevent unwanted caching.
I'm using the urlArgs parameter, as suggested in the docs. This is my app-build.js file:
({
appDir: "../",
baseUrl: "scripts/",
urlArgs: "cache=v2",
...
Then I build the project as follows:
$ node ../../r.js -o app.build.js
The output in app-build directory now contains both require-jquery.js, which is the same file as previously, and require-jquery.js?cache=v2, which is blank.
The index.html file doesn't seem to have any references to cache=v2. And when I load the page in a browser, I don't see any cache=v2 parameters appended to any of the scripts.
Am I doing something wrong?
The docs on urlArgs:
“During development it can be useful to use this,
however be sure to remove it before deploying your code”
and this issue from Github, James Burke:
“do not try to use urlArgs during build”
The urlArgs parameter is more of a runtime configuration (i.e., only understood by RequireJS, not the r.js optimizer), seemingly due to its author's stated belief that it is only suited to development (and "bad" dev servers that don't send proper headers). So you'd either need to configure it in your require.config call (in a .js file loaded by require.js, typically main.js or config.js):
require.config({
// other config, like paths and shim
urlArgs: "cache=v2"
});
Or, per this other SO answer, you'd define it in directly in a <script> block before loading require.js.
I would try using a different build.js file for the optimizer vs the build.js file you use running the live app. Based on your description, the optimizer script doesn't seem to properly handle the urlArgs parameter (since it's outputting a file called require-jquery.js?cache=v2).
I wouldn't expect cache=v2 to show up in index.html (why would it?), but you're right to expect it in the network activity log.

Categories

Resources