How to use vaadin-text-field in script module - javascript

I have tried to use vaadin-text-field in a script module, but it fails with the following message
Uncaught TypeError: Failed to resolve module specifier "#vaadin/vaadin-lumo-styles/color.js". Relative references must start with either "/", "./", or "../".
Now I know that "Bare" import specifiers aren't supported in ES6
But is there a way to make this work without hacking on the component's imports.
I mean locally of course
Here is my code :
<!doctype html>
<html>
<head>
<!-- Polyfills only needed for Firefox and Edge. -->
<script src="node_modules/#webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
</head>
<body>
<script type="module">
import {PolymerElement, html} from './node_modules/#polymer/polymer/polymer-element.js';
import './node_modules/#vaadin/vaadin-text-field/theme/lumo/vaadin-text-field.js';
class MyElement extends PolymerElement {
static get properties() { return { }}
static get template() {
return html`
<vaadin-text-field></vaadin-text-field>
`;
}
}
customElements.define('my-element', MyElement);
</script>
<my-element></my-element>
</body>
</html>
Note: I am using server to serve the file not polymer CLI

I found that serving the file with polymer serve is the fastest way to solve the problem.
According to Polymer's Documentation
The browser accepts only one kind of module specifier in an import
statement: a URL, which must be either fully-qualified, or a path
starting with /, ./ or ../. This works fine for importing
application-specific elements and modules:
However, it's challenging when you're writing a reusable component,
and you want to import a peer dependency installed using npm. The path
may vary depending on how the components are installed. So Polymer
supports the use of Node-style named import specifiers
Where #polymer/polymer is the name of the npm package. (This style of
specifier is sometimes called a "bare module specifier".)
These module specifiers need to be transformed to paths before they're
served to the browser. The Polymer CLI can transform them at build
time, and the Polymer development server can transform them at
runtime, so you can test code without a build step. Many third-party
build tools, like WebPack and Rollup also support named modules.

Related

"Error resolving module specifier" danfojs

I was able to use danfojs using
<script src="https://cdn.jsdelivr.net/npm/danfojs#1.1.2/lib/bundle.min.js"></script>
However, the .js file is too big (over 6MB) for production so I need some help with dead code elimination.
I read that webpack's tree-shaking is good for eliminating dead code
I therefore "npm install danfojs" per the official documentation.
In my html file, I tried to do a ES6 import
<script type="module">
import * as dfd from 'danfojs';
import { readCSV, DataFrame } from 'danfojs';
</script>
In Firefox, when I load the webpage, it throws an error of
Uncaught TypeError: Error resolving module specifier “danfojs”. Relative module specifiers must start with “./”, “../” or “/”.
Any help getting the import running OR doing dead code elimination in another way would be much appreciated.
The folder structure is like this, based on a flask project
root
node_modules
danfojs
app
templates
home
webpage.html

"Import" using ESM from CDN throwing errors (Picmo)

I am trying to install the Popup picker from Picmojs but I am limited by the following:
I can't modify any file as I am integrating the code in a co-code builder (no access to index.js,..) but can host files
I can't use NPM nor Yarn as I am working in the browser
Here's what the documentation says
Use ESM from CDN You can also import the ESM version of PicMo
directly. You will first to create an ES module that imports PicMo:
index.js import { createPicker } from 'https://unpkg.com/picmo#latest/dist/index.js';
createPicker(...);
Then you can import the local module from a script tag:
<script type="module" src="index.js"></script>
I indeed tried in a Fiddle (even without the script that as I didn't understand this part) and it seems to be working all fine: Link to Fiddle
However, this relates to the createPicker function, but I'm interested in the Popup picker and therefore need the createPopup function.
According to their documentation:
A popup picker is not displayed until it is triggered by clicking on a
popup trigger, usually a button.
To use a popup picker, you must first install the #picmo/popup-picker
package. This package contains the createPopup function.
createPopup(pickerOptions: PickerOptions, popupOptions: PopupOptions):PopupPickerController
-> I don't know how to "first install the #picmo/popup-picker package".
Here's what I tried based on the previous working example:
import { createPopup } from 'https://unpkg.com/#picmo/popup-picker#latest/dist/umd/picmo-popup.js';
Link to Fiddle
But I always get the same error: "<a class='gotoLine' href='#43:10'>43:10</a> Uncaught SyntaxError: The requested module 'https://unpkg.com/#picmo/popup-picker#latest/dist/umd/picmo-popup.js' does not provide an export named 'createPopup'"
Any hint for me? I'm really stuck on this part.
You're trying to use the UMD version of the library, but you can't use UMD with ESM.
Based on your URL, I tried https://unpkg.com/#picmo/popup-picker#5.4.0/dist/index.js which gave me this error:
TypeError: Failed to resolve module specifier "picmo". Relative references must start with either "/", "./", or "../".
That tells us that the file uses import ____ from "picmo", which won't work in the browser without an import map. If your target browsers support them, we can do that like this:
<script type="importmap">
{
"imports": {
"picmo": "https://unpkg.com/picmo#5.4.2/dist/index.js",
"#picmo/popup-picker": "https://unpkg.com/#picmo/popup-picker#5.4.0/dist/index.js"
}
}
</script>
<script type="module">
import { createPopup } from "#picmo/popup-picker";
console.log(typeof createPopup);
</script>
...but sadly as I write this import maps are just supported by Chromium-based browsers like Chrome, Edge, and Opera, not Firefox or Safari.
If you need to target those as well, the import ____ from "picmo" would seem like an insurmountable barrier, but unpkg.com has a feature to "expand" bare imports. From the unpkg home page:
Query Parameters
?meta
Return metadata about any file in a package as JSON (e.g. /any/file?meta)
?module
Expands all “bare” import specifiers in JavaScript modules to unpkg URLs. This feature is very experimental
And indeed, adding ?module to that URL to ask unpkg to do that for us works:
<script type="module">
import { createPopup } from "https://unpkg.com/#picmo/popup-picker#5.4.0/dist/index.js?module";
console.log(typeof createPopup);
</script>
Since that imports picmo, you'll want to watch the network tab to see what exact URL is used to import picmo and use that if you need to import it in your code (so you're getting the same instance). For instance, when I did that just now it requested https://unpkg.com/picmo#%5E5.0.1?module and got a redirect pointing to https://unpkg.com/picmo#5.4.2?module which also returned a redirect pointing to https://unpkg.com/picmo#5.4.2/dist/index.js?module. That would suggest you want to import picmo from https://unpkg.com/picmo#%5E5.0.1?module (the first URL, since that's what the JavaScript engine will have seen), but you'll need to experiment to be sure.
All of that aside, it's well worth dropping them a note asking whether this is really how you should do it and/or asking for a way that doesn't rely on a "very experimental" feature of unpkg.com.
(Source #joeattardi from Github)
You're using the UMD version of the module with an import statement. This won't work; only ES modules work with imports. UMD modules are loaded with a script tag.
But then you are mixing an ESM import (your import of the main picmo package) with a UMD, which won't work either.
Two options:
Use the UMD version of the base picmo package as well, both loaded with script tags.
Use the ESM distribution of #picmo/popup-picker from unpkg. Note that you will need to add ?module to the URL, otherwise your browser will likely give an error about an invalid relative path. If you do it this way you don't need the picmo import since the popup module imports it.
So for the ESM route, you need just a single import:
import { createPopup } from 'https://unpkg.com/#picmo/popup-picker#latest/dist/index.js?module';

Importing web component without module bundler

I am trying to follow these instructions for using web components. I installed the polymer paper-button with npm install --save #polymer/paper-button, addded the below to my index.html and opened it with vscode's live-server. But I get a console error saying: Uncaught TypeError: Failed to resolve module specifier "#polymer/iron-flex-layout/iron-flex-layout.js". Relative references must start with either "/", "./", or "../".. I would like to solve this without using a module bundler like webpack.
<script type="module" src="node_modules/#polymer/paper-button/paper-button.js"></script>
...
<paper-button raised class="indigo">raised</paper-button>
A workaround I have found is to instead use https://unpkg.com/ as per below:
<script type="module" src="https://unpkg.com/#material/mwc-button#latest/mwc-button.js?module"></script>
Note: you need to add the ?module parameter to the end of the URL in order for unpkg to fix the bare module syntax within the file requested otherwise it just returns the original file with bare module imports.
The error you're getting refers to the inability of browsers - even those that support ES modules - to resolve bare module imports (import foo from 'bar';).
Yes, here:
↓
<script type="module" src="node_modules/#polymer/paper-button/paper-button.js"></script>
you're importing by relative path but paper-button in turn is importing other modules by bare specifier:
paper-button.js:11:1
import '#polymer/iron-flex-layout/iron-flex-layout.js';
To know more about modules in the browser and the reasons behind the lack of support for bare specifiers I would recommend this article by Damien Seguin.
You don't necessarily need a module bundler to be able to launch the application: polymer serve, Polymer's dev server, resolves module specifiers automatically. Also, Polymer CLI's build command may be of help if you don't want to manually configure a build system or alternatively tools like Babel can help you transform imports without bundling.

Importing ES2015 module in Safari DP requires file extension

I'm currently testing ES2015 coverage on Safari Developer Preview (which claims to support 100% ES2015, modules included).
I've made a simple test, using the same syntax I've been using regularly when developing using ES2015 code (along with Babel.JS for transpiling and Browserify for bundling).
Unexpectedly my code wouldn't work without including the .js extension in the import statement. Is that standard behavior? I thought you could omit that.
/* filename: scripts/alert.js */
export default class Alert {
constructor(message) {
this.message = message;
}
show() {
alert(this.message);
}
}
// Another file
/* filename: scripts/index.js */
import Alert from "./alert.js"; // this won't work if I change it to 'import Alert from "./alert";'
(new Alert("Hello, World!")).show();
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>ES2015 Modules</title>
</head>
<body>
<h1>ES2015 Modules</h1>
<script async="async" type="module" src"scripts/index.js">
</script>
</body>
</html>
Unexpectedly my code wouldn't work without including the .js extension in the import statement. Is that standard behavior? I thought you could omit that.
It's not the browser's job to second-guess what that resource specifier means to the server. You can certainly configure your server to respond to the GET without the .js by delivering a matching file that has .js, but that's server configuration.
There's likely to be evolution in this regard. For instance, right now the spec requires that a module resource specifier start with either / or ./. This is specifically so that...
...in the future we can allow custom module loaders to give special meaning to "bare" import specifiers, like import "jquery" or import "web/crypto". For now any such imports will fail, instead of being treated as relative URLs.

How to consume NPM packages in the browser with TypeScript?

This is my setup:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="../node_modules/systemjs/dist/system.js"></script>
<script src="../node_modules/lodash/index.js"></script>
</head>
<body>
<script>
System.config({
packages: {'js': {defaultExtension: 'js'}}
});
System
.import('./js/app')
.catch(console.error.bind(console));
</script>
</body>
</html>
app.ts
import {_} from 'lodash';
export class App {};
When I try transpiling TypeScript into JavaScript I get the error below:
error TS2307: Cannot find module 'lodash'.
What's the most standard/recommended way of loading a NPM packing into your project when using TypeScript?
Notes
node_modules is accessible and the file node_modules/lodash/index.js is being served correctly.
I'm trying not to use Bower because I find it should be done with NPM instead.
I'm using SystemJS which I believe is an universal module loader.
First off, typescript can't find your module because you need to put the typings in your file. Second, you need to export your typescript using the --module system flag (or equivalent in tsconfig.json). And third it needs to be loaded using systemjs. I would highly recommend you use JSPM for this, I know I know - another package manager, but it's more of an extension on NPM than anything else. It allows you to manage your Systemjs deps really easily. http://jspm.io/
I'm afraid I'm not famililar with SystemJs, but from what I know of module loaders, they recognize libraries by the path they were loaded from, not the module's global name or anything. So, having lodash loaded via a <script> won't actually help it know whether or not it has it, or what object to give back. In basic terms, you'll want to load it via your module loader, not on its own.
However, you likely don't want to write "../node_modules/" into all your require statements in-script; that'd be annoying. You could look through SystemJs' configuration documentation to see if there's a way to create a mapping, so that a particular module name will automatically cause it to know to use a certain path for the script.

Categories