I'm using require.js and optimize it with the node module r.js.
It works but I have one problem when trying to require a module after I've included require.js.
That's what I need:
<script data-main="/js/app-built" src="/js/vendor/require.min.js"></script>
<script type="text/javascript">
require(['Functions'], function(Functions){
console.log(Functions);
});
</script>
This doesn't work, as it doesn't find the Functions module.
But this works:
<script data-main="/js/app-built" src="/js/vendor/require.min.js"></script>
<script type="text/javascript">
require(['app-built'], function(){
require(['Functions'], function(Functions){
console.log(Functions);
});
});
</script>
Is there a way to achieve the first approach?
In your first snippet the problem is that by the time the first require call executes, it is quite possible (quite likely in fact) that RequireJS has not yet loaded your application. The data-main attribute initiates right away the loading of your main module but it only initiates it right away. The loading is still asynchronous. And the reason it works in your second snippet is that the outer require forces the inner require to execute after your main module is loaded.
So for your require call to be successful, RequireJS must have enough information to load it. So it must already have a configuration that will allow it to find your module. This either adding some configuration before you load RequireJS. You can set require to a configuration object which will be picked up by RequireJS when it is loaded:
<script type="text/javascript">
require = {
// Enough config to find the main module.
baseUrl: ...,
paths: ...,
bundles: {
// List here every module you want to load individually.
"app-built": ["Functions"]
}
};
</script>
<script src="/js/vendor/require.min.js"></script>
<script type="text/javascript">
require(['app-built']);
require(['Functions'], function(Functions){
console.log(Functions);
});
</script>
You don't have to pull the whole config out of your main module because RequireJS can combine configs, but there need to be enough there to allow RequireJS to start loading things. The app-built module could contain additional configuration that is not needed for the initial steps. In the code above I've dropped data-main and used require(['app-built']) instead because I'm not sure whether it is possible to still use data-main even when using the bundles parameter. (I'm concerned it might confuse RequireJS.) Using bundles will allow RequireJS to know that when you require Functions, it must find it in app-built.
Apart from perhaps still being able to use data-main instead of the initial require call (which I'm not sure you can do), I do not think it is possible to simplify this further.
Related
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.
I'm using requirejs in a large project. This project will soon be upgraded to angular2.
Angular2 uses system.js, so I'm thinking of switching to system.js too. Should I be able to remove the reference to the requirejs library and include system.js instead and expect it to work, or is there something I don't understand here?
I tried by just removing the require.js file and adding the system.js file instead, but I get error messages saying define is not defined.
Can you help? Will I need require.js in addition to system.js?
I just switched to system.js too. You need to replace your require.js with system.js and add simple script tag. So it should look like this:
<script src="~/lib/system.js/dist/system.js" type="text/javascript"></script>
<script>
// set our baseURL reference path
System.config({
baseURL: '/app'
});
System.import('startup.js');
</script>
in addition to above steps set
System.defaultJSExtensions = true;
by default systemjs is not adding extension .js
This is very weird because it was all working Friday, and now it doesn't. When my program first starts, it fails on the very first require with "Module name "../common/windward" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded"
test-layout.html:
<script src="../../libs/jquery.js"></script>
<script src="../../libs/es6-promise.js"></script>
<script data-main="test-layout.js" src="../../libs/require.js"></script>
test-layout.js:
var windward = require('../common/windward');
The requireJS manual wants the first require to be:
require(['foo'], function (foo) {
//foo is now loaded.
});
However, this is the way the typescript compiler creates the .js file (for amd). And it worked 3 days ago.
Is there something else I need to do to get requireJS started?
this is the way the typescript compiler creates the .js file (for amd).
No. It should generate:
define(["require", "exports", "../common/windward"], function(require, exports, windward) {
});
Something seems to be calling --module commonjs in your pipeline.
I am creating a wirejs app using requirejs. For IE 8 I am using polyfills: cujo/poly js library and require this lib be preloaded before wirejs is loaded.
If I used curl as the AMD loader, as per the documentation, I have following option available:
curl({ preloads: [ "poly" ] });
What works for me is:
// in index.html
<script data-main="js/app" src="js/lib/require.js"></script>
// in js/app.js
define(function(){
// set configuration options
requirejs.config({// set config with paths});
// require the library and HOPE it will load before
// everything else!
require(['poly']);
});
This document recommends using shim config for this purpose. However, I haven't been able to figure out how. Some of the things I tried:
// DID NOT WORK!!
requirejs.config({
....
"shim": {
"poly": {
"exports": "poly"
}
}
});
Is there a better way to approach this?
Any help appreciated!...thanks for your time!
I do use RequireJS together with polyfills, but I don't use RequireJS to load them. The goal of a polyfill is to make a browser which lacks feature X look as if it does in fact have feature X. I prefer a setup in which all the code I run (with the exception of the polyfills themselves) runs with the polyfills already loaded so that the code runs with the same set of features available to it, no matter what browser runs the code. So I want my polyfills loaded before RequireJS too.
But if we ignore this preference, could RequireJS be used to load the polyfills? Yes, but RequireJS won't make it easy. There's no trivial way to tell RequireJS "this body of code must be loaded before you load anything else", which is what you'd want for polyfills. What you'd have to do is manually invoke require so that your polyfills are loaded first. Your index.html could be something like:
<script>
require = {
// Your config.
//
// Setting a global require before loading RequireJS is one way to give it
// a config.
};
</script>
<script src="js/lib/require.js"></script>
<script>
// No data-main above...
//
// This double require ensures that the polyfills are loaded first.
require(["poly"], function () {
require(["js/app"]);
});
</script>
js/app.js becomes:
define(function(){
// whatever...
});
In a large application where there may be multiple entry points other than js/app, you have to use the double require like above every time you want to load a module from outside a RequireJS module to ensure that the polyfills are loaded first.
I ran into the same problem, and my solution was to make Require.js load the polyfills as dependencies for me. You can see in this gist how I solved it in combination with Conditioner.js, but the solution is the same without it.
I've chosen to feature detect loading polyfills, so newer browsers don't make unnecessary requests. Feature detection makes this specific solution superior.
In your index.html:
<script src="/js/require.js" data-main="/js/main"></script>
In the file /js/main.js:
var _polyfills = [];
if (!('classList' in document.documentElement)) {
_polyfills.push('polyfills/classList');
}
// ... more feature detects & polyfills ...
require(['bootstrap'].concat(_polyfills), function(bootstrap) {
bootstrap.run(); // Bootstrap your app here!
});
I have a built library (concatenated, minified and included before require.js) of several globals (jQuery + plugins, constructor functions, etc ). This library is used as a base on which apps are built on top of, with assumed dependencies. i.e, if I include my app scripts after the library, then I can freely use jQuery and constructors without any issues.
For bigger apps I'm considering using requirejs (to manage the different modules within the app), while still using this built library. How might I add existing globals like jQuery to the dependency list in require?
<script src="pathto/lib.js" type="text/javascript"></script>
<script src="require.js" data-main="../js/app" type="text/javascript"></script>
requirejs.config({
shim: {
'jquery': {
exports: '$'
}
},
// jQuery is already loaded with lib.js, no need for any path...
path : {
jquery : 'jquery.js'
}
});
Is this possible? Or should I just continue with assumptions that certain globals will exist within the app modules because lib.js was included before require / the app js?
Using require to load the lib.js is not possible, because it is part of a CMS.
-- EDIT --
What about using a named module, and just return a handle on the global object, as that is where the lib content sits anyway?
define("lib", function () {
return this;
});
require(["lib"], function (lib) {
// use existing globals found in lib via
lib.jQuery
// or simply
jQuery
});
That allows me to follow the require() convention of naming dependencies, rather than assuming.
I am doing the exact same thing for my project where I load jquery from a CDN, so my path configuration looks like this
path: {
'jquery': '//path/to/the/cdn'
}
In your case, I think you should do as you updated (define and then return), because in some 3rd-party libraries, they might define jquery as the dependencies. If you don't have jquery in your RequireJS configuration, you have to modify the source code of the 3rd party libraries