Expand my Community achievements bar.

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

Avatar

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

Avatar

Employee Advisor

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' )();

Avatar

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 @Deleted Account-eslint/no-unused-vars
4:9 error Require statement not part of import statement @Deleted Account-eslint/no-var-requires
5:5 warning 'dt' is assigned a value but never used @Deleted Account-eslint/no-unused-vars
5:10 error Require statement not part of import statement @Deleted Account-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]"/>

Avatar

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.



Arun Patidar

Avatar

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 



Avatar

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