I'm building a Web app in Angular that needs to make calls to functions from an existing project written in pure Javascript. The original Javascript code will be used as more of a library, as it contains astronomical data that is too large to rewrite in its entirety. I have my project set up with components within an app root within the src file. I'm looking to call and define variables using functions from the original javascript, but I have no idea where to begin.
ORIGINAL JAVASCRIPT
MY PROJECT SETUP
Two posible solutions with AngularCLI:
1) put the script file path/name reference in the scripts array of the angular-cli.json file. When your app is built, those script files (and css files in the styles array) are placed into script tags automatically for you. It is then available globally.
2) if there is an NPM package available for the third party solution, then npm install packagename --save then require() or import that module where you need it in Angular.
Related
I have been looking for a way to mostly share some code between projects specifically for SPFX and fluent ui. We found 3 main ways to do that.
1.
Creating a component library is the way that seemed least complicated cause it uses the same infrastructure and do all building without the need to configure it.
But this adds some issues, we need to built and manually link the solution locally to make it work, this will also work if we put in a repo. so this is mitigated.
The second is that implicitly this will also require the fluent ui and react. Plus having to place it inside a SPFX component library project.
2.
I saw some promise using paths in ts and this works fine while using the ts compiler. It will go to the folder that your proj is referring and build it at calling time. which is great. But it did not work in SPFX.
3.
Another way was to have a post install to sync the folders which seems easy enough but I wonder how practical this is plus how people are doing it, if they are, how.
All I wanted to figure out now is a way to take my component code and share as if they were in a folder of my src or a simple extension of the code. No need to have extra dependencies or build steps, just the code that can be used as a ts/tsx file. ex:
shared lib:
//assuming I have react and fluentui already installed for the project.
import button from 'fluentui';
export const fancyCustomButtom = (props) => {
return (<Button text="Standard" />);
};
src project folder:
import {fancyCustomButtom} from 'shared-lib'
It is fine if it needs to build the files before we can use it but can we do it at build time or when the package is installed? also wouldn't it increase my bundle size by making both module dependent on things already available (react, fluentui)?
Given the way Microsoft have architected the loading of bundles in SharePoint and Teams - I believe an SPFX component library is the best way to share code between different solutions, particularly if you are looking to minimise bundle size...
Imagine you have a library for something re-usable: a form, a set of standard branded components - something of that nature. You could put your shared code in repos and add references to it - either by publishing your own repo publicly or using the npm install git+https://yourUrl syntax; but what effectively happens there is that your code is pulled down in to node_modules for each project, and any referenced module code is included in your bundles. If you have two, three, four or more webparts on the same page - using those same libraries, you're multiplying how many times that code is included on the page.
If you follow Microsoft's guide on setting up a component library project however, your npm link commands allow your types to be recognised in consuming projects without needing to actually include the bundled distribution code. You can deploy your library code once to the App Catalog, and if it's referenced in other solutions -- it's loaded on pages as needed: once.
I have found the development experience to be quite flaky at times, but it does work. When I run gulp clean on my library code, or come back to it after some time, I sometimes find that I need to run npm link and npm link my-project-name again as per the instructions in the above tutorial. Whenever you run gulp build on your library, you should also rebuild the project that consumes the library, either by using gulp build / bundle or by saving a file (if you're running gulp serve). This process works well for developing, and once it comes time to deploy, all you need to do is add a named reference to your library inside package.json and then deploy both .sppkg files to your App Catalog.
In terms of your last question re: bundle size - react is not actually included in the dependencies for an SPFX library project, but you will find it's available to use. When you build your library, if you take a look in the generated javascript in your dist folder, you will see it's listed as one of the dependencies for the webpacked content along with react-dom and ControlStrings. It's on line 1.
office-ui-fabric-react is included as a devDependency thanks to the #microsoft/sp-webpart-workbench package that gets scaffolded with all SPFX projects - and if you check your library's dist javascript, you will see that included components are being webpacked and included in your bundle. I'm not entirely sure if when you pull this code in to your consuming project, whether webpack then tree-shakes to de-duplicate and ensures only necessary code is included: I don't know. Someone else may be able to illuminate us there or provide a more accurate explanation of what's going on... I will update this response if anyone comments to let me know.
And finally, this is more of a personal way of working, but it may be worth consideration:
When developing a library, I sometimes reference it in other projects via a local npm install ../filepath command. This ensures that when I install the library as described, the consuming project installs any necessary dependencies. I'm able to tweak both projects if I need o. When it comes time to deploy, I commit my changes to both projects, deploy my library code to the App Catalog, and then npm uninstall the library from the consuming project and add a reference as described in the above tutorial. When I deploy projects that use my library, they just work.
I recently developed a library that uses pnpjs, in particular the #pnp/sp library that is used to talk to SharePoint. If you look at the Getting Started guide for that library, they expect you to pass a reference to your Application Customizer or Web Part context during setup, or explicitly set things up using a base URL and so forth - and of course, a library doesn't really have a page context of any sort - the whole point of this code is that it's reusable. So that poses a challenge. My solution was to do the setup in the consuming web part(s) and ensure that they pass a reference to the sp object (which is of type SPRest) to any code or components that exist in my library. My library has peerDependencies on those pnp libraries so that the code isn't duplicated in consuming projects. Sometimes you have to think about what your library needs to include in its bundle and what you expect consuming solutions to already have, and maybe find ways to ensure things aren't included that aren't needed.
For example, in the scenario you talk about, you may want to ensure fluentui or office-ui-fabric-react are only devDependencies or peerDependencies for your library. As long as your library and the project(s) consuming your library both use the right version(s) you shouldn't have any trouble, and you can document any pre-requisites with your library documentation. You can check which versions of these libraries are installed per the SPFX version you are currently using ie. SPFX v1.11 or v1.12 etc. Just run npm ls <packagename> to get a breakdown, or check your package.json file.
Basically I have a number of legacy web applications that reference and use a library from a CDN (Kendo UI). I have a task to remove such requests to remote hosts and so I'd like to encorporate the library into an existing npm script task that collects all dependencies into a single local js file which the application references.
The problem I'm having is that this library does not provide pre-compiled js files that can be used immediately (unlike other libraries such as jquery or angular), but it is modularised and requires webpack or browserify to use it.
Since our legacy applications do not use the modular approach to loading dependencies, and I have no scope to rewrite them, I would like to somehow package the modularised library into an equivalent js file that will load the library so my application can access it simply via a <script> reference to it.
I have tried using browserify to compile from a source js file that contains simply a require reference to the library, but then referencing the compiled file in my application results in an error as the library's functions are not available to my application.
Can anyone point me in the right direction?
If your using some library's that are module based, and you want to use them standalone, you will need to do 2 things.
expose the module to the global scope. Maybe using the expose loader https://github.com/webpack-contrib/expose-loader or even just assign to the window object.
If the modules are also using a library that your also including standalone, you need to tell webpack about these,.
eg.
{
externals: {
jquery: 'jQuery'
}
// other stuff..
}
Finally when you include these, remember the ordering of your script tags. eg. make sure you include jquery before your bundled javascript.
So I am working with a couple of different Angular starter kits, but I have yet to find one that automatically puts in the script src, for the vendor resources such as angular formly, bootstrap, etc., in the index.html. I am trying to make it so my dependencies in my module can work.
Anyone know of any good grunt or gulp build that would take care of this?
I believe grunt-wiredep is what you are looking for. It will inject your bower dependencies into your 'index.html'.
however if you are trying to include JS dependencies into a stand-alone angular module meant to be used with different HTML applications, you will need to concatenate those dependencies into a single deployable JS file. This can be easily done with grunt-contrib-uglify.
I'm putting together a solution with Node, Express and Angular. I've installed the node Angular package, but I'm not sure how to properly reference the library in my html. Do I need to configure a custom route outside of the public folder to achieve this?
Ideally, i'd like a solution that is analogous to the ASP.Net script bundle, where I can reference a named bundle, or Node script module in my html.
Edit
What I'm specifically trying to build right now is a test harness page that allows me to visualize Mocha unit tests, which necessitates client side script references to Mocha, Chai and Angular. It doesn't seem that keeping redundant copies of these libraries, or using a CDN reference for just the client side html is clean.
What is the best way to do this in Node?
The angular module in npm is for using angular server-side via jsdom. If you need it client-side for browsers, just download a copy from angular's website.
The only other way you could include the angular npm module client-side is if you were using browserify, which would also work.
I have 2 projects. They use same js/img files. When I change js content in first project I should also change it in second project. I wanna make it as dependency. So I deploy changes to my local repository, then goto project1/project2, call update and changes are loaded.
I have tried to use bower but it doesn't satisfy me because of some strange behaviour (it copies whole folder content and ignores main section in component.json)
How can I implement normal dependency managment in my project? note: I need to manage my local dependencies
The main property in component.json is currently only used for other tools using Bower. There is currently a discussion going if Bower should have a .bowerignore file for ignoring files it doesn't need.
You might be better of just using a git submodule or symlinking the files.
Alternatively you could check out if any of the other JS package managers fills your need: npm, Ender, volo, component, jam
Another option (if you just want to fetch single files) might be: pulldown.
Configuration is extremely simple and you can easily add your own files/urls to the list.