Use MUX Player (Video) in Angular 14/15 - javascript

Mux is a video API service that has its own player: MUX Player
I am wanting to use this npm package in Angular 14/15 by importing it into a specific component only. The js should only be loaded when this component is loaded.
Import
The two methods of using the service are:
via a direct <script src="https://unpkg.com/#mux/mux-player"></script> import in the HTML (which I can do in angular's index.html file. This does however mean that the script is loaded for everyone, which is not what I want.
npm Package #mux/mux-player
Usage
Add the code to a component's HTML where the script or npm package has been imported.
<mux-player
stream-type="on-demand"
playback-id="FuJSYrK0014ec2LPnm11bzC2MAySAQPqA"
metadata-video-title="Tea and Cookies"
metadata-user-id="user-24601"
/>
Making sure to also include schemas: [CUSTOM_ELEMENTS_SCHEMA] in the module (or standalone component).
Problem
Angular can be a bit weird about untyped packages. I think that this package uses typescript, but in any case, importing the npm package gives me plenty of errors. Essentially, it's not being loaded because Angular is tree-shaking it out when I am not using the imported class in the components' ts. This means that on load, I am seeing:
Cannot find module '../../../types/mux' or its corresponding type declarations and Property 'error' in type 'MuxVideoElement' is not assignable to the same property in base type 'CustomVideoElement<HTMLVideoElement>'. Type 'MediaError' is missing the following properties from type 'MediaError': MEDIA_ERR_ABORTED, MEDIA_ERR_DECODE, MEDIA_ERR_NETWORK, MEDIA_ERR_SRC_NOT_SUPPORTED
What I've tried
To confirm that the <script> import and HTML code work together, I imported the script into the index.html, and this removed all errors and the player loaded fine.
I have tried importing the npm package import MuxPlayerElement from "#mux/mux-player";, and added declare module "#mux/mux-player"; to the typings.d.ts.
Import the package into the component, and tried to declare the #ViewChild template ref as a MuxPlayerElement, to get around any tree-shaking.
There is an Angular demo where it says "This player? It's an open book." at https://www.mux.com/player, however, this results in the error Only void and foreign elements can be self closed "mux-player". Easy solution to this is to close the tag with </mux-player> rather than .../>

Related

How to tune babel loader to properly import a module named macro.js when using CRA

I'm using a library vtk.js. VTK has a special design of classes (https://kitware.github.io/vtk-js/docs/develop_class.html). When I write a class I need to import macro.js module which exposes several base methods such as getters/setters/newInstance etc (https://github.com/Kitware/vtk-js/blob/master/Sources/macro.js).
Looks like CRA uses some special loader for macro.js files. I get an error when trying to import such a file (SyntaxError: Cannot use import statement outside a module). If I copy an original file macro.js from #kitware/vtk.js to my local source folder I still get an error. Even if I remove all the contents of macro.js file I get an error (The macro imported from "../macro" must be wrapped in "createMacro" which you can get from "babel-plugin-macros". Please refer to the documentation to see how to do this properly: https://github.com/kentcdodds/babel-plugin-macros/blob/master/other/docs/author.md#writing-a-macro). However, when I rename macro.js to macro2.js the error is gone.
Is there some way how can I disable this macro loader?

Text to speech for Angular apps - "allowJs is not set" issue

I'm having trouble integrating this speech-to-text package into my Angular app. I've added the import statement:
import spoken from "../../../node_modules/spoken/build/spoken.js";
My project is able to find the spoken.js module but it tells me that "allows is not set".
If I set that value to true in my tsconfig.json file, I then get multiple .js related errors in other files, and I'm unable to build the project. Has anyone encountered something like
this before?
If you want to import the module at runtime but not check it with TypeScript, try removing the .js extension from the import path.
One way would also be to disable type checks for JS files via "checkJs": false in your tsconfig.json.
Or you could also include the file in scripts array in angular.json file and in your controller, just declare that variable:
declare const spoken: any;
(feel free to use something more specific instead of any :])

Using a static script tag in a React component

I'm using the default starting project from create-react-app, with the following folder structure:
app
--public
----index.html
--src
----App.js
----components
-------map.js
I have included an external CDN library in the index.html body tag. However, I'm confused about how to use the methods of this library in my map.js component.
Just writing the library methods in my map.js, returns:
Failed to compile
./src/components/map.js
Line 5: 'L' is not defined no-undef
Is there any way I can include a JS CDN library in my React components without actually importing the library as React Component via npm install?
You're loading a component in the DOM, React has no knowledge of the DOM. So you need to create a wrapper component for the DOM library and use the ref prop to access it. If you're a beginner please use React libraries exclusively, if you need third party libraries, start by reading the React docs https://reactjs.org/docs/integrating-with-other-libraries.html about third party libraries.
Btw, the error you're seeing is most likely a babel error which can't transform your ES6 classes, it can't find the library you require. I think there are options to configure global environment, so it ignores these errors (but that probably means ejecting from cra).
Take a look at this link:
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#using-the-public-folder
To reference assets in the public folder, you need to use a special
variable called PUBLIC_URL.
Inside index.html, you can use it like this:
Only files
inside the public folder will be accessible by %PUBLIC_URL% prefix. If
you need to use a file from src or node_modules, you’ll have to copy
it there to explicitly specify your intention to make this file a part
of the build.
When you run npm run build, Create React App will substitute
%PUBLIC_URL% with a correct absolute path so your project works even
if you use client-side routing or host it at a non-root URL.
In JavaScript code, you can use process.env.PUBLIC_URL for similar
purposes:
It will show you how to do it the way create-react-app prefers.

Attempting to load a JavaScript sdk into an Angular2 application. Can't find all dependencies

I'm attempting to make use of this library: https://github.com/MagicTheGathering/mtg-sdk-javascript in an Angular2 application.
Unfortunately, I've been going in circles trying to load it into my application.
Firstly, on the TypeScript side if I import it using:
import { } from 'mtgsdk';
there are no types to load into the {}.
If I attempt to load it using something similar to:
import * as mtg from 'mtgsdk'
I'm unable to because it says that it's unable to find a module named mtgsdk.
I've installed the module using
npm install --save mtgsdk
Also, npm installs work fine for other modules.
The application compiles fine if I load it in using require via something similar to this:
var mtg = require('mtgsdk');
Taking that approach, I'm able to compile and launch but in the browser I get a number of errors about modules that it can't find. I figure they are prerequisites for the sdk that didn't get loaded so I start bringing them in via package.json.
For every one that I bring in, I then have to go to systemjs.config.js and add an entry pointing to the module's entry point and often have to specify a default extension using blocks like this:
pointer
'mtgsdk': 'npm:mtgsdk/lib/index.js',
'request-promise': 'npm:request-promise/lib/rp.js',
'ramda': 'npm:ramda/dist/ramda.js',
'emitter20': 'npm:emitter20/index.js',
'bluebird': 'npm:bluebird/js/browser/bluebird.js',
'request': 'npm:request/index.js'
default extension
'request-promise':
{
defaultExtension: 'js'
}
I'm not sure if that's the right approach though because the more dependencies I add, the more that I end up requiring. At one point I had literally gotten up to 50 extra dependencies added because every time I launched, the browser console would find more that were needed.
Is there any easier way to load all of these in?
Also, some of them (such as tough-cookie and request-promise-core) were very problematic to load and I couldn't get the browser console to stop complaining about them. Finally, some of them seemed very basic such as url, http, https. Those seem like they should already be present.
Using systemjs was utilized in the previous versions of Angular 2, However Angular 2 has evolved to Angular 4, with super new features like Angular CLI.
I recommend your use Angular CLI, with #angular/cli.
Importing Node modules
Since mtgsdk is a node-module, you can easily import it using
import * as mtg from 'mtgsdk'
However for your program to compile, you must install a type definition for it. or declare one for it in /typings.json or your app might not build.
Importing Client Scripts
For client scripts like firebase.js you won't need to add client scripts as entries in systemjs.config.js again.
Using #angular/cli, you would easily add them in the scripts[] array in your angular-cli.json for automatic compilation.
Then access them like this
declare const firebase: any;
Here is a quickstart tutorial to set up Angular with #angular/cli.

Why angular2 sources don't have typescript files in sources [duplicate]

When I work with angular2 code I often need to see the implementation of a class, let's say the Router class.
If I click on the Router type in my IDE WebStorm, e. g. inside the constructor of another class
export class myClass {
constructor(private router: Router) {}
// ...
}
my IDE takes me to the TypeScript definition file router.d.ts inside my node_modules folder. What I want is it to take me to the original router.ts file with the implementation of the router class, not just its definition.
The original .ts file is not included in the node_modules folder structure when you get angular2 from github via the standard package.json suggested in the Angular2 Quickstart. Currently, I have to look up the original code in the official github repo.
Any ideas how to get the .ts files into my node_modules/#angular folder instead of the .d.ts files?
Sadly, it's not possible since no TS files exist. Even if you add them it still not possible since you import real angular paths which always point to the definition files. On top of that the file structure of the project does not correlate to the structure of the import string literals.
Some background and more information
The NPM package does not include .ts files, this is by design from the angular team. Up until some time ago the .ts files were indeed supplied with the NPM package.
The reasoning for removing them is to disable abuse from users accessing private classes and #internal and private APIs which is public methods/properties in the API that are not supposed to be public but must be so other angular internal classes can use them.
We used to see a lot of code samples out there doing things like import { PromiseCompleter } from 'angular2/src/facade/lang'; (before RC0) but this was changed when the project structure had a big structure refactor in RC0. This abuse was wide and it's bad, very bad... For users and for Angular PR.
The Angular project has a complex and robust build process where all of the API is moved from .ts files into d.ts files using an automated process that limits exposure. (public_api_guard)
The end result is d.ts files only.
It's also not possible to clone the git repo and use it since, again, the file structure is way way different so imports will have to change. Most importantly without the build Angular will, most likely, not work.
A solution using a different approach
However, if you debug your app you notice that you reach actual angular core .ts files in the source view of the console, this is because the NPM package comes with source map files that include the whole TS source code. Nice trick they did there.
This is what I use to dig deep into angular, it works quite great and I get a lot from it.
It's not as nice as Goto Declaration but it something...
IMO it's also easier to understand when you step through code...

Categories

Resources