how to Implement lit-element-bootstrap package in lit-lement - javascript

I would like to implement lit-element-bootstrap package in lit-element.
I am getting following error in console,
Failed to load module script: The server responded with a non-JavaScript MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec
//header.js
import { LitElement, html, css } from 'https://unpkg.com/#polymer/lit-element/lit-element.js?module';
import 'https://unpkg.com/lit-element-bootstrap#1.0.0-alpha.10/lit-element-bootstrap';
export class Header extends LitElement{
constructor() {
super();
}
render(){
return html`
<bs-alert primary>
<div>A simple primary alert—check it out!</div>
</bs-alert>
`;
}
}
customElements.define('header-element', Header);
//index.html
<!doctype html>
<html>
<head>
<script src="https://unpkg.com/#webcomponents/webcomponentsjs#2.2.7/webcomponents-bundle.js"></script>
<script src="https://unpkg.com/#webcomponents/webcomponentsjs#2.2.7/webcomponents-loader.js"></script>
<script type = "module" src = "../components/header.js"></script>
</head>
<body>
<header-element></header-element>
</body>
</html>

The URL you are trying to import from is getting redirected (302).
Current URL: https://unpkg.com/#polymer/lit-element/lit-element.js?module
Try changing it to:
https://unpkg.com/#polymer/lit-element#0.7.1/lit-element.js?module
Not sure if you should be loading it from this URL always, you can download the file and import it from your directory, rather than downloading it from this new URL. As this new URL can also change in future.

lit-element has been updated, the correct link would be https://unpkg.com/lit-element
or if you want to specify the extension
https://unpkg.com/lit-element/lit-element.js

Related

How to fetch HTML and CSS files for web components when hosted on a different domain than the application itself?

I am looking for a clean solution to split web components into JS, HTML and CSS files and host them on a CDN. I try to avoid the webpack html and css-loader as they dont allow me to export my web component as a plain ES module.
The goal is to use a web component from any frontend app just by importing it from a spcified URL. Thereby seperation of concerns should be preserved. Individual files for style, markup and logic also allow for syntax highlighting.
In a local dev environment I found the following to work great:
WebComponent.js:
export default class WebComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
const style = new CSSStyleSheet();
const template = document.createElement("template");
fetch("./WebComponent.css").then((res) =>
res.text().then((css) => {
style.replaceSync(css);
this.shadowRoot.adoptedStyleSheets = [style];
})
);
fetch("./WebComponent.html").then((res) =>
res.text().then((html) => {
template.innerHTML = html;
this.shadowRoot.appendChild(template.content.cloneNode(true));
})
);
}
}
WebComponent.css:
button {
/* Some styling */
}
WebComponent.html:
<button>Custom buttom</button>
I can import the component by using browser native ES module imports:
index.html:
<!DOCTYPE html>
<html>
<body>
<web-component></web-component>
<script type="module">
import WebComponent from "./WebComponent";
customElements.define("web-component", WebComponent);
</script>
</body>
</html>
This works until I move the web component files to a different location (a google cloud storage bucket) than my index.html and import WebComponent.js from there.
<!DOCTYPE html>
<html>
<body>
<web-component></web-component>
<script type="module">
import WebComponent from "https://storage.googleapis.com/storage-bucket/WebComponent.js";
customElements.define("web-component", WebComponent);
</script>
</body>
</html>
WebComponent.js gets imported correctly but it then tries to fetch WebComponent.css and WebComponent.html from a URL relative to localhost where index.html is served. However it should fetch from a URL relative to where it is hosted (https://storage.googleapis.com/storage-bucket/).
Any ideas how something like that can be achieved? Without hard coding the url into both fetch calls. That's not an option as the url can change automatically from time to time.
You are having issue with linking resources in the JS web page for which :
local component is working
import WebComponent from "./WebComponent";
remote component is failing
import WebComponent from "URL";
It might be that for this to work you should try this :
<script type="module" src="https://storage.googleapis.com/storage-bucket/WebComponent.js">
customElements.define("web-component", WebComponent);
</script>
References :
https://cloud.google.com/storage/docs/hosting-static-website
https://www.npmjs.com/package/webcomponent?activeTab=readme
https://lit-element.polymer-project.org/guide/use
JavaScript file paths are relative to the displayed page. So the behavior you are observing is expected.
You can use a JavaScript variable with a simple js declaration like below and use this variable across whenever you assign URLs dynamically:
<script type="text/javascript">
var webComponentPath = 'https://storage.googleapis.com/storage-bucket/';
</script>

Import classes into one main file shows error

I create many js classes and wanna import all of them to one main.js file where I want to invoke all of methods from these classes I need. Then, I want to use this main.js script in my index.html website file.
But shows me error like this: Failed to load resource: the server responded with a status of 404 (Not Found) in console for every method I want to use. I do not think that it's a problem with paths but I do not have any idea how to solve this.
main.js class
import NavigationAnimation from "./dom/navigation";
NavigationAnimation.stickyNav();
NavigationAnimation class
export default class NavigationAnimation {
//code
}
files structure is like this:
and my index.html is like that
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<header>
</header>
<main>
</main>
</body>
<script type="module" src="js/main.js"></script>
</html>
Can anybody explain what is wrong?
The import statement isn't being transpiled so needs to be the full filename, including the extension, just like the call for main.js:
import NavigationAnimation from './dom/navigation.js' // <- add '.js' here
Also consider using the .mjs extension.

Cannot use import statement outside a module?

I am just trying to have fun with JS, I am creating a small project trying to implement a new architecture that I di not use before, I was always using js in React apps, or using native JS but not creating an app with it, I was using it to create some animations and handle some changes in my pages, nothing complex).
I want to learn how to create a JS app, implementing a MVC architecture ! I am not following any tutorial, so here is my folder structure :
Here is my index.html :
<html>
<head>
<title>Test js PROJECT</title>
</head>
<body>
<div id="root"></div>
<script src="app.js"></script>
</body>
</html>
And that's my app.js :
import { loadApp } from './MVC/controllers/loadApp';
loadApp();
And that's is my loadApp.js :
const loadApp = () => {
const showUsersOption = document.createElement('button');
const showProductsOption = document.createElement('button');
showUsersOption.createTextNode('Users');
showProductsOption.createTextNode('Products');
const app = document.getElementById('root');
app.appendChild(showUsersOption);
app.appendChild(showProductsOption);
}
export default loadApp;
So I think what I am trying to do is simple, adding two buttons to the root element, But I got this :
app.js:1 Uncaught SyntaxError: Cannot use import statement outside a
module
Based on this comment to the question, I added type module in my script like that :
<html>
<head>
<title>Test js PROJECT</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="app.js"></script>
</body>
</html>
But I got this :
Access to script at
'file:///C:/Users/Taoufiq.BENALLAH/Desktop/Master/js/app.js' from
origin 'null' has been blocked by CORS policy: Cross origin requests
are only supported for protocol schemes: http, data, chrome,
chrome-extension, chrome-untrusted, https.
GET file:///C:/Users/Taoufiq.BENALLAH/Desktop/Master/js/app.js
net::ERR_FAILED
Based on the comments in this question here, I have to restart my editor or run npm install, but I am not using node modules or anything, my app is simpler than that.
Any idea ? Any help would be much appreciated.

PWA Simple Demo - Error when add pwabuilder-sw-register.js

Hello,
I'm trying to create a simple PWA demo by following the steps of this article: "https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/get-started"
However when I reach the step to download and add the files: "pwabuilder-sw.js" and "pwabuilder-sw-register.js" to root and then add <script src="/pwabuilder-sw-register.js"></script> to the head of index.html I got error on Edge browser: "SCRIPT1086: SCRIPT1086: Module import or export statement unexpected here" I search around and I find that I have to add type="module" like this <script src="/pwabuilder-sw-register.js" type="module"></script> but now I'm getting another error: "0: Unable to get property 'define' of undefined or null reference" in
pwaupdate (175,5829)
My page code looks like:
Index.html
<html>
<head>
<title>Express</title>
<link rel="stylesheet" href="/stylesheets/style.css">
<link rel="manifest" href="/manifest.json">
<script src="/pwabuilder-sw-register.js" type="module"></script>
</head>
<body>
<h1>Express 2</h1>
<p>Welcome to Express</p>
</body>
</html>
pwabuilder-sw.js
// This is the service worker with the Cache-first network
const CACHE = "pwabuilder-precache";
importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.0.0/workbox-sw.js');
self.addEventListener("message", (event) => {
if (event.data && event.data.type === "SKIP_WAITING") {
self.skipWaiting();
}
});
workbox.routing.registerRoute(
new RegExp('/*'),
new workbox.strategies.CacheFirst({
cacheName: CACHE
})
);
pwabuilder-sw-register.js
// This is the service worker with the Cache-first network
// Add this below content to your HTML page inside a <script type="module"></script> tag, or add the js file to your page at the very top to register service worker
import 'https://cdn.jsdelivr.net/npm/#pwabuilder/pwaupdate';
const el = document.createElement('pwa-update');
document.body.appendChild(el);
I searched a lot but I did not find any clue.
Please advise.
There are only 2 things you need to make this work:
Add pwabuilder-sw.js and pwabuilder-sw-register.js to your site root.
Add the following script tag to your <head>
<script type="module" src="pwabuilder-sw-register.js"></script>
Here's a quick sample that shows this working.
It looks like the MSDN article missed the "module" script type. My fault! I've updated the MSDN article to include this fix.
You normally don't need any more this script reference <script src="/pwabuilder-sw-register.js" type="module"></script>
The script will be loaded by the pwaupdate component. So simply add this code inside a block at the end of your HTML page:
import 'https://cdn.jsdelivr.net/npm/#pwabuilder/pwaupdate';
const el = document.createElement('pwa-update');
document.body.appendChild(el);
If it still doesn't work, please open an issue on our Github repo or ask to Justin who's in charge of this part on Twitter: https://twitter.com/Justinwillis96
Thanks!
David

React component rendering on server-side, but client-side does not take over

I have an EJS view which is served up to a client:
index.ejs
<!DOCTYPE html>
<html>
<head>
<title>Example app</title>
</head>
<body>
<div id="reactApp">
<%- reactContent %>
</div>
</body>
<script src="__res__/client/main.bundle.js" />
</html>
main.bundle.js is the bundle that I create using browserify:
gulpfile.js (partial)
function bundle(filename) {
var bundler = browserify('./app/client/' + filename + '.js');
bundler.transform(babelify);
bundler.transform(reactify);
return bundler.bundle()
.pipe(source(filename + '.bundle.js'))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('./dist/client'));
}
And the client is ultimately served this code:
main.js (bundled into main.bundle.js)
import React from 'react';
import {Login} from './auth/login.react';
React.render(React.createElement(Login), document.getElementById('reactApp'));
alert('hi');
However, even though the browser requests and recieves the main.bundle.js script, the client does not run the alert('hi'); line, which leads me to believe that the React.render line does not work either. I can affirm that Javascript is enabled, and my browser is the latest version of Chrome. My react component (Login) is as follows:
login.react.js
import React from 'react';
export class Login extends React.Component
{
handleClick() {
alert('Hello!');
}
render() {
console.log('rendered');
return (
<button onClick={this.handleClick}>This is a React component</button>
);
}
}
So, very simple. However, none of the alerts that you see in the code is ever run. The console.log('rendered'); line is never run on the server, but when I check the source code for my page, I get:
HTML output of my page
<!DOCTYPE html>
<html>
<head>
<title>Example app</title>
</head>
<body>
<div id="reactApp">
<button data-reactid=".2fqdv331erk" data-react-checksum="436409093">Lel fuck u</button>
</div>
</body>
<script src="__res__/client/main.bundle.js" />
</html>
Which means that the server correctly renders my react component, but why does the client script not work? The handleClick function never runs, my console.log lines never run, and neither does the alert lines. What is happening? The reactid and checksum are rendered correctly, shouldn't it be working? Shouldn't the React code on the client-side be smart enough to find the component and run correctly?
In your index.ejs, adding a closing element to your script tag should fix the issue: <script src="__res__/client/main.bundle.js"></script>
On a separate note, in my testing, I was getting an error in login.react.js when loading the page until I added default to the export line: export default class Login extends React.Component. Not sure if you will need to do the same.

Categories

Resources