顯示具有 requirejs 標籤的文章。 顯示所有文章
顯示具有 requirejs 標籤的文章。 顯示所有文章

2020年2月13日 星期四

[JS] RequireJS - Prevent JS File Caching

Problems
Very often when we updated the JS files, directly refreshing is not reflecting the changes, instead we need to manually clear cache, which makes end users using the web application quite annoying.


Solutions
RequireJS provides "cache busting" which can force browser to download the latest version of JS files every time new pages loaded

Basically, we write a general function accepting target path not to cache, the "require.config" will then execute the function, the bust function actually use current time and attach as the parameter of the JS URL, since time is always changing, it can force the browser to retrieve the JS files for every load


function bust(path) {
    return path + '?bust=' + (new Date()).getTime();
}

require.config({
    baseUrl: '/base/path',
    paths: {
        'fileAlias': bust('fileLikelyToChange'),
        'anotherFileAlias': bust('anotherFileLikelyToChange'),
        'jQuery': 'jQuery'
    },
});



References
- https://stackoverflow.com/questions/16523755/cache-busting-specific-modules-with-requirejs

2015年1月16日 星期五

[requireJS] define VS require

Difference between define and require

We often see define and require in requireJS, but what's their difference? I try to elaborate as below.

require
  1. When you want to load some stuff, you need to use require, like jquery, bootstrap etc.
  2. It has NO return statement
e.g.:
require(["jquery", "bootstrap", "bootstrap_select"], function() {
 //requirejs sugar function
 var angular = require('angular');
});


define
  1. As the name implies, it helps you define module that will be depend by other modules or applications
  2. It has return statement for inclusion by other modules
e.g.:
define(["angular", "angular-route", "angular-animate"],function(angular){
 var insiderApp = angular.module("insiderApp",["ngRoute", "ngAnimate"]);
 //routing
 insiderApp.config(['$routeProvider','$locationProvider',function($scope,$routeProvider,$locationProvider){
  
 }]);
 
 return insiderApp;
});

This is official explanation
 /**
     * The function that handles definitions of modules. Differs from
     * require() in that a string for the module should be the first argument,
     * and the function to execute after dependencies are loaded should
     * return a value to define the module corresponding to the first argument's
     * name.
     */

2015年1月15日 星期四

[requireJS] Case Study: Working With AngularJS

Struggling for 2 days, I finally make myself clear with the combination of angularJS and requireJS. I will note down with examples.


Target
  • To load controllers, directives of AngularJS through requireJS.

  • Enjoy the benefits of requireJS on AngularJS

Files Included
  • main.js
    • Centralize all the js loading by one single main js file.

    • Specifying the dependencies of each module when loaded. E.g.: Bootstrap depends on jQuery

  • insiderApp.js
    • To define the Angular main insiderApp module

  • controller.js
    • To define the Angular controller module

  • step0.html
    • The Angular view

Coding

main.js
require.config({
 paths: {
  'jquery' : 'lib/jquery.min',
  'bootstrap' : 'lib/bootstrap.min',
  'bootstrap_select' : 'lib/bootstrap-select',
  'stepOne' : 'core/stepOne',
  'angular' : 'lib/angular',
  'angular-animate' : 'lib/angular-animate',
  'angular-route' : 'lib/angular-route',
  'controller' : 'controllers/controller'
 },
 
 //we do not add AMD-compliant script here!!
 shim: {
  "bootstrap" : { "deps" : ['jquery'] },
  'bootstrap_select' : { "deps" : ['jquery', 'bootstrap'] },
  'stepOne' :  { "deps" : ['jquery','bootstrap_select'] },
  'angular' : {
   exports : 'angular'
  },
  'angular-animate' : {
   "deps" : ['angular'],
   exports : 'angular-animate'
  },
  'angular-route' : { 
   "deps" : ['angular'],
   exports : 'angular-route'
  },
 },
 //for debug
 urlArgs: "bust=" + (new Date()).getTime() 
});


require(["jquery", "bootstrap", "bootstrap_select", "stepOne", "insiderApp", "angular", "controller"], function() {
 //requirejs sugar function >> Avoid putting all modules to the parameters
 var angular = require('angular')

 var csArr = ["/css/bootstrap-select.min.css", "/css/bootstrap.min.css", "/css/psliteM.css"];
 
 //manually start over insiderApp for angularJS, no need to put ng-app in html file
 angular.bootstrap(document,["insiderApp"]);
});
insiderApp.js
define(["angular", "angular-route", "angular-animate"],function(angular){
 var insiderApp = angular.module("insiderApp",["ngRoute", "ngAnimate"]);
 //routing
 insiderApp.config(['$routeProvider','$locationProvider',function($scope,$routeProvider,$locationProvider){
  
 }]);
 
 return insiderApp;
});

controller.js
//controller
define(['insiderApp'],function(insiderApp){
 insiderApp.controller('insiderControl', ['$scope', function($scope){
  //store all the required images path here
  $scope.menuImages = [
                     {
                      lm : './images/info.png',
                      width : '200px', 
                     },
                     {
                      mid : './images/setting.png',
                      width : '200px',
                     },
                     {
                      rm : './images/tv.png',
                      width : '200px',
                     },
                    ];
 }]);
});
step0.html







Smart Moment (Menu)


 
 
 




Points to Note
  • main.js
    • Some tutorials will use require.config and we may also have requirejs.config, they are basically the same

    • Requirejs object is used to setup 
      • Dependencies of different modules
        • Remember only non-AMD script is allowed to put in the deps parameters for dependency loading.

      • Module exports as global variables for use of other modules

      • Define the exact path of the js files

    • require(["jquery", "bootstrap", "bootstrap_select", "stepOne", "insiderApp", "angular", "controller"]....
      • jquery, bootstrap etc. is the self-defined name of js scripts to load, they are loaded in order

      • We must load the controller module for the AngularJS controller to work properly

    • Inside require function we have a second require function,which is called sugar function, it only loads the required modules for use inside the function, if you don't need it, you are NOT required to include in function parameters.

    • angular.bootstrap is to manually trigger the start of angularJS, which is highly recommended to use when cooperate with requireJS
      • When this was set, NO exists in the html view or AngularJS will throw errors

  • insiderApp.js
    • define(["angular", "angular-route", "angular-animate"],function(angular){
      • Normally, we will ignore the first parameter of the define function and let requireJS to use the file name as the module name (recommended)

      • Second array parameter tells requireJS that insiderApp module requires angular, angular-route and angular-animate to be loaded before executing the insiderApp module

      • function parameter "angular" is returned by the angular function, this object is for the implementation of insiderApp

      • Return the insiderApp variable or not depends on whether or not other modules need insiderApp, normally you need to return it.

      • var insiderApp = angular.module("insiderApp",["ngRoute", "ngAnimate"]);
        Just like usual, start the angular module, we can do any configuration of the angular object in this file.

  • controller.js
    • Just like usual, controller of the Angular object

    • define(['insiderApp'],function(insiderApp)...
      • Controller rely on insiderApp for adding controller to the Angular module, so we need to put insiderApp to the array and use it inside the function

    • insiderApp.controller('insiderControl', ['$scope', function($scope){...
      • Do all the work of Angular controller as usual

  • step0.html
    • Main view

    • NO here as we have already bootstrapped it manually in main.js

Others
  •   How to determine whether a module is AMD-compatibile module
    • Check the source code to see whether it has keyword like "define", "require"

References
  1. http://segmentfault.com/blog/moejser/1190000000492238 
  2. http://camnpr.com/archives/1563.html
  3. http://tech.pro/blog/1561/five-helpful-tips-when-using-requirejs
  4. http://stackoverflow.com/questions/17366073/requirejs-define-vs-require
  5. http://kielczewski.eu/2013/04/integrating-angularjs-with-requirejs/
  6. http://stackoverflow.com/questions/14619239/require-js-shim-not-working-for-this-code