using requirejs optimizer to minify to a single javascript and single css - javascript

I am writing jQuery plugin and using requirejs in order to make my plugin modular and easier to code.
The plugin has also its own css files. Now, I want to combine and minify all the js files and css files. I am using r.js to so it. Here is the build.js configuration file that knows how to concatenate and minify js files into one file:
({
baseUrl: 'js/plugin',
optimize: 'none', // none, uglify or uglify2
wrap: true,
name: '../vendor/almond',
include: 'main',
out: '../dist/jquery.my-plugin.min.js'
})
How can I add an option to minify also css file? I saw the cssIn option, but where do I tells r.js wha is the output name? Do I need to use modules? If so, how?

r.js automatically inlines contents of #import url(...) links in all .css files found in the project directory (thus concatenating multiple files into one master stylesheet).
In your current build configuration, however, with only baseUrl specified, r.js doesn't even know about the CSS folder (which is, presumably, somewhere in ../../style/ relative to js/plugin/).
You'd have to add the appDir and dir properties to your buildconfig file (both explained in detail in the example config file) and set project root (ie. appDir) to directory that contains both JS and CSS folders.
Please note that, as mentioned in the documentation, adding appDir will require changing value of baseUrl to be relative to appDir.

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?

Javascript project structure for dev and production using npm and grunt

I am trying to structure javascript files in a project. I have used NPM to manage the modules and planning to use Grunt to concatenate and compress the js and css files for deployment.
I am currently using the following structure
-[project root]
-- [node modules] :packages such as requirejs, jquery, semantic-ui etc using npm
--[war]
---[Dev]
----[css] multiple css files from modules (Question 2:?)
----[js] multiple js files from modeuls (Question 2:?)
- Gruntfile.js :for concatenate and compress
---[Production] -
----[css]:This is where the compressed and concatenated css files are kept
----[js] :This is where the compressed and concatenated js files are kept
Question 1: Is the above approach to structure the project correct ? Any other recommendations which allows to manage the packages, dev and production files.
Question 2: Can NPM or another tool allows me to pick up the js and css files from the [node modules] folder and place them to (dev>>css or dev>>js) folder ? If am doing this manually how do I track the versions ? Seems like I am missing something here, there must be a better solution.
Suggestions/recommendations/comments are much appreciated.
Thanks
The question is a bit too wide for SO format, but in general your structure is good. Instead of copying files from node_modules, you have your own JavaScript files under js and you import/require them to your own files.
//foo.js
//ES6 style imports
import {Foo as Bar} from "biz";
//Common JS style requires
var Bar = require("biz");
//AMD style requires
require(["biz"], function (Bar) {
If you want to use your node_modules in a browser, you'll want to bundle them using Browserify, Webpack, Rollup or similar. To automate this, you can easily use Grunt tasks such as grunt-browserify together with grunt-watch.
Same applies for your CSS files: You store your own files under css and if you need CSS files from node_modules you can import them to your own files: if you are using some preprocessor (such as SASS or LESS), the preprocessors usually inline your imports when building the .css-file. If you are just using plain .css files, see grunt-css-import for example.

Why does r.js combine and minify JS, then copy all the files to output dir?

I've been working with the RequireJS optimizer to create multiple optimized JS files for my project and have come across a problem that I’ve found mentioned in other posts but have not found a solution for.
When using r.js to optimized a single file, it pulls all the JS dependency into single file and drops it into the file specified by the “out” property in the build file. However, when trying to create two optimized files (i.e. multipage project using the ‘modules’ property), r.js creates two nicely optimized files but then drops ALL folders and files from the appDir into the output directory. That is, it pulls together and minifies all JS dependencies but then copies the individual files into the output directory.
I realize that r.js is not intended to be a deployment tool so is this by design or is there a way to tell r.js to not copy dependent files and directories into the output directory.
Yes, in your r.js build file, set the removeCombined option to true in order to preserve only the modules you specified to the output location.
{
...
//If set to true, any files that were combined into a build bundle will be
//removed from the output folder.
removeCombined: true,
...
}
See the r.js documentation's example build file.

How to use same config file for serving modules with requirejs and using r.js on the server side to concatenate and minify?

I am working on a project that uses requirejs to dynamically load modules from a web browser. Some of the modules are vendor files, e.g. jQuery, which are all installed into a folder /project/root/lib/ via bower. This project's modules are located in a folder /project/root/components/. So I have a requirejs config, components/main.js, that looks something like this:
requirejs.config({
baseUrl: '/components',
paths: {
jquery: '/lib/jquery/jquery',
}
});
This way, when a vendor module is requested, require finds it by using the mappings defined in paths, while all other modules are located relative to components.
I also want to use r.js to perform concatenation and minification and reduce all javascript files to simply app.js for use in production. I was able to successfully perform this task with r.js -o build.js. Here is what build.js looks like:
({
baseUrl:'components',
out: 'js/app.js',
name: 'app',
paths: {
jquery: '../lib/jquery/jquery'
}
})
However, because there are dozens of vendor file paths defined in my require.js config (main.js), I don't want to have to replicate the configuration across two different files. I would rather use a single config file. The problem is that the paths defined in main.js are absolute (/lib/..., /components), because they're URL paths, but the paths in build.js need to be relative (../lib/..., ./components), because they're filesystem paths. Is there a way to reconcile these differences and define the paths only in main.js, which I then I load in using mainConfigFile in build.js? I tried using the require config called map in build.js, but this method required that I defined a new mapping for each module, which is just as bad as re-defining all of the paths. I want a blanket mapping, essentially.
Is there a method to consolidate my config files to avoid duplicate path definitions?
There is nothing that requires using absolute paths in the configuration passed to RequireJS. RequireJS interprets paths that are relative using baseUrl as the starting point so this should work:
requirejs.config({
baseUrl: '/components',
paths: {
jquery: '../lib/jquery/jquery',
}
});
RequireJS will perform the final path computation for jquery by merging /components with ../lib/jquery/jquery, which resolves to /lib/jquery/jquery, which is exactly the same as the absolute path that was there originally.

RequireJS and Mustache (or any other engine): where to put templates

I am using RequireJS and Mustache in a Javascript application. The content of the templates is inside some external files, which are loaded via the text plugin.
The only thing that slightly annoys me is the directory structure this imposes. All my scripts live inside a js directory, like this
index.html
js
libs
require.js
text.js
jquery.js
...
controllers
...
views
...
...
Hence I configure RequireJS with baseUrl = 'js', to simplify module names. But this force me to have templates inside the js directory, otherwise they are not visible to the text plugin.
Is there a way to configure RequireJS so that text files dependencies are looked elsewhere than the scripts directory?
(Of course I could avoid the text plugin and manually define AJAX requests to grab the files, but this is not the point of the question. If possible, I would like to use the existing tools)
You can specify an absolute path. From the docs:
However, if the dependency name has one of the following properties, it is treated as a regular file path, like something that was passed to a tag:
Ends in ".js"
Starts with a "/"
Contains an URL protocol, like "http:" or "https:"
I usually set up my baseUrl to . and script paths starting with js like this:
require.config({
baseUrl: ".",
paths: {
"lodash": "js/ext/lodash/dist/lodash",
"jquery": "js/ext/jquery/jquery",
"domReady": "js/ext/requirejs-domready/domReady",
"text": "js/ext/requirejs-text/text.js"
}
});
Now I can keep templates in ./templates and reference them easily.

Categories

Resources