Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

How do you use the ui.frontend module with NPM to add JavaScript libraries to your AEM Site

tyronet42925573
Level 2
Level 2

So in my AEM Sites project, I want to use the ui.frontend module to add the JavaScript files for datatables.net by using npm.
So in the documentation link for installing the JavaScript and CSS files for datatables.net is
https://datatables.net/download/index

To install it using NPM the command is

npm install --save datatables.net-dt

 

So in my AEM projects ui.frontend folder I ran the command 
Screen Shot 2021-11-05 at 11.34.43 AM.png
Which updated the file package.json to contain the datatables.net dependency 
e.g

"dependencies": {
"datatables.net-dt": "^1.11.3"
}

The full package.json file generated is

{
  "name": "aem-maven-archetype",
  "version": "1.0.0",
  "description": "Generates an AEM Frontend project with Webpack",
  "repository": {
    "type": "git",
    "url": "https://github.com/adobe/aem-project-archetype"
  },
  "private": true,
  "main": "src/main/webpack/site/main.ts",
  "license": "SEE LICENSE IN LICENSE.txt",
  "scripts": {
    "dev": "webpack -d --env dev --config ./webpack.dev.js && clientlib --verbose",
    "prod": "webpack -p --config ./webpack.prod.js && clientlib --verbose",
    "start": "webpack-dev-server --open --config ./webpack.dev.js",
    "sync": "aemsync -d -p ../ui.apps/src/main/content",
    "watch": "webpack-dev-server --config ./webpack.dev.js --env.writeToDisk & watch 'clientlib' ./dist & aemsync -w ../ui.apps/src/main/content"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0",
    "@babel/plugin-proposal-class-properties": "^7.3.3",
    "@babel/plugin-proposal-object-rest-spread": "^7.3.2",
    "@typescript-eslint/eslint-plugin": "^2.14.0",
    "@typescript-eslint/parser": "^2.14.0",
    "acorn": "^6.1.0",
    "aem-clientlib-generator": "^1.4.3",
    "aemsync": "^4.0.1",
    "autoprefixer": "^9.2.1",
    "browserslist": "^4.2.1",
    "clean-webpack-plugin": "^3.0.0",
    "copy-webpack-plugin": "^5.0.4",
    "css-loader": "^3.0.0",
    "cssnano": "^4.1.10",
    "eslint": "^6.8.0",
    "eslint-loader": "^3.0.3",
    "glob-import-loader": "^1.1.4",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.4.4",
    "optimize-css-assets-webpack-plugin": "^5.0.1",
    "postcss-loader": "^3.0.0",
    "sass": "^1.17.2",
    "sass-loader": "^7.1.0",
    "source-map-loader": "^0.2.4",
    "style-loader": "^0.14.1",
    "terser-webpack-plugin": "^1.4.1",
    "ts-loader": "^5.3.3",
    "tsconfig-paths-webpack-plugin": "^3.2.0",
    "typescript": "^3.3.3333",
    "watch": "^1.0.2",
    "webpack": "^4.27.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.9.0",
    "webpack-merge": "^4.2.1"
  },
  "dependencies": {
    "datatables.net-dt": "^1.11.3"
  },
  "browserslist": [
    "last 2 version",
    "> 1%"
  ]
}

 
So I then ran the NPM command

npm run dev 

to build the CSS and JavaScript into apps/<my app>/clientlibs/clientlib-site/
when I look at the site.js file that is generated I expected it to contain the JavaScript for the datatabes.net, but it does not.

What steps am I missing?



5 Replies
dgordon86
Employee
Employee

hi @tyronet42925573  you will want to then reference the datables in your main.ts file: https://github.com/adobe/aem-project-archetype/blob/develop/src/main/archetype/ui.frontend.general/s...

 

Something like this:

 

var $  = require( 'jquery' );
var dt = require( 'datatables.net' )();
tyronet42925573
Level 2
Level 2

When I put 

var $  = require( 'jquery' );
var dt = require( 'datatables.net' )();

in to the file src/main/webpack/site/main.ts
and then run the command

 npm run dev

I get the errors

4:5 warning '$' is assigned a value but never used @Typescript-eslint/no-unused-vars
4:9 error Require statement not part of import statement @Typescript-eslint/no-var-requires
5:5 warning 'dt' is assigned a value but never used @Typescript-eslint/no-unused-vars
5:10 error Require statement not part of import statement @Typescript-eslint/no-var-requires

✖ 4 problems (2 errors, 2 warnings)

I don't get the errors when I put

require( 'jquery' );
require( 'datatables.net' );

or

import "jquery";
import "datatables.net";

and the file src/main/content/jcr_root/apps/<my app>/clientlibs/clientlib-site/js/site.js
does seem to have the datatables.net JavaScript code in it.

Screen Shot 2021-11-05 at 5.12.12 PM.png
But it doesn't seem to used in any of my components that use datatables.net
The client library for the clientlib-site has .content.xml file value

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
categories="[frontend.site]"
dependencies="[frontend.dependencies]"
cssProcessor="[default:none,min:none]"
jsProcessor="[default:none,min:none]"
allowProxy="{Boolean}true"/>

The components that use datatables.net have the clientlib .content.xml file values

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
allowProxy="{Boolean}true"
categories="frontend.components"/>

The client library clientlib-base have the .content.xml file value
 

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
allowProxy="{Boolean}true"
categories="[frontend.base]"
embed="[frontend.components,core.wcm.components.accordion.v1,core.wcm.components.tabs.v1,core.wcm.components.carousel.v1,core.wcm.components.image.v2,core.wcm.components.breadcrumb.v2,core.wcm.components.search.v1,core.wcm.components.form.text.v2,core.wcm.components.pdfviewer.v1,core.wcm.components.commons.datalayer.v1,frontend.grid]"/>
Arun_Patidar
Community Advisor
Community Advisor

Hi,

This is due to either eslint rule or ui.frontend.general/.eslintrc.js or typescript rule ui.frontend.general/tsconfig.json

which can be disabled to not check unused.

tyronet42925573
Level 2
Level 2

I updated the following file ui.frontend/.eslintrc.js
and added the following entry

"@typescript-eslint/no-var-requires": 0,


Contents of the whole file

module.exports =  {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
],
parserOptions: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
},
rules: {
"curly": 1,
"@typescript-eslint/no-var-requires": 0,
"@typescript-eslint/explicit-function-return-type": [0],
"@typescript-eslint/no-explicit-any": [0],
"ordered-imports": [0],
"object-literal-sort-keys": [0],
"max-len": [1, 120],
"new-parens": 1,
"no-bitwise": 1,
"no-cond-assign": 1,
"no-trailing-spaces": 0,
"eol-last": 1,
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
"semi": 1,
"no-var": 0
},
};

 
Which now allows the entries in the file
ui.frontend/src/main/webpack/site/main.ts

 

// Stylesheets
import "./main.scss";
// Javascript or Typescript
import "./**/*.js";
import "./**/*.ts";
// Include jquery and datatables.net to site.js
var $  = require( 'jquery' );
var dt = require( 'datatables.net' )( window, $ );

Which generate the Javascript from jQuery and datatales.net into the file
ui.apps/src/main/content/jcr_root/apps/frontend/clientlibs/clientlib-site/js/site.js

When I run the command

mvn clean install -PautoInstallSinglePackage

to install the package from the root folder to my AEM Author instance.

The component that I uses datatables.net still has the error
Screen Shot 2021-11-08 at 1.18.23 PM.png 



tyronet42925573
Level 2
Level 2

I posted this question internally at Adobe, and the feedback was

The advantage of using the ui.frontend module is to then be able to reference these libraries within scripts within the ui.frontend module and then webpack will intelligently build/compile your css/js artifacts. If you are just using jQuery, Datables statically, i'm not sure there is a real advantage of jamming them in the ui.frontend module only to output them as clientlibrary later.

 

So the ui.frontend module should not be used to add 3rd party JavaScript libraries to be generated to the

/clientlibs/clientlib-site/js/site.js

instead just create a client library the old fashion way.

 

e.g.

Screen Shot 2021-11-12 at 11.39.42 AM.png

and then reference this client library as an embed entry in the clientlib-base

Screen Shot 2021-11-12 at 11.46.12 AM.png