-
Notifications
You must be signed in to change notification settings - Fork 123
How to load amber
herby edited this page Oct 15, 2014
·
27 revisions
Amber is available both through the node and the bower package managers.
Note: This page is not obsolete in the sense that every piece described here still happens to exist in version 0.13 but has been moved to different files (devel.js
, deploy.js
, *.amd.json
). So this page needs to be rewritten to show things for 0.13 version and return the link back to Home page.
To load Amber, you should add these <script>
tags into your page (placement to head
or at the end of body
at your own discretion; if you want/need to load amber.js
or both the first two scripts asynchronously, see Note 2):
<!-- 1 -->
<script src="path_to_amber/support/requirejs/require.min.js"></script>
<!-- 2 -->
<script src="path_to_amber/support/amber.js"></script>
<!-- 3 -->
<script>
require.config({paths:{
// ---- up to version 0.12.3 use this ----
// -- 4 --
'biz_corp_clientlib': 'path_to_corp_clientlib/js',
'gh_author_foolib': 'path_to_foolib/js',
'biz_corp_app': 'code/js',
// -- 5 --
'biz_corp_app/_source': 'code/st'
// ---- since version 0.12.4 use this ----
// -- 4 --
'biz_corp_clientlib': 'path_to_corp_clientlib/src',
'gh_author_foolib': 'path_to_foolib/src',
'biz_corp_app': 'code/src',
// ---- end of version specific parts ----
}});
require([
// -- 6 --
"amber/devel",
// -- 7 --
"gh_author_foolib/FooLib-Backend",
"gh_author_foolib/FooLib-Frontend",
"biz_corp_clientlib/CorpClient-Bar",
"biz_corp_clientlib/CorpClient-Baz",
"biz_corp_app/CorpApp-Model",
"biz_corp_app/CorpApp-Client"
], function (amber) {
// ---- up to version 0.12.2 use this ----
// -- 9 --
amber.defaultAmdNamespace = 'biz_corp_app';
// -- 8 --
amber.initialize();
// ---- since version 0.12.3 use this ----
// -- 8 --
amber.initialize({
// -- 9 --
'transport.defaultAmdNamespace': 'biz_corp_app'
});
// ---- end of version specific parts ----
// -- 10 --
amber.globals.Browser._open(); // for legacy IDE, or
amber.popupHelios(); // for Helios IDE
amber.AppLogic._start();
});
</script>
Notes:
- Loading AMD loader
-
path_to_amber
can be anything - relative path, absolute path or full URL. - You don't need to load
require.js
AMD loader from amber location, you can load it from any other place you want. - Not tested, but amber should play just fine with any conforming AMD loader.
- Loading amber.js script that configures AMD loader
-
path_to_amber
can be anything - relative path, absolute path or full URL, it depends how you deploy / decide to load amber from. -
amber.js
is built so that it can appear afterrequire.js
but also before it - it the former case it properly configuresrequire.js
, it the latter case it prepares the configuration intorequire
global, using the feature ofrequire.js
that uses contents ofrequire
global, if it exists, as the configuration upon loading itself. - If you want to load and execute this script asynchronously, you must give it
id='amber-path-mapper'
, otherwise it cannot find its parameters (path and attributes).
- Hand-written script that actually loads Amber including your packages
- it is only required that things described later happen, in that order, sometimes after (1) and (2), but you can structure them as you wish; using
<script>
tag with presented structure is just a convention.
- Configuring namespace-to-path mappings for loading packages
- Each package in amber must have a namespace, the part before '/'. There should be no dot in namespace.
- Each namespace represents one physical location to load from, and optionally, to save to; IOW, it represent one URL path; again, it can be relative path (relative to page being loaded), absolute path or full URL path.
- You should point 'namespace' to the location of compiled amber files, which have
.js
extension. The convention in lot of projects is to put source (Smalltalk) files into.../st
and compiled files into.../js
where...
is same path. This is why in this example, all three namespaces are mappped into paths that end with/js
. This convention has changed inside amber itself and for new projects in version 0.12.4: there should be only one foldersrc
which holds both.js
and.st
files. - Namespaces are selected for the library / app (a group of amber packages at the same location) by its developer and are hardcoded into it. For this reason, care must be taken when selecting namespace, so it does not clash with other namespaces. One technique, used in this example as well, is to take the 'path' where the project resides ('corp.biz/clientlib', 'github.com/author/foolib' etc.), revert the domain name ('biz.corp/clientlib', 'com.github/author/foolib' etc.) and replace all separators ('.', '/') with underscores ('biz_corp_clientlib', 'com_github_author_foolib'). One can do some simplifyings if they seem to be safe enough; like shortening
github_com_
intogh_
. - Changing namespace is hard, or even impossible if your code is already reused (is a library) and is a breaking change. The namespace is world-wide global name for a group of files of your project. Every file of your project needs unique name, to be able to use it in list of dependencies in AMD. That is the role of namespace - to give your files a unique prefix (thus "name space"). Other, more technical, side to namespaces is that they group files that are held together, thus forming a high-level module. You can deploy this module anywhere you wish, since you map the namespace into the physical location for the loader.
- This example represents complex application that resides at
corp.biz
domain. This page loads the app, which has its own code (namespacebiz_corp_app
), uses some internal library (namespacebiz_corp_clientlib
) and also uses (contrived) third-party library foolib created by author and developed in github (namespacegh_author_foolib
). - As in previous cases,
path_to_corp_clientlib
andpath_to_foolib
can be any URL paths - relative to page being loaded, absolure or full URL paths with protocal, machine etc. - You can see the namespace
biz_corp_app
is mapped to relative pathcode/ja
, that is, if this page ishttp://foo/bar/index.html
, the mapped path ofbiz_corp_app
would behttp://foo/bar/code/js
.
- Configuring namespace-to-path mappings for saving package sources
- If you map 'namespace/_source' (the special ending
/_source
), you are mapping the URL path into which the page will try to save sources (file with.st
extension) of amber packages in namespace 'namespace'. - When saving, compiled
.js
files are saved as well; these are saved into the same path which is used for loading them. - Since version 0.12.4, it is recommended not to map
.../_source
at all. In that case,.st
files will be saved to the location of.js
files. - In this example, if you save any package from namespace
corp_biz_app
, its.st
file is tried to save intocode/st/PackageName.st
and the compiled file is saved intocode/js/PackageName.js
.
- Specifying proper amber subset to load
- The first element of an array of modules to load in the require call should be one of the preconfigured amber sets. There are three sets available:
amber/devel
which loads all amber packages including IDE and SUnit support,amber/helios
which loads all thatamber/devel
does but also adds the new work-in-progress IDE named Helios, andamber/deploy
which includes only core amber itself andCanvas
package for working with web page, but no IDEs, no compiler and no testing support is included. - If you wish to select your own subset, either make your own set by cloning and modifying some of the amber ones, or put
amber_vm/smalltalk
as the first element of the array and then include all amber packages you want to load by hand after it. There is no need to do this, though for 99.9% of the projects ;-)
- Listing other packages to load
- Besides the amber subset from (6), you also want to load your / third-party packages as well, so that you app actually loads. You just list them here. Of course, to load them, namespaces must be correctly mapped to paths in (4).
- If you happen to create new package and successfully save it, you must add it into this list in your
.html
page by hand. Amber does not touch your .html in any way - you write the loading scripts, you manage them; Amber only saves.st
file with source and``.js` file with compiled JavaScript into designated locations.
- Initializing smalltalk
- Sets up all the loaded packages and the amber runtime.
- Required before running any amber code.
- Specifying default namespace
- Amber itself does not have the concept of package namespace in the language itself. Namespace is the matter of external structure of the project (where are groups of packages located / loaded from / saved to). An existing package knows its namespace and uses it when saving. Newly created packages have no explicit namespace set, as they are created as a side effect of adding a class to a package name.
- This sets the 'default namespace'. Its sole purpose is to be added as a namespace to all newly created packages.
- If you are sure no new packages will ever be created (you are only using the packages to run some page, used
amber/deploy
subset to load amber; IOW you are not developing), you can omit this line altogether. - If you want to have a new package in different namespace than the default, just issue
(Package named: 'NewPackageName') transport namespace: 'new_namespace'
in Workspace after the package is created but before it is saved.
- Launching some startup code
- You should start your app / etc. by issuing some code here.
- In this example, you see the equivalent of
Browser open
andAppLogic start
. The first just opens the legacy IDE - while you are developing the app, it is convenient to have IDE opened automatically (the alternative code in the second line opens the new Helios IDE instead). The third line is just the stereotypical 'start the app' line, expecting you haveAppLogic
class somewhere in the code (probably inCorpApp-Client
package). - Alternatively, you can open legacy Browser by slightly longer
smalltalk.Browaer._openOn_(smalltalk.AppLogic)
which is compiled version ofBrowser openOn: AppLogic
. As it suggests, it opens the Browser on the specific class (as opposed to empty one from the example).