Always reference the documents on the git repo since they are updated more often then the NPM package website. I update NPM when there is a code change. I might change documentation without a code change and, at that time, I would not update the version number or NPM release.
gulp-component-assembler
is a gulp plug-in that assembles JavaScript components. The source for the components are a combination of JavaScript files, HTML Templates and Localization strings.
gulp-component-assembler
uses the file assembly.json
to define the list of files to assemble into the component output file. The filename of the component will be the name of the folder that contains the assembly.json
file. The extension of the component file .js
.
Examples: For a folder named
widget
the component output file will bewidget.js
. For a folder namedMyControl
the component output file will beMyControl.js
. The case of the component filename matches the case of the folder name.
Prior to version 2.0.0 the component output file would be placed in a folder of the same name as the output file itself.
As of version 2.0.0 the additional folder name is removed and component output file is placed one folder higher than it had been in previous versions.
Example For the path
.../testing/widget/assembly.json
the old, version 1.x, component output file would have been_outputPath_/widget/widget.js
and the new, version 2.0, component output file will be_outputPath_/widget.js
With version 2.x you can continue to use the old output path by including the useOldDest
option in the assemble()
command. See the useOldDest
option below.
The assembled contents of the component file are wrapped inside an Immediately-Invoked Function Expression (IIFE). This helps prevent anything within the component from having a negative effect, like name collisions, with any other script files loaded on the page.
npm install gulp-component-assembler --save-dev
or
npm install -g gulp-component-assembler
Please submit pull requests and issues. I want to make this into a tool that is useful to everyone. I will do my best to review and take care of PRs and issues quickly. If you have suggestions, I would love to hear them.
gulp-component-assembler
supports plug-ins to be run at various times during the assembly process. Plug-ins allow special manipulation of the component output file. If you create a plug-in, please either create a PR on the plug-in page or email me your info. I will add it to the list of third-party plug-ins in the PLUGINLIST.md file
The primary usage of the gulp-component-assembler
is to assemble the component output files. This is done when gulp calls the assemble()
function. This function uses the information in the assembly.json
file to assemble the component output file. The source files does not need to be called assembly.json
, but it must be a JSON
file and it must conform to the correct structure of the assembly.json
file. For simplicity, throughout all documentation, I will call this file assembly.json
You can also call the function loadPlugin()
to load plug-ins into the assembly process. Plug-ins, how to use them and how to write them are defined in the plug-ins README.md file
Here is an example of how to use the assemble()
function:
var gulp = require('gulp');
var compasm = require('gulp-component-assembler');
gulp.task('assemble', function() {
return gulp.src('./assembly.json')
.pipe(compasm.assemble())
.pipe(gulp.dest('./dist'))
});
gulp-component-assembler
provides it's own watch function that should be used in place of gulp.watch
. Pass the function the same parameters you would to gulp.watch
. The watch function only works in Gulp 4.
gulp.task('watch', function() {
compasm.watch('./assembly.json', gulp.series('assemble'));
});
gulp-component-assembler
provides it's own changed function that should be passed to gulp-changed
as an option. This will properly detect whether the files in the assembly.json have changed.
gulp.task('assemble', function() {
return gulp.src('./assembly.json')
.pipe(changed(dest, {hasChanged: compasm.hasChanged}))
.pipe(compasm.assemble())
.pipe(gulp.dest('./dist'))
});
The assemble()
function takes an optional object which contains any combination of the options defined below. These options allow the user to customize the assembly process and the output file for the component. The options are defined in the object passed to the assemble()
function. Like this:
compasm.assemble({
"defaultLocale": "en",
"exposeLang": true
})
Here is the list of options and their description and usage:
Key | Example | Use |
---|---|---|
allowMultiRootTemplates | allowMultiRootTemplates:true/false |
New in 3.0.0 - If set to true then templates can have multiple root nodes. |
defaultLocale | defaultLocale:"en" |
Set the locale that your project will use as the default locale. If you do not provide the defaultLocale option then the default locale is set to "en" . defaultLocale is also the locale that is used if the user attempts to request a non-supported locale. |
exposeLang | exposeLang:true/false |
If set to true then the language strings are also placed into a global object for access outside of the IIFE. The language strings will be added to [globalObj].[assemblyName].lang where assemblyName is the name of the assembly that is being created.See globalObj . |
externalLibName | externalLibName:"filename" |
Name for the external lib file. The default is assembly-lib.js and assembly-lib-min.js .See useExternalLib . |
externalLibPath | externalLibPath:"path/to/output/lib" |
Path to output the external lib file. The default is ./ .See useExternalLib . |
globalObj | globalObj:"objectToUse" |
This is an optional string that defines the global object that is used to expose the language string into the global scope. The default value is "window.components" .If you are building servers-side components to run in node.js, then you would set this to "global.components" or something similar. But be aware that this could become a problem if you are working with a server cluster.Currently this is only used if you set the option exposeLang to true . |
iifeParams | iifeParams:paramsObject |
This is an optional object that contains the list of parameters used by the IIFE and the list of parameters passed into the IIFE. The default values are "window, document". See Option: iifeParams below. |
localeVar | localeVar:"window.locale" |
The default value for this options is window.locale . If your application uses some other variable to set the locale then you can supply it here like window.myObj.locale . If the defined variable name is undefined or does not exist then the locale is set to the value of the option defaultLocale .See defaultLocale above. |
minTemplateWS | minTemplateWS:true/false |
This controls how white space is processed in the templates. If set to true then each set of white space is reduced to a single space to reduce the overall size of the templates while maintaining separation of tags. If set to false then all white space is preserved with the exception the white space at the beginning and end of the template which is trimmed and removed. |
supportTransKeys | supportTransKeys:true/false |
If set to true this creates a set to translation test values.See Option: supportTransKeys below. |
tagMissingStrings | tagMissingStrings:true/false |
If set to true then any string that was in the locale file for the default locale that is not found in one of the other locale files is marked so the user can see the lack of translation easily. If set to false then the missing translations are set to the key for that string. |
useExternalLib | useExternalLib:true/false |
If set to true then a single file assambly-lib.js is created with the common code used for each assembly. If it is set to false then each assembly contains copies of the common code needed for the assembly to work. If you choose to use the external libraries then you must include that file before including your own. |
useOldDest | useOldDest:true/false |
New in 2.0.0 - If set to true then the output directory structure is used. The output files are placed in the same folder as the assembly.json file. (Same as before ver. 2.0.0) If set to false then the output files are stored one level higher than the pre 2.0.0 locations, the parent folder of where the assembly.json file. |
useStrict | useStrict:true/false |
If set to true then "use strict"; is added just inside the IIFE.See Option: useStrict below. |
Option names are case sensitive. defaultLocale
is correct but DefaultLocale
is not.
Below is an example of assembling a component with the following options set:
- Set the default language to French
- Remove extra white space from templates
- Use the external version of the helper library code
- And, by using
gulp-uglify
, the code will be saved in both a non-minified and minified version file.
var gulp = require('gulp');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var compasm = require('gulp-component-assembler');
gulp.task('assemble', function() {
return gulp.src('./assembly.json')
.pipe(compasm.assemble({
"defaultLocale": 'fr',
"minTemplateWS": true,
"useExternalLib": true,
"externalLibPath": "js/"
})
.pipe(gulp.dest('./dist'))
.pipe(uglify())
.pipe(rename(function (path) {path.basename += "-min";}))
.pipe(gulp.dest('./dist'))
});
#### Option: `iifeParams`
The option iifeParams
is used to provide the values that are accessible within the IIFE function and the values that are passed into the IIFE.
The last parameter in the IIFE function is always undefined
which is automatically added to the function.
To set these values you create an object that has both a use
and a pass
property like this:
"iifeParams": {
"use": "window, document, $",
"pass": "window, window.document, window.jQuery"
}
This will produce the following in the component output file:
(function(window, document, $, undefined) {
// Your code would be here.
})(window, window.documet, window.jQuery);
#### Option: `supportTransKeys `
When supportTransKeys
is on the gulp-component-assembler
auto generates two special locales, ke
and zz
. When these locales are used the strings returned in the lang
object include the key names instead of the translated strings. More information about this is found in the section Accessing locale strings in your JavaScript
below.
#### Option: `useStrict`
If the option useStrict
is set to true
then the expression "use strict";
is added just inside the IIFE function like this:
(function(window, document, undefined) {
"use strict";
// Your code here
})(window, window.document);
The assembly.json
file defines a list of JavaScript source files, HTML template files and sub-assemblies to be included in the component output file. It can also define special locations for locale string files.
The assembly.json
files supports the following properties: files
, templates
, localePath
, localFileName
, and subs
.
The minimum assembly.json
file must contain the files
array, which defines the JavaScript source files to include in the assembled component.
{
"files": [
"file1.js",
"src/file2.js"
]
}
The built-in properties of the assembly.json file:
Property | Type | Description |
---|---|---|
files |
globby array of files | The list of one or more files, normally JavaScript files, to combine into the component file. |
templates |
globby array of files | The list of one or more files, normally HTML files, to combine as template strings into the component file. |
subs |
globby array of files | A list of one or more assembly.json files that are assembled into the component output file. |
localeFileName |
string | The root of the locale file names. The default is strings or the name of the containing folder. |
localePath |
string | A relative path indicating where to load the locale files. The default path is ./locales . |
Note: Additional properties can be placed in the assembly.json
file to be used by plug-ins. All additional properties will be ignored by the main assemble()
function. **But, since we have no idea what features might be added we also don't know what possible properties may be used by the assemble()
function in the future. For more information please see the section "Your own properties in the assembly.json
file" in the plug-ins README.md file
The
files
array property is a globby list of JavaScript source files that are to be included in this component. All file names are relative to the location of theassembly.json
file.
Each of these files are loaded, in the order provided, and appended into the component file. No modifications are made to these files.
All of the code from the files listed in the
files
array is wrapped inside an IIFE. This IIFE is to prevent name collisions between this component and all other JavaScript that you will load. So if you want anything accessible outside of the IIFE then you must provide the code to make it accessible. The simplest, but not best solution, is to create global variable. In the browser this is done by attaching parameters to thewindow
object. For example:
var localVar = "This will be a private variable, protected inside an IIFE";
window.globalVar = localVar; // This is now accessible throughout the app/web page
I should warn about making everything public and a member of the
window
object. This can lead to complicated code and hinder reusability. It is better to use some form of a module loading system.
Depending on your environment you may expose properties, classes and functions through things like
module.exports
,define
or an existing global object or function. But I leave that to you to research and find the best mechanism for you and your team.
the
templates
array property is a globby list of template files.gulp-component-assembler
will load all of these files and convert them into template strings within the assembled component.
If you do not provide a
temlates
entry in theassembly.json
thengulp-component-assembler
will attempt to load the default templates: "./templates/*.html"
Each file is converted to a string and appended to the
templateList
object in the output component file.
The templates are loaded by your script by accessing the
templateList
object, or by calling theloadTemplate()
function or theloadTemplateStr()
function.
If there are both templates and locale files then calling
getTemplate()
orgetTemplateStr()
will auto-populate translations in the data returned from those functions.
Template files allow you to wrap HTML content into your assembly. These templates can be used by your code to create DOM on the fly.
Angular directives often need templates. Using a provided template system from
gulp-component-assembler
allows the developer to create the templates as stand-alone HTML files and import them into the directives.
TODO: Provide more information here
- Angular example
- jQuery example
- Raw JS example
- Other examples
One or more
assembly.json
files can be assembled and incorporated as sub-assemblies in the component output file by using thesubs
property to define which assemblies are to be included.
subs
is a globby array ofassembly.json
files that are assembled into the component output file. Again, the name of theseJSON
files does not need to beassembly.json
, but they must conform with a correctly formattedassembly.json
file.
Each assembly will be placed in it's own IIFE function and they each have their own templates and locale files. This also provides a unique name-space for each sub-assembly. But this prevents direct access of values and functions contained in the other sub-assemblies without making them available through the global scope or some other mechanism.
If the
assembly.json
file in the myComponent folder looked like this:
{
"subs": [
"**/assembly.json"
]
}
And the file structure looked like this:
myComponent
│
├── assembly.json
├── sub1
│ │
│ ├── assembly.json
│ └── file.js
│
├── sub2
│ │
│ ├── assembly.json
│ └── file.js
│
└── thingy
│
├── item1
│ │
│ ├── assembly.json
│ └── file.js
│
└── item2
│
├── assembly.json
└── file.js
Then the component output file myComponent.js
would include the contents of the sub-assemblies sub1.js
, sub2.js
, thingy/item1.js
and thingy/item2.js
.
If the user does not provide a value for
localeFileName
thengulp-component-assembler
attempts to use the value of'strings'
. If files using that value do not exist then it attempts to use the value of the containing folder.
One locale file is needed per language. At this time,
2016-05-17
, we support the two letter (ISO-639-1) locale names, like'en'
,'fr'
,'de'
, etc. We also support four letter codes with fallback to two letter codes. For example,'zh-cn'
and'en-us'
are valid codes that fallback to'zh'
and'en'
.
TODO: Provide more information here
A value of
'localeFile'
would indicate files named like:localeFile_en.json
,localeFile_fr.json
,localeFile_zh.json
etc.
Note: If the user sets the
localeFileName
value in theassembly.json
file then the default value is not used.
Locale files are JSON files. They contain a single object that uses keys and values.
The default
- strings_en.json:
{
"BUTTON_OK": "OK",
"BUTTON_CANCEL": "Cancel",
"BUTTON_CLOSE": "Close",
"NO_CHANGES": "No Recent Changes"
}
- strings_fr.json:
{
"BUTTON_OK": "OK",
"BUTTON_CANCEL": "Annuler",
"BUTTON_CLOSE": "Fermer",
"NO_CHANGES": "Aucunes modifications récentes"
}
- strings_es.json:
{
"BUTTON_OK": "OK",
"BUTTON_CANCEL": "Cancelar",
"BUTTON_CLOSE": "Cerrar",
"NO_CHANGES": "No hay cambios recientes"
}
To set the selected locale in the browser you would set the global window.locale
to the locale you want to use.
The value for window.locale
must be set before loading any component output file.
TODO: Provide more information here
Within a component output file, each assembly and sub-assembly would contain it's own locale strings. These are accessed through the property lang
. In the examples JSON files above you would access the strings as lang.BUTTON_OK
, lang.BUTTON_CANCEL
, lang.BUTTON_CLOSE
and lang.NO_CHANGES
.
TODO: Provide more information here
Within a template file you access the locale strings by wrapping them within curly braces.
<div>
<div>{NO_CHANGES}</div>
<button>{BUTTON_OK}</button>
</div>
TODO: Provide more information here
gulp-component-assembler
support plug-ins. I have provided several and you can write their own.
For a list of available plug-ins go to the PLUGINLIST.md file.
For information on how to create your own plug-ins go to the plug-ins README.md file.
MIT - License File