UNPKG

aem-clientlib-generator

Version:

Creates configuration files for AEM ClientLibs and synchronizes assets.

302 lines (258 loc) 10.9 kB
# aem-clientlib-generator A node plugin that creates ClientLib configuration files (repository nodes) for [AEM ClientLibs](https://docs.adobe.com/docs/en/aem/6-2/develop/the-basics/clientlibs.html), creates _Client Library Folders_ and synchronizes all assets. ## Installation ```bash npm install aem-clientlib-generator ``` ## Usage ### Command Line Interface The CLI `clientlib` is located in `./bin/clientlib-cli.js`. The command can be used without parameters, it loads the default configuration file `clientlib.config.js`. More options are described in help menu: ```text Options: --help, -h Show help [boolean] --version, -v Show version number [boolean] --dry 'Dry run' without write operations. [boolean] --verbose Prints more details [boolean] ``` #### clientlib.config.js A clientlib configuration file is a simple exported module: ```js module.exports = { // default working directory (can be changed per 'cwd' in every asset option) context: __dirname, // path to the clientlib root folder (output) clientLibRoot: "path/to/clientlib-root", // define all clientlib options here as array... (multiple clientlibs) libs: [ { name: "test.base.apps.mainapp", assets: { js: [ "src/frontend/js/app.js" ], css: [ "src/frontend/css/styling.css" ] } }, ...// next clientlibs ], // or as object (single clientlib) libs: { name: "test.base.apps.mainapp", assets: { js: [ "src/frontend/js/app.js" ], css: [ "src/frontend/css/styling.css" ] } } } ``` #### npm scripts The CLI can be used in a project as local module via npm scripts (defined in `package.json`). ```js // package.json file: "scripts": { "test": "mocha", "build": "clientlib --verbose" } ``` In this case `npm run build` tries to load the default clientlib configuration file `clientlib.config.js` (same directory like package.json) and generates all clientslib as defined. ### Module: clientlib(arrProps | props, [options], callback) Import the module into a JavaScript file and run the module as a function: ```js var clientlib = require("aem-clientlib-generator"); clientlib(arrProps, { verbose: true }, function() { console.log("generator has finished"); }); ``` **Important:** Due to many write operations, the `clientlib` function is **asynchronously**! * `arrProps` `{Array<Object>}` Array of Clientlib configuration properties (see below) * `props` `{Object}` Clientlib configuration properties * `path` `{String}` Clientlib root path (optional if `options.clientLibRoot` is set) * `name` `{String}` Clientlib name (required) * `embed` `{Array<String>}` other Clientlib names that should be embedded (optional) * `dependencies` `{Array<String>}` other Clientlib names that should be included (optional) * `cssProcessor` `{Array<String>}` configuration for the clientlib CSS processor, requires AEM 6.2 (optional) * `jsProcessor` `{Array<String>}` configuration for the clientlib JS processor, requires AEM 6.2 (optional) * `assets` `{Object}` content that should be copied to the clientlib folder, more details below (required) * `allowProxy` `{Boolean}` allow for Clientlib creation under `/apps/myapp/clientLibs` but enable proxy to `/etc.clientlibs/myapp/clientlibs/mylib` See [AEM 6.3 Documentation](https://docs.adobe.com/docs/en/aem/6-3/develop/the-basics/clientlibs.html#Locating%20a%20Client%20Library%20Folder%20and%20Using%20the%20Proxy%20Client%20Libraries%20Servlet) * `longCacheKey` `{String}` optional string with placeholders to use with URL Fingerprinting, eq. `"${project.version}-${buildNumber}"` * `options` `{Object}` global options to be used for all clientlib definitions (optional) * `clientLibRoot` {String} Clientlib root path * `context` {String} changes the current working directory (via `process.chdir()`) * `cwd` {String} alias for `context` * `verbose` {Boolean} prints detailed information during generation * `dry` {Boolean} dry run without file write operations (sets automatically verbose to true) * `callback` `{Function}` to be called if clientlib() has finished ### The `assets` Object The `assets` object determine the content that should be pushed into the clientlib folder. The key stands for the content type, `js` for JavaScript files, `css` for styles and `resources` for other content such as fonts or images. ```javascript { js: { // JavaScript files to be copied and used for `js.txt` - a clientlib JS configuration file }, css: { // CSS files to be copied and used for `css.txt` - a clientlib CSS configuration file }, resources: { // other resources that should be copied } } ``` Each property can be an object of deeper configuration options (`assetConfig`) or an array of files (simple way, see example below). The following can be configured: * `assetConfig` `{Object}` Configuration object for an asset type * `base` `{String}` path within the clientlib folder where the data should be copied to (optional), default: asset key, e.g. for "js" is the base "js" * Hint: Using "." copies the files into the clientlib folder instead of the subfolder * `files` `{Array<String|Object>}` array of file paths (sources) or a src-dest key value map (required) * Important: The order of JS or CSS files in this property defines the merging/bundling order in AEM clientlib. * file object contains: * `src` {String} - source file relative to the current working directory or the global `cwd` option, if set * `dest` {String} - destination relative to the clientlib folder including base * `cwd` {String} - change working directory (relative to the context / global `cwd` option); only available with glob pattern * `flatten` {Boolean} - using file's basename instead of folder hierarchy; default true; only available with glob pattern For an glob example see example section below. ```javascript // simple version js: [ "pth/to/file.js", {src:"pth/to/lib/file.js", dest: "lib/file.js"} ] // will be transformed to: js: { base: "js" files: [ {src:"pth/to/file.js", dest: "file.js"}, {src:"pth/to/lib/file.js", dest: "lib/file.js"} ] } ``` ### Example ```javascript var clientlib = require("aem-clientlib-generator"); clientlib([ { name: "test.base.apps.mainapp", // the name will be used as subfolder in clientlibs root and for the AEM repository node // in this example it creates: // the subfoler: path/to/clientlibs-root/test.base.apps.mainapp/ // repository node: path/to/clientlibs-root/test.base.apps.mainapp.json // new in AEM 6.2: configure the clientlib processor by yourself: // An example to disable minification for CSS: cssProcessor: ["default:none", "min:none"], // using google closure compiler for minification instead of YUI jsProcessor: ["default:none", "min:gcc;compilationLevel=whitespace"], // new in AEM 6.3: create clientLibs in /apps/myapp/clientlibs and proxy to /etc.clientlibs/myapp allowProxy: true, // allow URL Fingerprinting via placeholder longCacheKey: "${project.version}-${buildNumber}", assets: { // creates the JS configuration file: // path/to/clientlibs-root/test.base.apps.mainapp/js.txt // which lists all JavaScript files from the ClientLib. // and copies all files into a js subfolder (default base): // path/to/clientlibs-root/test.base.apps.mainapp/js/ js: [ // file will be copied to: // path/to/clientlibs-root/test.base.apps.mainapp/js/app.js {src: "src/frontend/js/app.js", dest: "app.js"}, // file will be copied to: // path/to/clientlibs-root/test.base.apps.mainapp/js/libs/mylib.min.js {src: "src/frontend/js/libs/mylib.min.js", dest: "libs/mylib.min.js"}, // copy source map files as well {src: "src/frontend/js/libs/mylib.min.js.map", dest: "libs/mylib.min.js.map"} ], // creates the CSS configuration file: // path/to/clientlibs-root/test.base.apps.mainapp/css.txt css: [ "src/frontend/css/styling.css", "src/frontend/css/lib.css" ] } }, { name: "test.base.apps.secondapp", embed: [ "test.base.apps.thirdapp" // this clientlib will be auto embedded in AEM (kind of `merging`) ], dependencies: [ "test.base.apps.mainapp" // define clientlib dependency ], assets: { js: { base: "js", // by default the `base` is the asset key property files: [ {src: "src/frontend/secondapp/js/lib.js", dest: "secondapp-lib.js"} ] }, // creates the CSS configuration file: // path/to/clientlibs-root/test.base.apps.secondapp/css.txt // that lists all CSS files from the ClientLib. // All files defined below will be copied into the defined base: // path/to/clientlibs-root/test.base.apps.secondapp/style/ css: { base: "style", // changes the `base` from `css` (default) to `style` files: [ "src/frontend/secondapp/main.css" ] }, resources: [ "src/frontend/resources/template.html" ] } }, { name: "test.base.apps.thirdapp", assets: { // copy all files into the clientlib subfolder, because `base` is changed: // path/to/clientlibs-root/test.base.apps.thirdapp/ resources: { base: ".", // copy the file into `test.base.apps.thirdapp` (root) instead of `test.base.apps.thirdapp/resources` files: [ "src/frontend/resources/notice.txt" ] } } }, { name: "test.base.apps.fourth", assets: { js: { // "flatten" is true by default and using file's basename instead of path for destination // set to false to keep the folder hierarchy below "cwd" flatten: false, // remove this option if you like a flat list of files in your clientlib cwd: "src/frontend/js/", // change working directory (will be stripped from destination) files: [ "**/*.js", // match all js files recursively "**/*.js.map" ] }, css: [ // all css will copied to destination folder "style" (in base folder css) {src: "src/frontend/css/*.css", dest: "style/"}, // all css will copied to destination folder "vendor" (in base folder css) {src: "src/frontend/secondapp/*.css", dest: "vendor/"} ] } } ], { cwd: __dirname, // using folder of the file as current working directory clientLibRoot: path.join(__dirname, "path/to/clientlibs-root") }, function() { console.log("clientlibs created"); }); ```