I got this basic Javascript code which is compiled by webpack. I am using Hot Module Replacement for Styles and Javascript.
When I listen to https://localhost:3000/mypage everything works perfectly.
However I would like the app() to run if the HMR can not connect:
GET http://localhost/__bud/hmr 404 (Not Found)
I am aware, that in this case my updates will not be applied.
This does currently work, however I have the feeling that it is not the correct way to do this.
My setup is:
WSL2 - Ubuntu
Wordpress 6.0
bud.js
Webpack
/**
* Import a file with the correct ES6 Module way:
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
*/
import Cookie from './modules/Cookie.mjs';
import LazyLoadImages from './modules/LazyLoadImages.mjs';
/**
* app.main
*/
const main = async (err) => {
if (err) {
// handle HMR errors
console.error(err);
}
// application code
app();
/**
* Initialize
*
* #see https://webpack.js.org/api/hot-module-replacement
*/
import.meta.webpackHot?.accept(main);
};
/**
* Add custom code inside this function
*/
const app = () => {
document.addEventListener("DOMContentLoaded", function (event) {
// Add your imported code here, for example: new defaultExport();
new Cookie(true);
new LazyLoadImages();
});
}
/**
* Run the application even if HMR is not enabled/used
*/
app();
Related
I would like to use Comlink in my Vue 3 application and I think Comlink just works fine however when I try to reference my worker for new Worker() I think it fails to take hold onto that file.
My tree looks like this:
src
--pages
----page.vue
--workers
----worker.js
My worker.js:
import * as Comlink from 'comlink';
const worker = {
trial() {
return 'hello';
},
};
Comlink.expose(worker);
My page.vue:
import * as Comlink from "comlink";
export default {
methods: {
tryOnClick() {
const worker = new Worker("../../workers/worker.js");
Comlink.wrap(worker);
worker.trial();
},
},
};
(Later I would use my worker in a manager class and not directly in the page I just want to try it out)
This gives me the error in the console:
worker.js:1 Uncaught SyntaxError: Unexpected token '<'
When I open this error up it seems like it fails at the very beginning of the HTML:
<!DOCTYPE html>
How should I reference my worker.js when I initialize the new Worker?
Unfamiliar with javascript/node.js, and I'm unable to get my script to run:
import { IDS, MangoGroup, MangoClient } from '#blockworks-foundation/mango-client';
import { Account, Connection, PublicKey } from '#solana/web3.js';
import { Market } from '#project-serum/serum';
import { readFileSync } from 'fs';
setInterval(function () {
console.log("timer that keeps nodejs processing running");
}, 1000 * 60 * 60);
As you can see, this script is essentially blank. The imports alone are causing it to fail. If I remove the imports, then node.js stays running.
What's the problem?
EDIT: Here is the output: gist
If you are trying to run the script using nodejs, add "type": "module" in the package.json file. I hope this will solve your issue.
I am creating a React App using the Create React App utility and I want to override the default service worker that it provides.
Since I don't want to eject my app, I am using the workbox-build package to create my service worker (I also used yarn to install the workbox-sw package).
My service worker code is the following:
/* eslint-disable no-restricted-globals */
import * as core from 'workbox-core';
import * as routing from 'workbox-routing';
import * as strategies from 'workbox-strategies';
import * as precaching from 'workbox-precaching';
self.addEventListener('message', event => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
core.clientsClaim();
routing.registerRoute(
new RegExp('^https://fonts.googleapis.com'),
new strategies.StaleWhileRevalidate({
cacheName: 'google-fonts-stylesheets-v1',
})
);
precaching.precacheAndRoute([]);
routing.registerNavigationRoute(
precaching.getCacheKeyForURL('/index.html'), {
blacklist: [/^\/_/, /\/[^/?]+\.[^/]+$/],
}
);
And my workbox-build script is:
const workboxBuild = require('workbox-build');
// NOTE: This should be run *AFTER* all your assets are built
const buildSW = () => {
// This will return a Promise
return workboxBuild.injectManifest({
swSrc: 'src/service-worker.js',
swDest: 'build/service-worker.js',
globDirectory: 'build',
globPatterns: [
'**\/*.{js,css,html,png,json}',
]
}).then(({
count,
size,
warnings
}) => {
// Optionally, log any warnings and details.
warnings.forEach(console.warn);
console.log(`${count} files will be precached, totaling ${size} bytes.`);
});
}
buildSW();
For registering the service worker I am using:
import { Workbox } from 'workbox-window';
export function register() {
if ('serviceWorker' in navigator) {
const wb = new Workbox('/service-worker.js');
wb.register();
}
}
However when I run my App I get these errors:
service-worker.js:2 Uncaught SyntaxError: Cannot use import statement outside a module
:3000/107/aggregator:1 Uncaught (in promise) TypeError: Failed to register a ServiceWorker for scope ('http://localhost:3000/') with script ('http://localhost:3000/service-worker.js'): ServiceWorker script evaluation failed
What am I doing wrong?
Current Answer
According to Mozilla's documentation it should work now, but keep an eye on the up-to-date implementation status in each browser. Firefox and Opera are still behind.
Original answer from 2020
There is no module support in workers yet.
importScripts() could do the job for you, but it can not import modules, meaning anything with an "export" keyword inside.
https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts
fips' answer helped me get on the right track.
I am not using a bundler/compiler, which seems like a the avenue to pursue.
However, for anyone else that this may help:
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.5.3/workbox-sw.js');
workbox.precaching.precacheAndRoute(self.__WB_MANIFEST);
fits well to those trying to solve some examples from Googles documentation
or more specific to your code, all those modules are accessible as attributes on the workbox object.
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.5.3/workbox-sw.js');
self.addEventListener('message', event => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
workbox.core.clientsClaim();
workbox.routing.registerRoute(/* your params here */);
workbox.precaching.precacheAndRoute(/* your params here */);
// presuming OP function is deprecated in current version and changed
// to 'registerRoute', but may actually be 'NavigationRoute' check
// current documentation for more clarity.
workbox.routing.registerRoute(/* your params here */);
I have a Vue.js app. This app is a progressive web app, so it's intended to primarily run on the client-side. However, during the initial start-up, I need to authenticate the user in my Azure Active Directory, get data associated with their account, and store it for offline use.
I have a server-side API in place already for retrieving the data associated with a user account. I also know how to store it for offline use. However, my question is: how do I authenticate with the Microsoft Graph from my Vue.js app? Everything I see relies on using Node.js middleware, but unless I'm misunderstanding something, my progressive web app isn't a Node.js app. It's just straight up JavaScript, HTML, and CSS.
If the user closes the app, then revisits it in a couple of days, I believe I would need to use the refresh token to get a new access token. Still, once again, everything I see relies on Node.js middleware. I believe I need a solution that works purely in Vue.js / JavaScript. Am I mistaken?
Updates
1) Installed the Microsoft Graph Client via NPM (npm install #microsoft/microsoft-graph-client --save). This installed v1.7.0.
2) In my Vue.js app, I have:
import * as MicrosoftGraph from '#microsoft/microsoft-graph-client';
import * as Msal from 'msal';
let clientId = '<some guid>';
let scopes = ['user.read'];
let redirectUrl = 'http://localhost:1234/'; // This is registered in Azure AD.
let cb = (message, token, error, tokenType) => {
if (error) {
console.error(error);
} else {
console.log(token);
console.log(tokenType);
}
}
let reg = new Msal.UserAgentApplication(clientId, undefined, cb, { redirectUrl });
let authProvider = new MicrosoftGraph.MSALAuthenticationProvider(reg, scopes);
The last line generates an error that says: export 'MSALAuthenticationProvider' (imported as 'MicrosoftGraph') was not found in '#microsoft/microsoft-graph-client'
The last line generates an error that says: export 'MSALAuthenticationProvider' (imported as 'MicrosoftGraph') was not found in '#microsoft/microsoft-graph-client'
This error occurs because the main script (lib/src/index.js) of #microsoft/microsoft-graph-client does not export that symbol. You'll notice that logging MicrosoftGraph.MSALAuthenticationProvider yields undefined. Actually, the main script is intended to be run in Node middleware.
However, #microsoft/microsoft-graph-client provides browser scripts that do make MSALAuthenticationProvider available:
lib/graph-js-sdk-web.js
browserified bundle (not tree-shakable)
sets window.MicrosoftGraph, which contains MSALAuthenticationProvider
does not export any symbols itself
import '#microsoft/microsoft-graph-client/lib/graph-js-sdk-web'
let authProvider = new window.MicrosoftGraph.MSALAuthenticationProvider(/* ... */)
demo 1
lib/es/browser/index.js
ES Modules (tree-shakable)
exports MSALAuthenticationProvider
import { MSALAuthenticationProvider } from '#microsoft/microsoft-graph-client/lib/es/browser'
let authProvider = new MSALAuthenticationProvider(/* ... */)
demo 2
lib/src/browser/index.js
CommonJS module (not tree-shakable)
exports MSALAuthenticationProvider
import { MSALAuthenticationProvider } from '#microsoft/microsoft-graph-client/lib/src/browser'
let authProvider = new MSALAuthenticationProvider(/* ... */)
demo 3
I have a JSON file within my custom node package. When I run the code as an app it works fine and loads. If I install the package as a module in say a React app the path is wrong and I get a 404. I tried to use the path module to sort this but its just returning the same URL but it needs to reference the local file in the custom node package instead.
/**
* injects the json
* #returns {Promise<void> | *}
*/
loadModels() {
const manifest = path.resolve('somefolder/myfile.json');
return someClass.loadFile(manifest)
.then(() => {
// do stuff
})
.catch(error => {
console.error(`Unable to load JSON: ${error}`);
}
);
}