Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import non-core npm modules in Angular 2 e.g. (to use an encryption library)?

In my Angular 2 app (SystemJS module manager, Typescript as scripting language) I need to import a npm module to handle encryption (either Crypto-JS;Forge-JS or any other serving the purpose)

In the case of CryptoJS, after installing it via npm install * I tried by adding:

  <script src="node_modules/crypto-js/crypto-js.js"></script>

in index:html.

The in my service (app/services/my-service.service.ts) I import it via

  import {CryptoJS} from 'node_modules/crypto-js/crypto-js.js' // or /aes.js --> same issue

However the import doesn't work correctly as for example

 console.log(CryptoJS);

prints undefined.

I also tried to add the module path in

 System.config({
     // ...
     map: {
        CryptoJS
    }
}

and importing it in my service by

 import {CryptoJS} from 'cryptoJs';

While I'm not sure what I should actually put in SystemJS config, none of the solutions I tried worked.

EDIT I also tried...

// import ... as to overcome no default export
import * as CryptoJS from 'node_modules/crypto-js/crypto-js.js';

but then

 console.log(CryptoJS.); 

gives no AES/whatever method (my editor usually advices which methods I could use via auto-completion)

EDIT 2 now thanks to Thierry and PierreDuc contribution it is clear that typings and module import are unlinked concepts.

However neither of them is working. This is what I've done:

I downloaded CryptoJS typings file, put it in typings/cryptojs/cryptojs.d.ts

Then I added

  /// <reference path="cryptojs/cryptojs.d.ts"/>

to typings/main.d.ts

Then I added cryptojs in SystemJS's map config:

   cryptojs: "node_modules/crypto-js/crypto-js.js"

Finally I tried to import cryptojs in my service by

  import CryptoJS from 'cryptojs'

As far as I see there are 2 issues:

  • typings are not loaded since there is no autocompletion when I try to import the module (I also tried to restart the Angular 2 app). Perhaps I didn't understand how to import external typings?
  • the module is not loaded anyway, I can see that by console.log(cryptojs) (nothing is printed, not even undefined; unlikely my previous attempts)

EDIT 3

Finally I got the import working thanks to Thierry and PierreDuc advice (not sure what went wrong on the first place). However I still have issues with typings.

Despite I put

  /// <reference path="../../typings/cryptojs/cryptojs.d.ts"/>

directly in my service, when I write

  import CryptoJS from 'cryptojs';

just below that line, I get no autocompletion and when I start Angular 2 app over by npm start ; I get the following error and the app doesn't start

  app/services/user.service.ts(6,22): error TS2307: Cannot find module 'cryptojs'.

NOTE: If I add cryptojs to SystemJS config (but not a ) and then write (without any import)

console.log(CryptoJS.AES.encrypt('my message', 'secret key123').toString());

it just works but I'd rather solve the typings + import issues.

like image 206
dragonmnl Avatar asked Apr 21 '16 14:04

dragonmnl


People also ask

Can we use npm modules in Angular?

You can download and install these npm packages by using the npm CLI client, which is installed with and runs as a Node. js® application. By default, the Angular CLI uses the npm client.

What is CryptoJS?

CryptoJS is a growing collection of standard and secure cryptographic algorithms implemented in JavaScript using best practices and patterns. They are fast, and they have a consistent and simple interface.

How do you use CryptoJS in angular 9?

Angular 9 code:import * as CryptoJS from 'crypto-js'; encryptionKey: any = 'secret key string'; let encryptedStr = CryptoJS. AES. encrypt('123456', this. encryptionKey.

Which of the following directory holds all the 3rd party libraries in angular?

appData. The angular-cli key in the generated app should be used for Angular CLI specific data. This includes the CLI configuration itself, as well as third-parties library configuration.


4 Answers

You could try this since the library is CommonJS-compliant in your main HTML file:

System.config({
  map: {
    cryptojs: 'node_modules/crypto-js/crypto-js.js'
  },
  (...)
});

and import it this way:

import CryptoJS from 'cryptojs';

For the compilation part, you can follow the Pierre's suggestion.

Edit

I made some tests and here is the way to do.

  • Install typings for crypto-js:

    $ typings install --ambient crypto-js
    
  • Include the corresponding typings into your ts file:

    /// <reference path="../typings/main/ambient/crypto-js/crypto-js.d.ts"/>
    
    import {Component} from 'angular2/core';
    (...)
    
  • Configure the library in SystemJS in your main HTML file:

    <script>
      System.config({
        map: {
          'crypto-js': 'node_modules/crypto-js/crypto-js.js'
        },
        (...)
      });
    </script>
    
  • Import the library into your ts files:

    import CryptoJS from 'crypto-js';
    
like image 86
Thierry Templier Avatar answered Oct 17 '22 08:10

Thierry Templier


I was able to get CryptoJS working in an Angular2 project generated with angular-cli with the following steps/configuration:

bash

npm install crypto-js --save
typings install crypto-js --ambient --save

angular-cli-build.js

module.exports = function(defaults) {
  return new Angular2App(defaults, {
    vendorNpmFiles: [
      /* ... */
      'crypto-js/**/*.+(js|js.map)'
    ]
  });
};

system.config.ts

/** Map relative paths to URLs. */
const map: any = {
  'crypto-js': 'vendor/crypto-js'
};

/** User packages configuration. */
const packages: any = {
  'crypto-js': {
    defaultExtension: 'js',
    main: 'index.js',
    format: 'cjs'
  }
};

some.component.ts

import * as CryptoJS from 'crypto-js';

This was the only setup that I could get working for both a regular build and a -prod build. I realize this question wasn't specifically about angular-cli, but figured I'd answer it anyways in case it helps someone else.

like image 29
hartz89 Avatar answered Oct 17 '22 09:10

hartz89


The answers import the entire crypto-js library, thus bloating the app if you only use small bits of it.

I want to keep my app as trim as possible, so this is my approach:

install via NPM

npm install [email protected]

systemjs.config.js

System.config({
    map:{
        'crypto-js':  'node_modules/crypto-js',
        ...
    },
    packages:{
        'crypto-js': {main: './index.js', defaultExtension: 'js', format: 'cjs'},
        ...
    }
});

component.ts

//only the core + the modules you need
import CryptoJS from 'crypto-js/core';
import 'crypto-js/sha1';

This has a couple of drawbacks though. The shortcut methods don't work for me:

doesn't work

let hash = CryptoJS.SHA1('abcdefghi'); // CryptoJS.SHA1 is undefined

works

let sha1 = CryptoJS.algo.SHA1.create();
sha1.update("abcdefghi");
let hash = sha1.finalize();

To avoid the compiler error "Could not find module x", I needed to add the following to a custom.typings.d.ts

declare module 'crypto-js/core'

Then link to the typings from my main.ts

///<reference path="./app/custom.typings.d.ts"/>

The main drawback is that the typings mentioned in the other answers don't seem to work with this approach because they are for the whole crypto-js library. For instance, CryptoJS.algo is not recognized. So it really sucks but I don't have intellisense/autocomplete in the IDE

So why put with such a drawback? Whereas the whole library adds about 60kb of minified JS to my app, importing just what I need adds 4.5kb. And that's a win for me.

like image 33
BeetleJuice Avatar answered Oct 17 '22 10:10

BeetleJuice


To install cryptojs package run following command:

npm install crypto-js --save

After completing above installation if you are using webpack/bundles or updated angularjs versions then run following command as well to get the declaration files.

npm install --save @types/crypto-js

In @types of node_modules d.ts files will be added so as to resolve import related error for cryptojs. This worked for me.

like image 24
Neha Tawar Avatar answered Oct 17 '22 09:10

Neha Tawar