I'm getting this error when I browse my webapp for the first time (usually in a browser with disabled cache).
Error: Mismatched anonymous define() module: function (require) {
HTML:
<html>
.
.
.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script> var require = { urlArgs: "v=0.4.1.32" }; </script>
<script data-main="assets/js/main" src="assets/js/libs/require.js"></script>
<script src="assets/js/ace/ace.js?v=0.4.1.32"></script>
</body>
</html>
JS:
$(function () {
define(function (require) {
// do something
});
});
Anyone know exactly what this error means and why its happening?
source file, a short discussion about it in the github issues page
Like AlienWebguy said, per the docs, require.js can blow up if
You have an anonymous define ("modules that call define() with no string ID") in its own script tag (I assume actually they mean anywhere in global scope)
You have modules that have conflicting names
You use loader plugins or anonymous modules but don't use require.js's optimizer to bundle them
I had this problem while including bundles built with browserify alongside require.js modules. The solution was to either:
A. load the non-require.js standalone bundles in script tags before require.js is loaded, or
B. load them using require.js (instead of a script tag)
In getting started with require.js I ran into the issue and as a beginner the docs may as well been written in greek.
The issue I ran into was that most of the beginner examples use "anonymous defines" when you should be using a "string id".
anonymous defines
define(function() {
return { helloWorld: function() { console.log('hello world!') } };
})
define(function() {
return { helloWorld2: function() { console.log('hello world again!') } };
})
define with string id
define('moduleOne',function() {
return { helloWorld: function() { console.log('hello world!') } };
})
define('moduleTwo', function() {
return { helloWorld2: function() { console.log('hello world again!') } };
})
When you use define with a string id then you will avoid this error when you try to use the modules like so:
require([ "moduleOne", "moduleTwo" ], function(moduleOne, moduleTwo) {
moduleOne.helloWorld();
moduleTwo.helloWorld2();
});
I had this error because I included the requirejs file along with other librairies included directly in a script tag. Those librairies (like lodash) used a define function that was conflicting with require's define. The requirejs file was loading asynchronously so I suspect that the require's define was defined after the other libraries define, hence the conflict.
To get rid of the error, include all your other js files by using requirejs.
Per the docs:
If you manually code a script tag in HTML to load a script with an
anonymous define() call, this error can occur.
Also seen if you
manually code a script tag in HTML to load a script that has a few
named modules, but then try to load an anonymous module that ends up
having the same name as one of the named modules in the script loaded
by the manually coded script tag.
Finally, if you use the loader
plugins or anonymous modules (modules that call define() with no
string ID) but do not use the RequireJS optimizer to combine files
together, this error can occur. The optimizer knows how to name
anonymous modules correctly so that they can be combined with other
modules in an optimized file.
To avoid the error:
Be sure to load all scripts that call define() via the RequireJS API.
Do not manually code script tags in HTML to load scripts that have
define() calls in them.
If you manually code an HTML script tag, be
sure it only includes named modules, and that an anonymous module that
will have the same name as one of the modules in that file is not
loaded.
If the problem is the use of loader plugins or anonymous
modules but the RequireJS optimizer is not used for file bundling, use
the RequireJS optimizer.
The existing answers explain the problem well but if including your script files using or before requireJS is not an easy option due to legacy code a slightly hacky workaround is to remove require from the window scope before your script tag and then reinstate it afterwords. In our project this is wrapped behind a server-side function call but effectively the browser sees the following:
<script>
window.__define = window.define;
window.__require = window.require;
window.define = undefined;
window.require = undefined;
</script>
<script src="your-script-file.js"></script>
<script>
window.define = window.__define;
window.require = window.__require;
window.__define = undefined;
window.__require = undefined;
</script>
Not the neatest but seems to work and has saved a lot of refractoring.
Be aware that some browser extensions can add code to the pages.
In my case I had an "Emmet in all textareas" plugin that messed up with my requireJs.
Make sure that no extra code is beign added to your document by inspecting it in the browser.
Or you can use this approach.
Add require.js in your code base
then load your script through that code
<script data-main="js/app.js" src="js/require.js"></script>
What it will do it will load your script after loading require.js.
I was also seeing the same error on browser console for a project based out of require.js. As stated under MISMATCHED ANONYMOUS DEFINE() MODULES at https://requirejs.org/docs/errors.html, this error has multiple causes, the interesting one in my case being: If the problem is the use of loader plugins or anonymous modules but the RequireJS optimizer is not used for file bundling, use the RequireJS optimizer. As it turns out, Google Closure compiler was getting used to merge/minify the Javascript code during build. Solution was to remove the Google closure compiler, and instead use require.js's optimizer (r.js) to merge the js files.
Related
I'm using gulp to combine my scripts in order to load only one file in HTML (make it faster).
Here's a sample code, name of libraries don't matter much, you'll get the idea :
// gulpfile.js
mix.scripts([
'vendor/jquery-2.1.1.min.js',
'vendor/angular.js',
'vendor/slideout.min.js',
'vendor/dirPaginate.js',
'vendor/cookie.js'
], 'public/js/libs.js');
And then I do this :
// app.js
let app = angular.module('app', ['angular-slideout', 'cookie', 'dir-paginate'], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
export default app;
I only use one file to load every NG library in my project, and then I import this app in my controllers. Now this is only an example, but I already have conflicts depending on the order of mixing these scripts in.
Any advice on processing this ? I already had to ditch some libs I wanted to use because they were conflicting with others. Going on this way, this looks like a dead end.
I have a situation using system.js with an angular application where I need to be able to include specific System.import(f) statements on a per-page basis, but it was imperative that they all be included before angular finishes bootstrapping and loading up its module.
I spent a long time on this problem and eventually this is the workaround I devised;
in my config.js, I am doing this...
config.js
// .... configuration ... //
Promise.all([
System.import('jquery'),
System.import('angular'),
System.import('angular.ng'),
System.import('bootstrap')
]).then(function() {
$(document).on('angular', function() {
angular.bootstrap(document, ['module-name']); $('body').removeClass('cloak');
});
});
Then I have a css class named .cloak. I tried ng-cloak but found it wasn't doing the job (I suspect because I'm deferring the angular bootstrapping)
.cloak { visibility: hidden; }
then on my individual page, I use this sort of code to shoe-horn my page-specific imports and finalize the process.
<!-- Load SystemJS -->
<script src="assets/js/system.js"></script>
<script src="config.js"></script>
<script>
System.import('app/main').then(function (e) {
Promise.all([
System.import('app/controllers/index'),
System.import('app/controllers/read'),
System.import('app/controllers/edit/article'),
System.import('scripts/lib/init')
]).then(function (m) {
$(document).trigger('angular');
});
});
</script>
So that's the basic idea; I don't allow angular to finish wiring up its module until everything has been imported through system.js. At present, this seems to work fine.
My problem is that I'm not a very good programmer, nor am I very clever. This seems like an extremely standard, normal problem that comes with the way system.js is designed and it occurs to me that there has to be a better, built in solution that I'm missing or haven't found.
Has anyone else dealt with this before that can offer some advice?
The reason I need to defer the module wiring is because I've got various angular controllers and models and such and I don't want them all to load on every page. (I mean, trimming down the scripts to only the ones needed at the moment is one of the points of a module loader, aside dependency resolution).
Trying to use the ng-app directive was constantly causing trouble - as angular would try to load before everything was finished and loaded in, so it had trouble finding things like certain controllers and the like on certain pages.
The biggest reason I need an alternative is that this method doesn't work well for minifying typescript.
This is an extremely standard issue with ng-cloak in general. Perhaps a better way has come around, but pretty much since I started working with angular I've just defined ng-cloak in the header of my index.html file like this:
<style>
[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak {
display: none !important;
}
</style>
and added class="ng-cloak" to the body tag of my page. It works great and when Angular finishes loading it's internal ng-cloak styles effectively overwrite mine.
It seems like moving the inline script basically as is, to an external file, would still allow it to run exactly as you have it and then minification and such would be fine.
It also sounds like you're not creating a SPA here, since if I understand you correctly, you're calling config.jss from each page. You may want to reconsider that and go with a SPA. You will likely end up loading everything up front, but you'll load it all only once.
I understand that requirejs and browserify can load my files dependent on its current context, and that it is amazing. I would really prefer to use the #section sections syntax that the razor engine uses. Was just wondering if there is a way to implement this into a typescript / angularjs application.
for example
index.html
#renderSection scripts;
// which could turn into something like
<script data-render="scripts"></scripts>
// the app.run() could declare all the scripts that will be needed on every
// page view
view.html
<script ng-section-repeat="injected in injection"></script>
// the ng-section-repeat is basically taking all the items in the
// typescript constructor and then finding out which ones are needed for
// that view.
I like the idea injecting application file dependencies in the view , without a configuration file and all the added extras that comes with the loaders.
I just want to easily define what files are needed in the actual view and get them loaded, with angular's dependency injection handling the dependency itself.
If you are handling all your dependencies with $inject then , as far as i can tell, dependency is technically already setup in the controllers, all one would need, is to load this as it is called. Which could even eliminate the need for the #section scripts completely
Update:
What i have done to sort of replicate the module loaders is to just use gulp-concat and define the file order in my gulp.config.js and then pass it to the gulp-src before running $.concat .this allows me to have the files in the gulp steam , in dependent order . They are however loaded on the first load. With gulp-uglify the files are tiny ( its now at 566Kb with 16 external libraries loading in 69ms . To put that into perspective it takes 209ms to load one google font ).
I dont know maybe i am not understanding browserify correctly but i honestly struggle to see the need for it, its seems extremely convoluted for something so simple
It is possible using external modules and an injector to do what you asked for:
I just want to easily define what files are needed in the actual view
import {UserFactory} from 'models/userFactory';
import {UserValidator} from 'models/userValidator';
import {Inject} from 'angular2/di';
and get them loaded, with angular's dependency injection handling the dependency itself.
Note: My example uses angular 2.x because I less familiar with angular 1.x and I'm sure you can do something really similar...
class SomeComponent {
userName: string;
userRating: number;
rating: number;
constructor(
#Inject(UserFactory) UserFactory
#Inject(UserValidator) UserValidator
)
{
this.UserFactory = UserFactory;
this.UserValidator = UserValidator;
}
}
Then you can use Browserify to create a bundle.js file that can be executed in a web browser.
I am trying to set up tests for my Angular.js project and I keep getting "$injector:nomod, Module 'result' is not available! You either misspelled..." error. I am sure that I am including "result" module in the "files" array inside "karma.config.js", basically it looks like this:
files: [
'../javascripts/jquery-2.1.4.min.js',
'../jquery-ui/jquery-ui.min.js',
'../D3/d3.js',
'libs/angular.min.js',
'libs/angular-route.min.js',
'libs/angular-animate.min.js',
'libs/selectize.js',
'libs/angular-selectize.js',
'libs/angular-mocks.js',
'simulator.js',
'*.js',
'services/**/*.js',
'qa/tests-*.js'
],
...
I thought initially that the ordering of the main module: 'simulator' (defined inside 'simulator.js' file) is wrong, so I specifically moved it upwards, before
the other modules, like the following stackoverflow thread recommends:
Angular module not available in Karma Jasmine test run
It did not help. Then I tried to make sure that the files are imported in the same order as in my angular apps' main entry file (except for angular-mocks.js and qa/tests-*.js), importing each single file, instead of using wildcards, but no success.
Jasmine definitely goes inside the test files but stumbles upon the line where I am trying to import the module "result":
describe('simulator.chartService', function() {
var chartService;
var graphConfig;
console.log("instantiating module result");
beforeEach(module('result'));
console.log("finished instantiating");
beforeEach(inject(function($injector) {
graphConfig = $injector.get('graphConfig');
chartService = $injector.get('chartService');
}));
it('should be created', function() {
expect(chartService.calcColors(10)).not.toBeNull();
});
});
So, I see that the error happens in-between two console.log() statements.
I suspect that still something can be wrong with the ordering of my files inside the array "files" in "karma.config.js". I have main module "simulator" which is dependent on other modules:
angular.module('simulator', ['ngRoute','ngAnimate','selectize','newexp2','newexp','login','edit','exps', 'result','templates','commons'])
Modules 'newexp2', 'newexp', 'login', 'edit', 'exps', 'result', 'templates' are all dependent on the module 'commons'.
How to correctly import interdependent modules inside the "files" array?
Is it just enough to place "simulator.js", main module, above all others,
or I also need to place all other modules before "commons.js"?
Another my suspicion is that angular.js library version that I downloaded from the official angular website, "angular-mocks.js", can be incompatible with other modules that I am using. I had such an issue with "angular-animate.js" file before.
As long as I surround my test code with $(function(){...}) (and all other my modules ARE surrounded with it) it does not generate the error while importing the result module, so I start seeing two console.log() statements without an error in-between, however, this generates some unknown error which prevents me from invoking the it part at all, whereas when I do not surround it with $(function(){...}), the it test is invoked, but the module result import fails.
So far I am pretty much stuck and do not know where to move and what to try. Any suggestion would be greatly appreciated.
OK, I figured it out. The issue was that ALL of my angular code was enclosed inside $(function(){...}). The solution is to remove all of the $function(){...}), then reorder javascript imports inside the main entry .html file, and then all of the testing starts working good.
The question might be better to mark as duplicate with:
Angular document.ready() issue
I have a service that I call during app.run() and for some reason when I load the files async at that point they don't seem to take.
Here's the service i'm using:
angular.module('nav').service('SubmoduleService', ['submodules_config',
function(config){
this.autoload = function(){
for(var key in config.modules){
for(var i=0; i<config.modules[key].length; i++){
var src = config.modules[key][i].replace(':path', config.path).replace(':name', key);
console.log(src);
var js = document.createElement("script");
js.type = "text/javascript";
js.src = src;
document.body.appendChild(js);
}
}
return true;
};
}]);
Here's the config file:
angular.module('nav').constant('submodules_config', {
path: "scripts/submodules/:name",
modules: {
gallery: [':path/config.js', ':path/directive.js']
}
});
So basically the config defines a module and all the files that need to get loaded for that module.
I see the files get loaded into the DOM, but for some reason when I load the controller that uses that directive, it doesn't work.
NOTE: The directive works when loading the files explicitly.
Any help is appreciated.
E
By default, angular bootstraps the application on the DOM Ready event. When you load scripts asynchronously, this event can be fired before the scripts load, so angular won't know about the directives contained in them when the DOM is $compiled().
There are quite a few ways to work around this, but they all revolve around deferring compilation of the DOM until the required modules are loaded.
On simple (but not the only) way to defer compilation for a fragment of your application is to simply use ng-if. In pseudo code, it would look something like this:
<div ng-if="moduleWithMyDirectiveLoaded" my-directive></div>
This leaves you with the task of figuring out how to determine if a particular script has been loaded and getting that information into your angular application.
Unfortunately, this isn't trivial. You can write this yourself, but others have already done it for you and you'd probably be better off using one of those tested, cross-browser solutions.
require.js comes to mind as an option, but there are many others that would also work.