Creating Modules in Flash CS4

You can now create modules in Flash CS4 using AS3.  You couldn’t in CS3, but could in Flash 8 using AS2.  Flash CS4 comes with a new feature in the Publish Settings called “External Library Path”.  What this allows you to do is point to a set of code, and allow you to compile WITHOUT it.  This is almost exactly the same as mxmlc’s (Flex compiler) -load-externs compiler parameter.  We still don’t have -link-report, though, grr….

Introduction

Modules refer to SWF’s that contain only the code that they need to contain, and nothing more.  This allows large, multi-SWF Flash sites/applications to have a low overall file size, and to scale performance wise.  If you have 30 SWF’s, and they all use the same 14k Button component, you don’t want to add 14k to each SWF.  Instead, you want to only add it once and have all the other SWF’s share it.  You can see how this scales nicely with not only saving massive amounts of file size, but also only loading those classes that you need at the right time.  Here is more info on modules with regards to Flash (as opposed to Flex which embraces this concept):

Basics of Compiling Classes

When you use the “MovieClip” class, you can’t just type MovieClip, you have to import it via:

import flash.display.MovieClip;

This allows the Flash compiler to know what MovieClip you are talking about.  MovieClip is an internal class, meaning it’s built-in into the Flash.  Code that you write in class files (or even on the timeline) is called an external class.  Both require a package path and import of some sort.  This allows strong-typing to work.  For example, if you type in:

var my_mc:MovieClip = new MovieClip();
addChild(my_mc);
my_mc.stoop();

And attempt to compile, it’ll fail. This is because the compiler knows what methods MovieClip exposes, and can do spell checking for you.  In this case, it would complain that there is no “stoop” method on MovieClip.  Seeing this, I’d know to change it to stop.  This is great!  In the past, I’d spend hours hunting down stupid misspellings like this.  ActionScript 1 didn’t do this, so a lot of bugs were from mispellings.  Additionally, Flash needs to know what the class is so it can put it in the SWF.

When you use a Button:

import fl.controls.Button;
var buton:Button = new Button();
addChild(button);
button.label = “Hello”;

That Button class is compiled into the SWF.  This is great, expected, and cool.

How?

But what if you want to create a mult-SWF site, such as using Gaia?  That, or you just have a very large Flash application, perhaps written for AIR, and don’t want the user to have to download & initialize the whole thing for sections they may never even go to?

In AS2, you could use exclude.xml.  This allowed you to compile SWF’s with strong-typing, yet the actual class itself wouldn’t be compiled into the SWF.  Naturally, the SWF didn’t work if you double-clicked it.  BUT, if you loaded it into another SWF via loadMovie (old skool Loader), it would work if the parent SWF had the class it needed.  You could share classes this way across SWF’s.

In Flash CS4, you can now do the same thing by creating a SWC file (a SWF inside a ZIP file).  You can also use a folder full of classes, but SWC’s are just easier.  You then add that SWC to the External library path in the Publish Settings for the FLA.  This SWC’s sole purpose is to contain all the classes you DON’T want to put into the SWF.

So, if you’re creating a multi-SWF site that utilizes Flash CS3 components, you’d:

  1. Create a “components.fla” that has all the components you need in the library.  You’d put those components in a MovieClip on frame 1, and export that MovieClip as “Components.swc”.
  2. Compile your FLA as “components.swf”.
  3. Any FLA that uses those components (excluding Components.fla) would put Components.swc in their External library path.  Additionally, delete the componentShim SWC in the Library for AS3 components.
  4. Your main SWF first loads components.swf in the same ApplicationDomain, wait’s for Event.INIT, and then proceeds to load any other child SWF it wants.

That’s it!

Remember, there is no longer “_global” in AS3; you’re classes are now stored in seperate ApplicationDomains.  Think of them as like separate _global’s that you can share or create.  So you’re Loader call which would normally be:

components.load(new URLRequest(“components.swf”));

Now becomes:

components.load(new URLRequest(“components.swf”), new LoaderContext(false, ApplicationDomain.currentDomain));

You can then load everything else as normal; it’s just that 1 line of code that’s important in getting  your component classes into the correct place to be shared (ie ApplicationDomain.currentDomain, aka “t3h default _global”).

Conclusions

If you were to use every Flash CS3 component, you’re SWF would be at least 80k.  If you had to use those components in other SWF’s, even just 5, suddenly you 400k extra the user has to download.  This doesn’t include skins and all your code.  Using modules, you can cut down each SWF 80k.

This isn’t restricted to just the Flash AS3 components.  This can include any class that you write as well.  When creating large Flash sites, there are bound to be many common controls and graphics that each SWF will share.  In the past, you’d use loadMovie, and load 1 SWF dynamically, and share it amongst others.  Now, with modules, you can write strongly-typed code and not have to worry about sharing; you can just let the External library path optimize it for you.

It helps to do a little planning to see if any classes are shared amongst multiple SWF’s.  Since Flash can’t do what mxmlc can do, and generate a list of classes used in a SWF, you have to manually guess/remember what those are based on your code.  Additionally, even graphics & Fonts are considered classes to, so those count as candidates for being excluded.

Hopefully this’ll reduce your Flash site’s download time, or speed up your AIR app.

6 Replies to “Creating Modules in Flash CS4”

  1. This is great info. I knew how to avoid duplicating classes in pure AS3 mxmlc environment but wasn’t aware you could do the same with the IDE, and this was making me very dubious about using Gaia. Also very much enjoyed your posts on Agile, thx.

  2. Thanks! Gaia got around it by using the Bridge Pattern. His interface classes add an additional 800 bytes (not kilobytes) to each SWF… so Gaia wouldn’t really benefit from the amount of work that’s involved. However, the second you start sharing assets or components… heck yes!

  3. . . No matter how I try (“Advanced ActionScript 3.0 Settings” from the “Publish Settings” dialog or “Path” in “Project Properties” from the “Project” panel), my SWC is not used when compiling the other files. I’m generating it automatically when exporting the main SWF of my app (ticking the “export swc” box on the “Publish Settings” dialog, “flash” tab) but when I add it as a external library on the other movies, the classes are still being recompiled in the other files.
    . . What am I doing wrong here?

  4. Jesse,

    Thanks for this, it was driving me crazy having to go through domains and not sharing, so the tip for the LoaderContext was just what I needed.

    I’m using that in the SWCFile class in the desuade.utils package for the new Partigen 2. It let’s you load a .swc file and get it’s classes easily. When you are interested, here’s the source on github:

    http://github.com/andrewfitz/desuade/blob/master/com/desuade/utils/SWCFile.as

    Cheers, and thanks again!
    -Andrew

  5. Diego,

    After much wrestling and googling, I was able to get around the same problem you were having. The trick is that the classes in the SWC can no longer be in the classpaths of the SWFs that are trying to use the SWC as an external library; else they get included in the build.

    It’s a bit annoying if all your files are in the same project, but what I’ve done is moved SWC only classes out of my /src folder into /src/_forSWCs/mainOnly and /src/_forSWCs/componentsOnly. Then main.fla and components.fla need to include those specific paths in their classpaths for SWC builds. For the rest of the project FLAs, they include the SWCs as external libraries and still use /src as their class path. I was able to shave 500kb out of my project SWFs with this technique.

    HTH! And thanks to Jesse for the always helpful posts~

Comments are closed.