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.
Related
I'm trying to convert a requirejs project to use webpack. In the Index page, before the webpacked bundle.js script is called, a requirejs module is defined inline that uses some Razor directives to set some js variables from the c# controller. This requirejs module is then referenced a few places in other js files.
When I try webpacking my js files, obviously webpack can't find this module, and I can't separate it into its own js file because it contains Razor statements.
I can't think of a way around this, but perhaps there is? Help, please...
I am refactoring a extremely large javascript file into multiple files with es6 modules / webpack. To start with, I am moving a single function out of giantFile.js into singleFunction.js, and then importing this new function file into index.js, which is the entry point for webpack to create bundle.js, which is then included in my template.html file as a script tag. In my template file, I also include giantFile.js as a script tag, which calls the function in singleFunction.js.
Is it simply a case of getting the script's imported in the correct order, or am i mistaken in my understanding of how giantFile.js can access the newly created modules.
Currently, within the console, when I type singleFunction(), i receive 'is not defined' error message', and so it would be good to check my understanding is correct of how I can use modules before further debugging. If anyone can point me towards some good resources on refactoring front end javascript and best practives that would be much appreciated too. Many thanks.
in singleFunction.js
`export default function singleFunction() {...}`
in index.js
import singleFunction from './components/singleFunction'
in template.html
<script src="/frontendHotness/components/singleFunction.js"></script>
<script src="/unstructuredMess/js/giantFile.js"></script>
The webpack compiled version of your giantFile.js should still be your application's entry point and the only file that is embedded in your HTML file using the <script> tag.
During your refactoring, you should gradually move well-encapsulated bits of functionality into separate files, or modules. Those modules export the functionality, to be used by dependent modules.
Your parent module, in this case giantFile.js can now import the different modules it depends on. These dependencies will be resolved by webpack, which moves your parent module together with all its dependencies into one JavaScript file that you can load from your HTML page.
Note that this dependency tree can be arbitrarily deep - your submodules can itself depend on other modules. You should however ensure that your modules encapsulate the functionality to do one particular job while being loosely coupled with other modules. Also avoid circular dependencies.
what is the advantage of using dependency injection over requiring modules?
/* with dependency injection */
app.controller('testCtrl', function(dep){
/* use dep... */
});
/* with require */
app.controller('testCtrl', function(){
var dep = require('./dep');
/* use dep... */
});
Those are 2 distinct things.
require is AMD's thing which solves loading of modules so you don't need to include <script> tag in order to load .js file. For that you can use libraries like requireJs
angular dependency injection is angular's thing to load angular modules like $scope, $http etc but those you have in angular and don't need to be loaded with require.
AMD you can use to load another files like another module, service or factory in different file and you want asynchronously load this file when needed you use define() or require() (see requirejs documentation) to load those files. Once you have files loaded with require you need to use angular's DI to to get reference to them in order to use them.
Without require you would need to have files from your service included somewhere in index.html in <script> tag
this is good article about using requirejs in angular.
Hope this will help you clarify stuff.
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
(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.