Author: brandontruong

Tree shaking with webpack settings

Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset. Its such a great tool for web development. One of the great feature it offers is the ability to tree shaking the javascript and CSS bundles with the right plugins.

For js tree shaking. I have used UglifyJsPlugin. Below is how I got the plugin works in my webpack.config.js file.

new webpack.optimize.UglifyJsPlugin({
  compress: { warnings: false }
}),

For css tree shaking. I have used PurifyCSSPlugin. Below is how I got the plugin works in my webpack.config.js file.

new PurifyCSSPlugin({
  // Give paths to parse for rules. These should be absolute!
  paths: ['./ng2app/index.ejs'].concat(glob.sync('./ng2app/components/**/*.html')),
  // Will minify CSS code in addition to purify.
  minimize: true,
}),

In order for PurifyCSSPlugin, make sure the above code goes after ExtractTextPlugin. See below

new ExtractTextPlugin({
  filename: "css/[name].bundle.css",
  disable: false,
  allChunks: true
}),
// Make sure this is after ExtractTextPlugin!
new PurifyCSSPlugin({
  // Give paths to parse for rules. These should be absolute!
  paths: ['./ng2app/index.ejs'].concat(glob.sync('./ng2app/components/**/*.html')),
  // Will minify CSS code in addition to purify.
  minimize: true,
}),

Another nice feature that I love to use in my webpack config is the ability to control how chunks should be sorted before they are included to the html via chunksSortMode option of html-webpack-plugin

new HtmlWebpackPlugin({
  title: 'My Dashboard (Webpack)',
  template: './index.ejs',
  hash: true,
  minify: {
    collapseWhitespace: true
  },
  chunksSortMode: function (a, b) {  //alphabetical order
    if (a.names[0] > b.names[0]) {
      return 1;
    }
    if (a.names[0] < b.names[0]) {
      return -1;
    }
    return 0;
  }
}),

To control the order of the chunks, I name them with the number at the front of that name. For example

entry: {
  '1bootstrap': bootstrapEntryPoints.prod,
  '2core': [
    './ng2app/polyfills.ts',
    './ng2app/vendor.ts'
  ],
  '3app': [
    './ng2app/main.ts'
  ].concat(glob.sync('./ng2app/components/**/*.scss'))
},
output: {
  path: outputPath,
  //publicPath: './',
  filename: 'js/[name].js',
  chunkFilename: 'js/[id].chunk.js'
},

Any feedback, please leave your comments and I’ll get back to you ASAP.

Advertisements

use Enum as an ItemsSource

Imagine we have an Enum type and we want to use that Enum type to be an ItemsSource of ListBox or ComboBox. Bolow is an example of an Enum type called AirFareBookingStatus

   1: public enum AirFareBookingStatus
   2: {
   3:     AlreadyPaid,
   4:     Cancelled,
   5:     Delayed,
   6:     Deleted,
   7:     InProcessing,
   8:     New
   9: }

What we want to achieve is to populate all the statuses from the Enum to a ListBox or ComboBox.

There is already a solution for this from the Silverlight forum. The idea is to go through all the Field and put them into a IEnumerable of KeyValuepair

   1: IEnumerable<KeyValuePair<string, AirFareBookingStatus>> results;

   2: var x = typeof(AirFareBookingStatus).GetFields().Where(info => info.FieldType.Equals(typeof(AirFareBookingStatus)));

   3: results = from field in x

   4:           select new KeyValuePair<string, AirFareBookingStatus>(field.Name, (AirFareBookingStatus) Enum.Parse(typeof(AirFareBookingStatus), field.Name, false));

Then all we have to do is assign the result to ListBox or ComboBox ItemsSource


   1: lstStatus.ItemsSource = results;

   2: cmbStatus.ItemsSource = results;


That would be good enough for it to work.

But we can even make it more generic by creating a helper function as below

   1: public static class Helper

   2: {

   3:     internal static IEnumerable<KeyValuePair<string, T>> GetEnumList<T>()

   4:     {

   5:         var x = typeof(T).GetFields().Where(info => info.FieldType.Equals(typeof(T)));

   6:         return from field in x

   7:                select new KeyValuePair<string, T>(field.Name, (T) Enum.Parse(typeof(T), field.Name, false));

   8:     }

   9: }

Then, we can call that function for every Enum type we have. For example

   1: lstStatus.ItemsSource = Helper.GetEnumList<AirFareBookingStatus>();

   2: cmbColors.ItemsSource = Helper.GetEnumList<ColorEnum>();

There is still one problem left we have. The item still displays the whole object, so make it display correctly, we need to create DataTemplate resource

   1: <DataTemplate x:Key="KeyValuePairDataTemplate">

   2:     <TextBlock Text="{Binding Key}" />

   3: </DataTemplate>

Then apply that DataTemplate to the ItemTemplate of ListBox or ComboBox as below

   1: <ListBox x:Name="lstStatus"

   2:     ItemTemplate="{StaticResource KeyValuePairDataTemplate}" />

   3:

   4: <ComboBox x:Name="cmbColors"

   5:     ItemTemplate="{StaticResource KeyValuePairDataTemplate}" />

That’s it. Hope that helps.

Continue …

Now, I have run into another problem. Doing that way above is all good, except the name won’t be as flexible. So, I am going to Description attribute to display data instead of the normal name of the Enum. To do that, I’ve changed a bit of my Enum like below

   1: public enum AirFareBookingStatus

   2: {

   3:     [Description("Already Paid")]

   4:     AlreadyPaid,

   5:     [Description("i am cancelled")]

   6:     Cancelled,

   7:     [Description("I got delayed")]

   8:     Delayed,

   9:     [Description("oh man i am about to be deleted")]

  10:     Deleted,

  11:     [Description("who is processing me")]

  12:     InProcessing,

  13:     [Description("I am brand new babe")]

  14:     New

  15: }


Next, I changed a bit in my helper function as well. It’ll get the Description attribute and make it to be Key

   1: internal static IEnumerable<KeyValuePair<string, T>> GetEnumList<T>()

   2:        {

   3:            var x = typeof(T).GetFields().Where(info => info.FieldType.Equals(typeof(T)));

   4:            return from field in x

   5:                   select new KeyValuePair<string, T>(GetEnumDescription(field), (T)Enum.Parse(typeof(T), field.Name, false));

   6:        }

   7:

   8: private static string GetEnumDescription(FieldInfo field)

   9:        {

  10:            DescriptionAttribute[] attributes = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), false);

  11:            if (attributes.Length > 0)

  12:            {

  13:                return attributes[0].Description;

  14:            }

  15:            else

  16:            {

  17:                return field.Name;

  18:            }

  19:        }

Finally, we will have something like this

Enum

That’s it. Let me know if you have any comments.

jQuery UI DatePicker: Disable Specified Days

jQuery UI DatePicker: Disable Specified Days

Written by David Walsh on Tuesday, January 26, 2010

jQuery Calendar Picker

One project I’m currently working on requires jQuery. The project also features a datepicker for requesting a visit to their location. jQuery UI’s DatePicker plugin was the natural choice and it does a really nice job. One challenge I encountered was the need to prevent specific days from being picked. Here’s the jQuery javascript I used to accomplish that.

The jQuery Javascript

/* create an array of days which need to be disabled */  var disabledDays = ["2-21-2010","2-24-2010","2-27-2010","2-28-2010","3-3-2010","3-17-2010","4-2-2010","4-3-2010","4-4-2010","4-5-2010"];    /* utility functions */  function nationalDays(date) {  	var m = date.getMonth(), d = date.getDate(), y = date.getFullYear();  	//console.log('Checking (raw): ' + m + '-' + d + '-' + y);  	for (i = 0; i < disabledDays.length; i++) {  		if(ArrayContains(disabledDays,(m+1) + '-' + d + '-' + y) || new Date() > date) {  			//console.log('bad:  ' + (m+1) + '-' + d + '-' + y + ' / ' + disabledDays[i]);  			return [false];  		}  	}  	//console.log('good:  ' + (m+1) + '-' + d + '-' + y);  	return [true];  }  function noWeekendsOrHolidays(date) {  	var noWeekend = jQuery.datepicker.noWeekends(date);  	return noWeekend[0] ? nationalDays(date) : noWeekend;  }    /* taken from mootools */  function ArrayIndexOf(array,item,from){  	var len = array.length;  	for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){  		if (array[i] === item) return i;  	}  	return -1;  }  /* taken from mootools */  function ArrayContains(array,item,from){  	return ArrayIndexOf(array,item,from) != -1;  }    /* create datepicker */  jQuery(document).ready(function() {  	jQuery('#date').datepicker({  		minDate: new Date(2010, 0, 1),  		maxDate: new Date(2010, 5, 31),  		dateFormat: 'DD, MM, d, yy',  		constrainInput: true,  		beforeShowDay: noWeekendsOrHolidays  	});  });  
Click here to copy this code to the clipboardClick here to add this snippet to CodaClick here to add this snippet to TextMateGet the raw code

1/* create an array of days which need to be disabled */
2var disabledDays = [“2-21-2010”,“2-24-2010”,“2-27-2010”,“2-28-2010”,“3-3-2010”,“3-17-2010”,“4-2-2010”,“4-3-2010”,“4-4-2010”,“4-5-2010”];
3
4/* utility functions */
5function nationalDays(date) {
6 var m = date.getMonth(), d = date.getDate(), y = date.getFullYear();
7 //console.log(‘Checking (raw): ‘ + m + ‘-‘ + d + ‘-‘ + y);
8 for (i = 0; i < disabledDays.length; i++) {
9 if(ArrayContains(disabledDays,(m+1) + ‘-‘ + d + ‘-‘ + y) || new Date() > date) {
10 //console.log(‘bad: ‘ + (m+1) + ‘-‘ + d + ‘-‘ + y + ‘ / ‘ + disabledDays[i]);
11 return [false];
12 }
13 }
14 //console.log(‘good: ‘ + (m+1) + ‘-‘ + d + ‘-‘ + y);
15 return [true];
16}
17function noWeekendsOrHolidays(date) {
18 var noWeekend = jQuery.datepicker.noWeekends(date);
19 return noWeekend[0] ? nationalDays(date) : noWeekend;
20}
21
22/* taken from mootools */
23function ArrayIndexOf(array,item,from){
24 var len = array.length;
25 for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){
26 if (array[i] === item) return i;
27 }
28 return 1;
29}
30/* taken from mootools */
31function ArrayContains(array,item,from){
32 return ArrayIndexOf(array,item,from) != 1;
33}
34
35/* create datepicker */
36jQuery(document).ready(function() {
37 jQuery(‘#date’).datepicker({
38 minDate: new Date(2010, 0, 1),
39 maxDate: new Date(2010, 5, 31),
40 dateFormat: ‘DD, MM, d, yy’,
41 constrainInput: true,
42 beforeShowDay: noWeekendsOrHolidays
43 });
44});

The base code is taken from this forum post. You’ll note that I created an array of dates in string format which also accommodates for comparing year.

I’d like to see jQuery UI implement a standard way of disabling days. Their DatePicker is very nice though so I can’t complain too much!

–>

Premium WordPress Themes

Follow via RSS Epic Discussion

Commenter Avatar January 26 / #
Mark says:

I have to admit, I wish Mootools came with such a wide variaty of UI plugins…

All and all, I think you accomplished your goal very well! Good stuff.

Reply

Commenter Avatar January 26 / #
Salih Gedik says:

Nice. But I rarely need jQ. Mootools FTW isn’t it?

Reply

Commenter Avatar January 26 / #
Simeon says:

Nice post! Can be easily expanded by populating he “disabledDays” using PHP to find all weekends, holidays, etc. I wonder what the performance impact is though if you span across several years as a typical selection might allow?

Reply

Commenter Avatar January 26 / #
Savageman says:

@mark: you should try this Mootools DatePicker (also works for time): http://www.monkeyphysics.com/mootools/script/2/datepicker

Doesn’t have a beforeShowDay option though…

Reply

Commenter Avatar January 26 / #

I would remove all the MooTools helpers 🙂 and just use the jQuery native $.inArray function:

Change this line: ArrayContains(disabledDays,(m+1) + ‘-’ + d + ‘-’ + y) to this instead: $.inArray(disabledDays,(m+1) + ‘-’ + d + ‘-’ + y) != -1

Then you don’t need to two other functions from MooTools.

Reply

Commenter Avatar January 26 / #

@Douglas Neiner: Sorry, flip the arguments. $.inArray( value, array )

Reply

David Walsh January 26 / #

@Douglas Neiner: I’m a complete MooTools nerd — I didn’t even think to check the jQuery API. Will update.

Reply

Commenter Avatar January 26 / #

Interesting dilema and solution. My problem with the jQuery Datepicker is figuring out how to store selected start and end dates in a cookie.

Reply

Commenter Avatar January 26 / #
Brad Zickafoose says:

Is it possible to have the DatePicker block out today’s date as well as past dates from being selected, only allowing tomorrow and future dates available for selection?

Reply

Be Heard!

I want to hear what you have to say! Share your comments and questions below.