How to import external JavaScript into Polymer 3.0 - polymer

Let's say I have a traditional javascript library such as google-charts and I wanted to incorporate that into my Polymer 3.0 project. How would I actually do the import?
This is how I would traditionally do it: https://developers.google.com/chart/interactive/docs/quick_start

ES Modules on NPM
Normally, one would prefer an ES module version of such a library if available (e.g., on NPM), since ES modules allow tree shaking (by Polymer CLI in this case) to reduce the size of the production build output.
Modules are loaded in JavaScript with the import keyword. If available on NPM, the library could be installed in your Polymer project with the npm-install command. For instance, you'd install google-charts like this:
npm install --save google-charts
Then, import that package in your element code:
import { GoogleCharts } from 'google-charts';
Example:
import { PolymerElement } from '#polymer/polymer';
import { GoogleCharts } from 'google-charts';
class MyElement extends PolymerElement {
// ...
ready() {
super.ready();
GoogleCharts.load(/* ... */);
}
}
demo
Non-ES Modules (not on NPM)
On the other hand if ESM is unavailable, the script is likely an AMD/UMD module, which adds symbols to the global scope. In that case, you'd still import the file, and access the global as you normally would had you used the <script> tag.
If the script is not on NPM, you'd have to copy the file locally into your project (and include the library file in your release), and then import the file by path. For example, if you copied the library to <root>/src/libs/google-charts.js, the element code at <root>/src/components/Chart.html would import it like this:
import '../libs/google-charts'
Example:
import { PolymerElement } from '#polymer/polymer';
import '../libs/google-charts' // adds GoogleCharts to global
class MyElement extends PolymerElement {
// ...
ready() {
super.ready();
GoogleCharts.load(/* ... */);
}
}

Related

AudioWorkletProcessor and Polymer 3.4.1 and 'window' not defined

Trying to use lit element/Polymer Web components AND an Audioworklet/AudioWorklet processor, I got this error:
boot-c9e09360.js:20 Uncaught ReferenceError: window is not defined
at boot-c9e09360.js:20:1
at this line in my code:
await aw.audioContext.audioWorklet.addModule("micSpkrAwp.js") //micSpkrAwp is the audio-worklet-processor running in different process.
The boot-c9e09360.js is a polymer file that contains:
/**
#license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
...
*/
/* eslint-disable no-unused-vars /
/*
When using Closure Compiler, JSCompiler_renameProperty(property, object) is replaced by the munged name for object[property]
We cannot alias this function, so we have to use a small shim that has the same behavior when not compiling.
#param {?} prop Property name
#param {*} obj Reference object
#return {string} Potentially renamed property name
*/
window.JSCompiler_renameProperty = function(prop, obj) {
return prop;
};
I have been using lit element/Polymer web components and it works well. I removed the polymer components and the AudioWorkletProcessor works well.
I think that the problem is that Polymer assumes that window is defined (since polymer works with DOM), but when encountering a javascript file - the AudioWorkletProcessor which has no reference to DOM (just a file that provides the audio process interface) this error occurs.
Any suggestions?
Code of micSpkrAwp.js:
import { frameBufferQBRes } from "./queue.js"
import {config} from "./config.js"
class MicSpkrProcessor extends AudioWorkletProcessor {
constructor() {
super()
/** ..**/
process (inputs, outputs, parameters){
console.log(`micSpkrAws - this.stopImmediateFlag ${this.stopImmediateFlag}`)
if (this.stopImmediateFlag) return false
const retVal=this.processFromQueue(inputs,outputs,parameters)
return retVal
}
}
registerProcessor('mic-spkr-processor', MicSpkrProcessor)
Thanks to Kaiido for the solution!
Answer: Polymer scripts got injected into the AudioWorkletProcessor code due to importing :
import { calculateSplices } from '#polymer/polymer/lib/utils/array-splice';
This was not immediately visible since it was a nested import (imported file contained this import statement). This import was removed, and the problem solved!

WebStorm generates bad import paths

My project has this structure:
root/
---tsconfig.json
---app/
------main.ts
---lib/
------public_api.ts
------files/
---------index.ts
---------file2.ts
---------file3.ts
The index.ts file in lib/ is a barrel file that exports all files in ./files:
# index.ts
export * from './file2';
export * from './file3';
The public_api.ts file exports whatever the barrel exposes
# public_api.ts
export * from './files'
Finally, tsconfig has a path alias for all files under lib/ like this:
"paths": {
"lib": ["lib/public_api.ts"]
}
With this setup, from within my app's main.ts I can import my library classes without using the full path:
# main.ts
import { File2Class } from 'lib';
That works well, and my IDE (PhpStorm / Webstorm) will know to automatically generate imports with the path alias when I'm in main.ts.
The problem is that sometimes when I am within a lib/files/*.ts file and I use a class from a sibling file, the IDE will use the same alias, so from within file3.ts It would auto-generate one of these imports:
# file3.ts
import { File2Class } from 'lib';
or
import { File2Class } from './';
This causes a hard to debug compilation error though. The correct import from a sibling file would be:
# file3.ts
import { File2Class } from './file2';
So my question is: is it possible to instruct Webstorm/PhpStorm to never use a parent path and to never import from the barrel in the current or parent directory?

CKEditor 5 throws Cannot read property 'create' of undefined in Angular6 project

I've created a project using JHipster and trying to create a WYSIWYG rich text editor using CKEditor 5. I've done the below steps by using the following link to create an editor.
npm install --save-dev #ckeditor/ckeditor5-angular
npm install --save-dev #ckeditor/ckeditor5-build-classic
Imported #ckeditor/ckeditor5-angular and added in imports in my module.js
Imported #ckeditor/ckeditor5-build-classic and created a variable public Editor: ClassicEditor; in my component
Used following code in html
Blockquote
<ckeditor [editor]="Editor" data="<p>Hello world!</p>"></ckeditor>
When I go to the page I added throws the following error which I got it from the browser developer tools console.
ERROR TypeError: Cannot read property 'create' of undefined
at CKEditorComponent.createEditor (ckeditor-ckeditor5-angular.js?076d:187)
at eval (ckeditor-ckeditor5-angular.js?076d:96)
at ZoneDelegate.invoke (zone.js?d135:388)
at Zone.run (zone.js?d135:138)
at NgZone.runOutsideAngular (core.js?09c9:3784)
at CKEditorComponent.ngAfterViewInit (ckeditor-ckeditor5-angular.js?076d:95)
at callProviderLifecycles (core.js?09c9:9568)
at callElementProvidersLifecycles (core.js?09c9:9542)
at callLifecycleHooksChildrenFirst (core.js?09c9:9532)
at checkAndUpdateView (core.js?09c9:10468)
I'm just wondering if that's an issue with CKEditor 5 or did I miss any steps?
You have the following code under the link:
export class ArticleUpdateComponent implements OnInit {
public Editor: ClassicEditor;
// ...
}
While you should actually set the ClassicEditor to the Editor property, you only set it's type (which is actually wrong too, since the editor can have type typeof ClassicEditor).
What you should do is simple property assignment public Editor = ClassicEditor;, which will make the ClassicEditor available in the template under the Editor property.
This error can be also thrown when the import is incorrect - depending on the TypeScript configuration the import should look like import * as ClassicEditor from '#ckeditor/ckeditor5-build-classic'; or import ClassicEditor from '#ckeditor/ckeditor5-build-classic';.
Created a file src/app/typings.d.ts with below code
declare module '#ckeditor/ckeditor5-build-classic' { // or other CKEditor 5 build.
const ClassicEditorBuild: any;
export = ClassicEditorBuild;}
Inside your main app module, import CKEditorModule as below:
import { CKEditorModule } from '#ckeditor/ckeditor5-angular';
#NgModule({imports: [CKEditorModule]})
Now, add import to the component where that issue was occurring in say x.component.ts
import * as ClassicEditorBuild from '#ckeditor/ckeditor5-build-classic';
export class x implements OnInit { public Editor = ClassicEditorBuild;constructor() { } ngOnInit(): void {}}
Finally, add below code in your x.component.html
<ckeditor [editor]="Editor" data="<p>Hello, world!</p>"></ckeditor>
My solution was roughly the same as above, but as these didn't quite solve it, I tried:
public Editor: any = ClassicEditorBuild;
(adding : any)
which worked
If you have this issue even if you have this:
public Editor = BalloonEditor;
Check if you have in your template any call to the ckeditor component
For example:
<ckeditor formControlName="contenido"></ckeditor>
If you not set [editor]="Editor" it will produce same error.
try declaring this
public Editor: any = ClassicEditorBuild;
and in
file
../../../../node_modules/#ckeditor/ckeditor5-angular/ckeditor.component.d.ts
change CKEDITOR_VERSION: to any from string.

How to troubleshoot es6 module dependencies?

I am developing a React & Reflux app, which is bundled by webpack with babel-loader (v6), and I am experiencing es6 modules dependencies issues
For example, I have a component that use the reflux .connect() mixin :
import MyStore from '../stores/my-store';
const Component = React.createClass({
mixins: [Reflux.connect(MyStore)]
});
When I import all modules individually in each file like this, everything's fine.
I then tried to improve my code by using deconstructed import statements :
...in a component :
//import One from '../js/one';
//import Two from '../js/two';
//import Three from '../js/three';
import { One, Two, Three } from '../js'; // Instead
...and in js/index.js :
import One from './one';
import Two from './two';
import Three from './three';
export { One, Two, Three };
App source code files are more concise using the above technique, because I can import all components in one import line.
But when I use this, some dependencies end up beeing undefined when I use them
If I use the same updated example...
//import MyStore from '../stores/my-store';
import { MyStore } from '../stores'; // Instead
const Component = React.createClass({
mixins: [Reflux.connect(MyStore)]
});
...MyStore parameter ends up undefined in Reflux.connect method.
I tried to troubleshoot in the debugger, but I'm not really aware of what's going on with the __webpack_require__(xxx) statements in the generated bundle. There must be a circular dependency that babel-loader or webpack require could not figure out when there are the index.js files re-exporting individual modules.
Do you know any tool that can help me figure this out? I tried madge but it does not work with es6 modules, and I could not find anything that would tell me where anything is wrong
In order to get extended info about build, run:
webpack --profile --display-modules --display-reasons
It will give you bunch of information for optimisation/profiling.
import statement is used to import functions, objects or primitives that have been exported from an external module.
As per MDN doc, you can import the Modules not the directory.
import name from "module-name";
import * as name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member [ , [...] ] } from "module-name";
import defaultMember, * as alias from "module-name";
import defaultMember from "module-name";
import "module-name";
Reference URL:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
http://es6-features.org/#ValueExportImport
https://github.com/lukehoban/es6features#modules
http://www.2ality.com/2014/09/es6-modules-final.html
As a workaround keep one file as base.js and include all your 3 files.

Can't import any java classes

HelloWorld.ceylon
import java.util { HashMap } //Error:(1, 8) ceylon: package not found in imported modules: java.util (define a module and add module import to its module descriptor)
void run() {
print("test");
}
module.properties
module CeylonHelloWorld "1.0" {
import java.base "8";
}
I get an exception in HelloWord.ceylon file
When I try that code, I get:
Incorrect syntax: mismatched token CeylonHelloWorld expecting initial-lowercase identifier
In module.ceylon.
The name of a module is supposed to be of form foo.bar.baz (initial-lowercase identifiers separated by periods).
Like mentioned by Gavin you will have to use a legal module name, when I change your code to use the module name "java8test" I get the following output when compiling:
$ ceylon compile java8test
warning: It looks like you are using class files from a Java newer than 1.7.
Everything should work well, but if not, let us know at https://github.com/ceylon/ceylon-compiler/issues.
In the near future, the Ceylon compiler will be upgraded to handle Java 1.8.
./source/java8test/run.ceylon:1: warning: import is never used: 'HashMap'
import java.util { HashMap }
^
2 warnings
Note: Created module java8test/1.0.0
Which is all as expected.
module.ceylon
module holaCeylon "1.0.0"{
import java.base "7"; // versiĆ³n 7 JDK
}
package.ceylon
shared package holaCeylon;
Now we go back to the run.ceylon file and import the java.util.HashMap Java library.
run.ceylon
import java.util { HashMap }
shared void run(){
print("Importando librerias de Java en Ceylon");
value romanos = HashMap<String,Integer>();
romanos.put("I", 1);
romanos.put("V", 5);
romanos.put("X", 10);
romanos.put("L", 50);
romanos.put("C", 100);
romanos.put("D", 500);
romanos.put("M", 1000);
print(romanos.values());
print(romanos.keySet());
}
Output:
salida
Code:
http://codemonkeyjunior.blogspot.mx/2015/03/ceylon-interoperabilidad-con-java.html