Adding a script to an Angular Library - javascript

I am trying to export some components of my Angular 6 application into a library. Unfortunately, I need to use a WebToolkit to connect to a proprietary service build by other people, which is only available as a pure javascript file. This file, in turn also needs jQuery and require.js.
Without libraries, I have solved this by adding these js files to the .angular-cli.json under "scripts"
{
...,
scripts: [
"node_modules/jquery/dist/jquery.js",
"node_modules/require/require.js",
"path/to/my/magic/library.js"
],
...
}
Now building my angular library, I would like to have those scripts built into my own library code, such that it can still be used by my customers in the simple manner of performing just one npm-install and importing it in their .module.ts file.
Is that somehow possible with the Angular-CLI 6? Or do you have other suggestions how I can achieve a simple installation of my library?

Provide the reference of your external JS in your angular. json file of main angular project in a script tag and provide the path of your package from your libraries node_modules folder like this. So now you have created the NPM package from your library and you are going to use it in different project
**Add externaljs file**
**Step 1**
Take a file in the assets folder and set any name. Like as custom.js
function getToday() {
alert(new Date().toLocaleDateString());
}
function greetings(name) {
alert(`wellcome ${name}`);
}
**Step 2**
Now add the customjs file reference in the angular.json scripts section array list. Like as below
"src/assets/custom.js"
**Step 3**
Now add the functions reference in a component file. I am using the app component.ts
//external js function declaration
declare function getToday(): any;
declare function greetings(name: any): any;
ngOnInit(): void {
// call the externaljs functions
getToday(); // without param
greetings('rohol'); // with param
}

Maybe isn't the cleanest way to do it but you can achieve this with:
let scriptTap = document.createElement('script');
scriptTag.src = '<route to your scripts>';
document.body.appendChild(scriptTag);
The best way to integrate is creating the library from ng new project-name -create-application=false
then you add the library with ng g library name-of-library
and you will have a clean project to develop your library

Related

Importing JS bundle to an Angular Library

I am trying to add a JS script bundle file to a custom Angular Library which is using features from it. I have added the types files so the linting errors are not showing, but the Project does not get built as classes from JS Bundle are not found.
I have tried and failed importing the bundle to the public-api file.
I am thinking of trying to make the bundle a private npm package to install. But that will take lot of time and effort.
What other options do I have?
Sometimes you could have that kind of circumtances like having would like to use an JS library in your Angular project.
i have encountered something like that but i have created one directive file in the src folder like "type.d.ts" so after i declared my library in it with something like "declare module 'pdfmake/build/vfs_fonts.js';" and at last imported it in my component file like "import * as pdfMake from 'pdfmake/build/pdfmake.js';"
1- Create one directive file like "type.d.ts"
2- Declare your JS library in your recent file created with something like "declare module 'pdfmake/build/pdfmake.js';"
3- Declare back the import statement in your component file like "import * as pdfMake from 'pdfmake/build/pdfmake.js';"

Use Moment.js in extjs project

I'm developing an Extjs project using 6.5.2 version and modern toolkit, i want to use https://momentjs.com/ package but i couldn't import the node_dependency.
The Momentjs page has the downloads or install methods, but if i download the code, where i want to use whatever method, this throw an exception and if i install the package using 'npm install moment --save' command, i don't know how to import and call it.
Someone can help me importing this dependency in extjs.
#Carlos You can do by adding script tag in the index.html file as suggested by Akrion.
Another way -
Inside app.json file you can add following inside js [] -
"js":[
{
"path": "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js",
"remote": true
}
]
Once this is added then you need to do sencha app refresh or sencha app build.
Then in the application code you can use it like following -
var welcomeText = 'Welcome to Sencha Fiddle! Today is: '+ moment(new Date()).format("MM-DD-YYYY");
Ext.Msg.alert('Welcome message',welcomeText);
Another approach would be to Ext.mixin.Mashup mixin.
This mixin allows users to easily require external scripts in their
classes. This load process delays application launch (Ext.onReady)
until all such scripts are loaded ensuring that your class will have
access to its required scripts from the start.
So you could have an Moment.js adapter class, like so:
Ext.define('MomentjsAdapter', {
mixins: ['Ext.mixin.Mashup'],
requiredScripts: [
'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js'
],
...
});
I like this very much, because you keep the external dependency close to the place where it's used. Which is very handy when you might want to remove the dependency or reuse it in a different place/project.

Using a node module in my Angularjs app

I have come across a few modules i would like to use in my Angular app but am at a crossroads on how to make work in my angular app as i will need to "require()" in my factory file.
Heres the node module im interested in: https://github.com/TimNZ/node-xero
On this current project i am using Gulp Angular in Yeoman to generate my boilerplate and am having a hard time figuring out how i should make this work if i need to modify any of the gulp scrips.
I was thinking i can just "Browserify" the single file that will use require() but is this the wrong approach? should i just browserify all the project files? is this standard practice?
Any advice is appreciated, currently has me at a stand still.
All the modules i want to use in relation to Xero all seem to be node modules.
The simplest starting point would be to use Browserify to build a standalone bundle that uses a global of your choice.
To do this, you could create a JS file that requires the node module(s) you want to use. You could create a file named bundle-index.js with this content:
exports.xero = require('node-xero');
You could then run this command to build a standalone module:
browserify --standalone the_global bundle-index.js > bundle.js
Where the_global is a name you find appropriate for the global object that will contain the exports. With the bundle.js file included in a script element, you would be able use it like this:
var privateApp = new window.the_global.xero.PrivateApplication({ ... });
Doing things this way would involve the least amount of disruption to your current project. And if you are only needing to use Browserify to require third party libraries that don't change frequently, you could start with a simple manual process for building the standalone bundle.
Note that you can export other required modules by adding additional exports to bundle.js:
exports.xero = require('node-xero');
exports.someOtherModule = require('some-other-module');
(function(){
var xero = require('node-xero');
angular
.module('app')
.factory('myFactory', myFactory);
function myFactory(){
var helper = {
myMethod: myMethod,
};
return helper;
function myMethod(){
xero.doStuff();
}
}
})();

Drupal 8 Multiple Custom Modules Using Same External JS Lib (e.g. Angular)

I've been pulled onto a Drupal 8 project with multiple custom modules that need to use Angular.js. What is the best way to provide the Angular files to each module?
Right now, each module references the remote Angular files hosted by googleapis.com in my-module.libraries.yml.
my-module:
version: 1.x
js:
https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js: { type: external, minified: true }
https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular-sanitize.min.js { type: external, minified: true }
js/my-module.js: {preprocess: false}
dependencies:
- core/jquery
- core/jquery.ui
- core/jquery.ui.accordion
However, I would prefer to host the Angular files locally and list them as dependencies just like jQuery.
I know I could put the Angular files in the module itself, but then each module would need its own copy.
Whatever is the proper way to do it, my goal is to host the Angular files locally and reference them from each module that depends on Angular.
The simplest way to solve this is to add a /libraries folder at the root of the Drupal project. Then create a sub-directory for each external library you are using, and reference that from your module.libraires.yml file.
For example, I created /libraries/angular/js, placed the files in there, and then referenced them by starting with a / in the code below.
my-module:
version: 1.x
js:
/libraries/angular/js/angular.min.js: {}
/libraries/angular/js/angular-sanitize.min.js: {}
js/my-module.js: {}
dependencies:
- core/jquery
Now any module within the project can reference the same files.

Bundling a reusable library with systemjs builder

My brain has melted trying to bundle code for a reusable library and I need someone to steer me back on the path.
I've written a library in TypeScript that I want to reuse in multiple projects using jspm.
It has a single entry point file called Index.js which exports just one class I want to expose (Class1).
Index.js
export { Class1 } from "./Classes/Class1";
The problem is that when I bundle this to a single file using systemjs-builder it dumps all of the dependencies in there.
Build output:
System.register("Classes/Class2.js", [], function(exports_1) {
});
System.register("Classes/Class1.js", ["Classes/Class2.js"], function(exports_1) {
});
System.register("Index.js", ["Classes/Class1.js"], function(exports_1) {
});
I don't believe an SFX bundle is suitable because I want to load this with systemjs, so there are a few things here I don't understand.
I don't want to expose class2 (it's just a dependency of class1) - but it looks to me from the output like anyone could just require it if they wanted to.
What about module ID clashes? What if I have another 3rd party library that also defines a Classes/Class1 module?
What I essentially want is a single file that exports only the modules I require and nothing else and is namespaced so that it doesn't clash with any other libraries. How can I achieve this?

Categories