Publishing Custom Elements, naming conventions, best practices? - web-component

I am about to make my Custom Element <card-t> public
pre-release is at: https://github.com/card-ts/playingcardts
Suggestions and enhancements much appreciated!
Couple of questions:
Naming Custom Elements
There is: https://www.webcomponents.org/community/articles/how-should-i-name-my-element
but it doesn't get past "must include a hyphen"
I went with element.card-t.js for sorting purposes.
Other best practices ??
Wrapping in IIFE & ES Modules?
The Custom Elements gets created in the Global Namespace, and doesn't return anything like a library does.
Wrapping in an IIFE should be enough?
Is there value in loading it as module?
<script type="module" src="element.card-t.js">
Extending Custom Elements
Should we by default return the class definition so extending is easier?

Since this is an opinion question these are my opinions:
Naming Custom Elements
I always name my JS file based on my class name and my class name is just the tag name but capitalized. So my tag <my-thing> would have a class name of MyThing and my filename would be components/MyThing.js
Wrapping in IIFE & ES Modules?
I create all of my code in ES6+ and then I create an additional ES5 CommonJS version and an ES5 IIFE version and let people load what they want.
I use rollup and my component-build-tools to create my various versions. component-build-tools component-build-tools also combines all dependencies of a component into the output file. This can lead to some replication, but most of the time that is small enough I don't mind.
My components end up with their templates and locale strings embedded into the published files. This is a feature of component-build-tools.
Extending Custom Elements
As a general rule I expose the class name in all three formats of my files. This does help with extending my components, yet I doubt that many people will ever want to do that.
Where to place the files.
The hardest thing is where to place the files so they are easily accessed by the web page.
I have a build step that copies my files from the node_modules folder into a dist folder. This was the easiest thing for me to know exactly where my files are located.
Doing this allows me to npm install anything and then still get their files into a location I know and can use. But it also has lead to me not worrying greatly about where my files end up in my repo.
I do tend to have a dist folder and in there I have:
dist
+- js
+- components
+- MyThing.js
+- MyThing.min.js
+- AnotherThing.js
+- AnotherThing.min.js
+- SoOn.js
+- SoOn.min.js

Related

Symfony 2.7 retrieve root directory ANYWHERE

I just want to ask if there's a way to retrieve the root directory of a Symfony Application ANYHWERE?
What I mean by anywhere is, in any file of my App.
I've searched everywhere and all I get is this:
$this->get('kernel')->getRootDir();
Which of course works! But I can't use it in my custom classes. I need to get the root directory in one of my custom classes.
I've already read answers about DependencyInjection/Service and other stuff, but I think it's too complex/overkill to implement those just to solve my current problem.
I just want the root directory of my app, period. Is there any other way?
The simplest way I can think of is to define a constant in your app.php file, like this:
define("ROOTDIR", $kernel->getRootDir());
so you can then use this constant anywhere. Compared to this, a static method is overkill, too.
I reviewed my answer. Indeed, it will not fit your need. Anyway, if you don't want to use dependency injection to achieve this goal because you have static methods, where do you call these static methods? In a controller? In a command? In another service? If you don't want to instanciate your class because you don't want objects with their own data, you have 2 options:
Get the root directory outside your class, and use it as a parameter for your static methods.
If your class uses static methods that means your class behave as a helper class, it is just a tool (converter, exporter, renderer...etc). So I assume that you placed all your helper classes in one directory. In this case you can create a enum class which defines constant like root dir, web dir giving the absolute paths.

Can name from build.sbt depend on Activator name in activator.properties (or vice versa)?

Just noticed that there are two name settings in any Typesafe Activator template - one in build.sbt and another in activator.properties.
Is there a way to make one depend on (use the value of) the other? Although the build's name can be defaulted to the name of the main project folder, I'm not sure about the activator's.
You could make build.sbt write out or modify activator.properties, using whatever scala code you want to use for that.
But you'd still have to check activator.properties in to git because the Activator template-publication system does not run sbt on the project, it just looks at the files in git.
And also your nice template intended for end-users would end up with some extraneous build code in it to generate activator.properties, which would clutter up the example.
You could try going the other way but I think it won't work.
In sbt, name is a setting rather than a task, and is thus evaluated only once -- so if you made it read from activator.properties, you'd need to restart (or at least reload) your sbt build whenever you edited activator.properties. But you could read from activator.properties using whatever scala code you like. Something like:
name := {
val props = new java.util.Properties()
props.load(new java.io.FileReader(file("activator.properties")))
props.getProperty("name")
}
However, this is going to fail for two reasons.
When a template is instantiated (cloned) by an end user:
activator.properties is dropped
activator tries to replace the name in build.sbt with a user-selected one
So on clone, first the above code would fail due to missing activator.properties, and second the user's selected name wouldn't be swapped in (because the above expression is too complicated for activator to figure out how to replace it).
This name-replacement means your build.sbt name will get dropped in most cases anyway. The one exception is if the user downloads the "template bundle" (a pre-cloned zip of the project) from the template's detail page on typesafe.com, then the name in your build.sbt would be kept.
Note that if you ever change the name in activator.properties then you'd end up duplicating your template (you'd effectively be publishing a new template), so you may not want to abstract this anyway -- you should change it only when creating a new template is your intent.
Perhaps the bottom line is KISS -- write the name in two places. The alternatives are all going to cause headaches.
The only way I can think of to make this sane would be to have some code outside of the template which generated the template. Akka and Play both do this, I think, for templates that are part of the larger akka and play source trees. But at this point you're definitely doing more work than I'd do just to avoid copying one name string around, you'd want to have some other reason to go there.

How to get brackets to ignore particular repeating errors?

I get JSLint errors in a file for undeclared functions and variables referenced from another file. Does brackets have a configuration/menu to remove these while keeping other linting errors?
JSLint complains whenever you reference an identifier that it can't see any declaration for in the file. So if you're using global variables/functions that were set by some other file, you'll get these warnings.
You can stop the warnings by individually specifying which undeclared globals you want to allow. To do that, place a directive like this at the top of your file:
/*jslint indent: 4 */
/*global ClassFoo, ClassBar, someFunction */
But of course, it's a pain to list things manually in each file.
Perhaps the best way to clean this up is to use a module loader like RequireJS. Then most your references to other files won't be through globals, and you'll only have to tell JSLint to ignore the few globals needed for RequireJS itself (usually just define).
Using a module loader has other benefits too. It eliminates "dependency spaghetti" by making cross-file dependencies very explicit, and it automatically load modules in proper dependency order. And there are easy tools that automatically concatenate all your modules into one file when you're ready for deployment.

Force Flash Builder 4 to compile all source files

According to the answers to this question here, the reason why I'm not seeing errors as I work in Flash Builder is that FB is "optimizing" them out because they aren't referenced at any point in the code execution. Is there an option to force Flash Builder to compile all files regardless of whether they're used in the software? This would make my development process a lot more intuitive.
The only way to do this is to actually reference the class somewhere in code that you know actually is being compiled, such as the Document Class in a .fla, or your Main.as file in a pure AS3 project. It can be as simple as declaring a variable of the given type, even if no value is ever assigned to it.
private var complieMe:OtherwiseUnreferencedClass;
// ^ This will cause your class to be compiled.
You need to reference each class somewhere in your project. The easiest/shortest way I've found to do this is to add an import followed by the class name in some common place, such as a script block in Main.mxml, although it really doesn't matter where:
import some.package.MyClass; MyClass;
Hope that helps.

Optimizing Flex when multiple modules are used

I have a Flex application where load time is extremely important (consumer site). i want to be able to get something up on screen and then allow additional modules to be loaded as necessary.
The issue I'm facing is that the sum total of all the modules is much larger than if i were to include all the components in a single .swf file.
Its pretty obvious why. For instance the classes needed for web service access seem to take about 100kb. If I dont use those classes in my main.swf then they'll be included in EVERY module that uses them. So if I have 5 modules thats an extra 500kB wasted.
In theory I want 3 levels
main.swf - minimum possible layout / style / font / framework type stuff
common.swf - additional classes needed by module 1 + module 2 (such as web services)
module1.swf - module 1 in site
module2.swf - module 2 in site
I dont know if this is even possible.
I'm wondering if I can load swz/swf files for portions of the framework instead of the entire framework.
I really need to get my main app size down to 200Kb. It grows to 450kb when I add web services and basic datagrid functionality.
Any lessons learned would be appreciated.
I know this was awhile ago, but I figured I'd post another response in case anyone is still looking for an answer on this.
I've been looking into optimizing Flex apps and, after some checking into it, have decided to use Modules. Primarily 'cause they have such good options for optimization.
The two mxmlc commands you need are:
mxmlc -link-report=MyAppReport.xml MyApp.mxml
and
mxmlc -load-externs=MyAppReport.xml MyModule.mxml
My external swf (using the Flex Framework) is now only 21k. It's doing much (yet), but even as it does more and more, it will continue to use resources from the main app code.
Here's the batch file I created to speed up the process (you have to have put mxmlc in your Environment Path variable for it to work like this. Control Panel -> System -> Advanced -> Environment Variables, Edit the Path System Variable, adding the path to your mxmlc (requires a reboot)):
cd C:\Projects\MyProject\Develop\Modules
mxmlc -link-report=MyAppReport.xml C:\Projects\MyProject\Develop\Source\Main.mxml
mxmlc -load-externs=MyAppReport.xml MyModule.mxml
move /Y MyModule.swf ..\Runtime\Modules
More info here:
http://livedocs.adobe.com/flex/3/html/help.html?content=modular_4.html
Hope that helps!
Flex is a bit of a pig when it comes to file size. There really is only one way to get your app sizes down and that is to use an external swz for the framework. There is an Adobe Devnet article on Improving Flex application performance using the Flash Player cache which I recommend you read.
On a project I worked on we had problems with our preloading module sucking in classes that we didn't want. What we had to do was create interfaces to the classes that resided in the other modules and reference them that way. When the module is loaded we simply assigned a reference to the IApplicationModule in order to call our initialization code.
Also look into putting your classes into a seperate SWF file and then use ApplicationDomain to get access to the classes
(this code taken from this forum post which explains how to access classes loaded from modules in Flex)
private function loadContent(path:String):void
{
var contentLoader:Loader = new Loader();
contentLoader.contentLoaderInfo.addEventListener(
Event.COMPLETE,
loadContent_onComplete);
contentLoader.load(new URLRequest(path));
}
private function loadContent_onComplete (event:Event):void
{
var content:DisplayObject = event.target.content;
if(content is IFlexModuleFactory)
{
var content_onReady:Function = function (event:Event):void
{
var factory:IFlexModuleFactory = content as IFlexModuleFactory;
var info:Object = factory.info();
var instanceClass:Class = info.currentDomain.getDefinition(
info.mainClassName) as Class;
addChild (new instanceClass ());
}
content.addEventListener ("ready", content_onReady);
}
else
{
addChild (content);
}
}
There is an option on the command-line compiler to exclude class definitions that are already compiled into another swf. It works like this:
Compile the Main Application (which contains a loader) and opt to generate a report.
Compile the Module and opt to exclude classes in the above report.
You could look into the ModuleLoader class, maybe you can load up your core stuff in the first 200kbs then load the rest when and if it's needed.
Also it's worth bearing in mind that any SWC's you use are embedded at compile time whereas any SWF's are loaded at runtime.

Resources