Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I prevent the Require.js optimizer from including the text plugin in optimized files?

tl;dr: How do I keep the text.js plugin out of my optimized file when all my text dependencies are inlined?

I'm using the Require.js optimizer (via Node) to optimize some of the JS files in my project. I'm using the text plugin to load text dependencies (HTML templates, CSS). I've got a module I want to optimize, including its dependencies, like this:

define(['text!core/core.css'], function(styles) {
    // do setup stuff, return an object
});

The Require.js docs say that the core/core.css file will be inlined when I run the r.js optimizer, which I'm invoking like this:

$ r.js -o baseUrl=./src name=core out=release/test.js

Tracing dependencies for: core
Uglifying file: c:/path/release/test.js

c:/path/release/test.js
----------------
c:/path/src/text.js
text!core/core.css
c:/path/src/core.js

The good news is, this works. When I look at the optimized file, I can see the inlined text, something like this:

define("text!core/core.css",[],function(){return"some CSS text"}),
define("core",["text!core/core.css"],function(a){ ... })

The bad news is, the text.js plugin is also included - it adds about 3K, and consists of (as far as I can tell) now entirely unnecessary code for loading external text files. I know 3K isn't much, but I'm trying to keep my code highly optimized, and as far as I understand the code for the text plugin is not at all necessary if my text dependencies are inlined. I can keep the text plugin out by adding exclude=text to my r.js call, but if I do, I get an error when I try to use the optimized code in the browser saying the text.js plugin couldn't be loaded.

So:

  1. Is there any reason the text.js plugin is actually required here?

  2. If not, is there a configuration option for r.js that can fix this behavior, or

  3. Is there an easy shim for the text.js plugin that I can include to convince Require.js that the unnecessary plugin is loaded?

like image 888
nrabinowitz Avatar asked Apr 17 '12 18:04

nrabinowitz


People also ask

What is Optimizer in JavaScript?

The optimizer is part of the r. js adapter for Node and Nashorn, and it is designed to be run as part of a build or packaging step after you are done with development and are ready to deploy the code for your users.

What is a RequireJS module?

RequireJS is a JavaScript file and module loader. It improves perceived page load times because it allows JavaScript to load in the background. In particular, it enables asynchronous JavaScript loading.

What is Shim RequireJS?

shim: Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value. Here is an example. It requires RequireJS 2.1. 0+, and assumes backbone. js, underscore.

How to RequireJS file?

To include the Require. js file, you need to add the script tag in the html file. Within the script tag, add the data-main attribute to load the module. This can be taken as the main entry point to your application.


1 Answers

The text plugin is really required since RequireJS needs to check if the plugin implements the method normalize before retrieving the proper module ID.

The way to remove the text plugin from the build is to use the onBuildWrite setting to create an empty plugin module as described on this issue comment: https://github.com/jrburke/r.js/issues/116#issuecomment-4185237 - This feature should land on a future version of r.js

Edit:

r.js now have a setting called stubModules that does exactly that:

//Specify modules to stub out in the optimized file. The optimizer will
//use the source version of these modules for dependency tracing and for
//plugin use, but when writing the text into an optimized layer, these
//modules will get the following text instead:
//If the module is used as a plugin:
// define({load: function(id){throw new Error("Dynamic load not allowed: " + id);}});
//If just a plain module:
// define({});
//This is useful particularly for plugins that inline all their resources
//and use the default module resolution behavior (do *not* implement the
//normalize() method). In those cases, an AMD loader just needs to know
//that the module has a definition. These small stubs can be used instead of
//including the full source for a plugin.
stubModules : ['text']

For more r.js options check the example.build.js file.

like image 115
Miller Medeiros Avatar answered Sep 28 '22 03:09

Miller Medeiros