I have my JavaScript organized as described here: https://stackoverflow.com/a/10816983/83897.
I have a JavaScript-heavy ASP.NET application that has multiple different pages (vs. being a single-page application). Each page has different dependencies, so I have a per-page .js file (page1.js, page2.js, etc.). Each has a require() call, declaring its dependencies:
require(['jquery', 'page1Module'], function($, module){
// page1 specific stuff here
});
This works fine. What I'm wondering is, how might the RequireJS build process work? I think I want a per-page "build" .js file (e.g. page1-build.js, page2-build.js, etc.)? Is there existing software I can leverage?
The process might look like this:
Compile all dependencies for a given script into one build.js file in a temporary directory.
Calculate an MD5 fingerprint for the compiled file.
Compare that fingerprint with the comparable file in public/assets.
Create an in-memory RequireJS manifest, mapping each module to the compiled file. Append this manifest to the compiled file.
Somehow make production use the build file.
EDIT: After some thought, I'm thinking the RequireJS optimization using node + r.js will just be part of a larger asset building process, where the asset building relies on some other, third-party library. The RequireJS optimization will simply be used for certain JavaScript dependencies (i.e. the JavaScript files for each page, including found dependencies), perhaps specified in some XML config.
You can create multiple optimized files by specifing the modules in the build profile:
{
modules: [
{
name: "main"
},
{
name: "page1",
include: ["dep1", "shim2"],
exclude: ["main"]
}]
}
Each entry will generate a optmized .js file.
More info here: How to use RequireJS build profile + r.js in a multi-page project
Related
I have a SS3.x module that I have forked, pulled down from it's fork via composer, and started porting to SS4. So far so good, except when it comes to Requirements.
I'm using the Requirements format found in existing code in another module, which has a colon-separated format as follows:
Requirements::javascript('company/mymodule:javascript/SortableUploadField.js');
This file exists in the module at /vendor/company/mymodule/javascript/SortableUploadField.js. However on page load, I have a 404 in console as SS is looking for this file at /resources/company/mymodule/css/SortableUploadField.css. And this does not exist.
I added the following to my composer.json file for the module as I saw other modules doing this:
"extra": {
"installer-name": "sortableuploadfield",
"expose": [
"css",
"javascript"
]
},
And ran a composer update. But the /resources directory does not appear for this module (other modules are there). And I can't find any information online on how this is supposed to work.
Edit: As a sidenote, I wonder if the documentation for Requirements is misleading? It omits this caveat with modules and mention of the resources directory at all. If that documentation is meant only to convey the process for working with JS/CSS in normal mysite development, then it is just a bit confusing because the code samples us everywhere. Which wouldn't be a direct url to something in /vendor, surely.
Found this after tracing code that basically used the /resources directory. Short answer to my query is simply running
composer vendor-expose
This calls the VendorExposeTask that does this copying. The only other place I found this task being used is on VendorPlugin install method. So I assume that other than the above command, the only way SS actually does this on your behalf is on initial install of a module.
I am quite new with GruntJS and I wonder if it is possible to have a task that loads some RequireJs modules to process them and write the result within a JS file.
I describe my scenario:
I have a RequireJs based project with many files.
I would like to concatenate/minify/etc the project to deploy it and increase performances, etc.
The optimization works perfectly with the grunt-contrib-requirejs plugin.
The grunt-contrib-requirejs plugin works with a main.js file and I should need to generate it dynamically.
I would like to generate the main.js processing some RequireJS module of the project (call them fileA.js and fileB.js).
I would like to use the generated main.js to run the grunt-contrib-requirejs plugin.
So the task sequence would be something like:
Custom Task:
loads fileA.js and fileB.js
merge them together
write the result of the merging within a new JS file
grunt-contrib-requirejs task:
use the generated main.js file to optimize the project
Do you know how can I achieve this?
I don't have any kind of restrictions on the way/tools/libs to use.
You can load RequireJS in Grunt, as follows:
var requirejs = require('requirejs');
You can then fetch all the fileX.js files in your tree through Grunt:
grunt.file.recurse('js/modules/', function callback(abspath, rootdir, subdir, filename) {
if (filename === 'fileX.js') {
/* Do something here. */
}
}
Once you have all the modules you need you can use r.js to minify/concatenate them.
I'm trying to leverage GruntJS to create a build process that is uniform across multiple teams and projects at my company. The idea hear is that we have a config file for each application that only specifies the files that need to be processed and what bundles they need to be concatenated into at the end. The build process would be the same for all apps: pick up the config for the app, process files in each bundle using a uniform build process.
For Example:
asset.json config file specifies two bundles, "main" with 1.js + 2.js and "secondary" with 2.js and 3.js
Build process says for each bundle, preprocess, minify, then concatenate into a js file based on the bundle
Get output of "main.js" and "secondary.js"
The problem I'm running into is that Grunt takes a "static" configuration and executes it. I've already abstracted out the building of the configuration so that I can add chunks dynamically, but right now I don't see a better way forward than literally looping over each bundle and building out a unique task for each section of the build process for each bundle, building up queues of tasks to execute, and then running each task in the queues during the build process. Its definitely possible, but its a lot of manual work and seems prone to breaking. Is there way to just execute each task in order as I loop over the bundles? Any better way to achieve the same net result of config + source in, N bundles out?
I want to be clear that I am fully aware that Grunt CAN build multiple files. What I'm trying to do is separate the specification of how many bundles from the build steps themselves. Grunt core has to bake these two things together which means each project would have to go in and alter their build steps rather than an external configuration. As per the example above, I should be able to swap out the asset.json file specified in step 1 for any config file that has 1, 2, 3, ... N bundles with N files in each one (and potentially specifying a "type" like scripts or styles).
Edit 10/12/13: The Nitty Gritty posted an article yesterday that might be another approach to tackling your issue.
This can be done by passing the module name you want to build as a command line argument and loading in the whole assets file in your grunt config. Please note this is example code, I have not tested this, so it's possible you need to set paths etc. correct for your case.
Start with updating the assets.json file to a plain JavaScript file, and reform it like so:
module.exports = {
main: ["1.js", "2.js"],
secondary: ["2.js","3.js"]
}
Next, you can pass a command line argument to Grunt, which should specify one of the module names in assets.js. Example:
grunt --bundle=main
Now, you'll need to load in the assets.js file in the Gruntfile:
var assets = require('./assets'); // assuming assets.js is on the same level as your Gruntfile
And then you can get the argument name by using:
var bundle = grunt.option("bundle");
Now you can use bundle as your output file name and assets.bundle to get the array files for that bundle.
I am new to gruntJS. Looking at the tutorials/presentations, I believe it is awesome.
Currently, we are using batch scripts in our web + embedded project, which performs the following tasks:
Merges all the JS file into one.
Merges all the CSS file into one.
Kills existing .EXE on which our project runs. It's basically a simulator's EXE which loads and runs our website. Our website is packaged in the form of ZIP file.
Deletes existing ZIP file.
Creates a new ZIP file which will contain some folders like "html", "lsp" (Lua Server Pages), images, JS(which will contain only one merged file), CSS(which will contain only one CSS file).
Start the .EXE. Basically the EXE once loaded which pick up the zip file from a specified directory.
I understand, merging process can be achieved via gruntJS, but I am not sure about starting/killing the EXE. It would be great if somebody gives me pointers how to get started. Once being certain about the process, I can convince my boss.
Thanks for reading.
Having a grunt-like script that launch your server isn't good practice. In an ideal world, you would separate the build and package phase from the launch of the server.
But anyway, there are either grunt plugins to do that, or the vanilla child_process of node, assuming you use node to run grunt.
Using grunt-exec it would look like this:
exec: {
start_server: {
command: 'program.exe'
}
}
Using the vanilla approach:
var spawn = require('child_process').spawn;
prog = spawn('program.exe');
prog.on('close', function (returnCode) {
console.log('program.exe terminated with code', returnCode);
});
I am a newbie to jasmine, please correct me if I am asking a wrong question.
I am working on a legacy system which has a lot java script code. I would like to write some tests for the same. Initially I thought of using buster since it's in beta I didn't explored much about it. Meantime while searching I came across jasmine. Writing tests in jasmine was simple, maven plugin makes jasmine to be integrated with CI also we can get coverage report. So I felt to use jasmine.
In our current legacy systems there are several js, which need's a lot of refactoring . But to start off writing some test.I need some help. Let me narrate the problem I am facing
We have a lot of scripts having conflicting function names, and global variable's and so on. So specifying the jsSource in pom or jstestconf file is cumbersome, as I need to exclude few files, sometimes scripts which needs tests might have a conflicting function name. Also some scripts may be dependent on other's and so on.
Is there a way in jasmine the below mentioned scenario could be achieved.
Test1.js
Include specific library, excluding common once
Include the java script(Source1.js) source which needs to tested
Then write the tests
Test2.js
Include specific library, excluding common once
Include the javascript source(Source2.js) which needs to be tested
to tested
Then write the tests
Something similar to junit's where we say include class which needs to be tested.
Doing some initial search I got to know by using requirejs I can achieve this. But I couldn't find any concrete example's.
I would need your opinion before proceeding further.
Also is there any other testing framework which I use which have good integration with maven & eclipse and better modularity of tests.
I've been using Karma to run jasmine tests, and you can specify the files Karma includes via the karma.conf.js files property. So you could set up 2 different configurations for Test1.js and Test2.js. For example (assuming you have node_modules and your other files are under my-application-root:
for config 1:
module.exports = function(config){
config.set({
basePath : './',
//files to load in the browser
files : [
'my-application-root/specific-library-1.js',
'my-application-root/Source1.js',
'my-application-root/test/Test1.js',
'my-application-root/node_modules/**/*.js'
],
exclude : [
'my-application-root/common-lib.js',
'my-application-root/specific-library-2.js',
],
.......
and for config 2:
module.exports = function(config){
config.set({
basePath : './',
//files to load in the browser
files : [
'my-application-root/specific-library-2.js',
'my-application-root/Source2.js',
'my-application-root/test/Test2.js',
'my-application-root/node_modules/**/*.js'
],
exclude : [
'my-application-root/common-lib.js',
'my-application-root/specific-library-1.js',
],
.......