Import gojs extension using webpack - javascript

I'm using Laravel 8 with Laravel-mix so that my JS assets are compiled with webpack.
I have imported gojs successfully by doing this:
npm i gojs
Then adding this to my bootstrap.js:
import * as go from 'gojs';
Then compiling using:
npm run dev
So far so good my app.js now includes the gojs code and I can run basic gojs samples on my pages.
However I cannot figure out how to include any gojs extensions.
I've tried adding an extension to my boostrap.js in all these different ways (separately not all at once):
import DataInspector from 'gojs/extensions/DataInspector.js';
import * as Inspector from 'gojs/extensions/DataInspector.js';
import { DataInspector } from 'gojs/extensionsTS/DataInspector';
require('gojs/extensions/DataInspector.js');
require('../../node_modules/gojs/extensions/DataInspector.js');
Most compile without error and when I check my app.js compiled javascript the DataInspector code appears to be included.
However when I add a sample script to my page that uses the Inspect I get error:
Uncaught ReferenceError: Inspector is not defined
So it appears the DataInspector extension has not been included. The only way I can get it to work is to directly add a script tag to the DataInspector.js file in my HTML. However I'd like to figure out how to properly import it with all my other assets.

It's best to copy extension files into your own directory to use them. They are provided as examples of how to extend the library, and should not be imported directly.
If you look at extension code, you'll see it carries this warning:
/*
* This is an extension and not part of the main GoJS library.
* Note that the API for this class may change with any version, even point releases.
* If you intend to use an extension in production, you should copy the code to your own source directory.
* Extensions can be found in the GoJS kit under the extensions or extensionsTS folders.
* See the Extensions intro page (https://gojs.net/latest/intro/extensions.html) for more information.
*/

Related

How to use npm packages as ES6 modules loaded by the browser in 2021?

I'm a JavaScript beginner. I do not use a "bundler".
For a few days now I've been trying to use moment.js and other date-time libraries in some JavaScript by importing it using ES6 modules (ESM).
I have a JS module I wrote, which is transpiled from TS, and that has this line:
import moment from "../lib/moment/src/moment.js"
My module is itself loaded via an import from a <script type="module" > tag, which works.
I've discovered that the moment package contains what looks like "source" code in its src folder which seems to look more like the JS/TS I'm accustomed to, and has a "default export" at the bottom.
So I'm referencing that "source" version in my transpiled JS module. This gets me past a couple of errors I was getting:
The requested module 'blah' does not provide an export named 'default'
And
Cannot set property 'moment' of undefined (at moment.js:10)
And leaves me stuck with loading the other modules its dependent upon, because I guess, their file extensions are missing.
GET https://blah/lib/moment/src/lib/locale/locale net::ERR_ABORTED 404 (moment.js:37)
After 3 days tearing my hair out I feel like I have been fighting a battle I shouldn't be attempting at all.
I would expect in 2021, what with widespread ESM browser support, that this would just work, but I've tried 5 different date-time libraries and had no success.
I assume the 404s have occurred because the moment authors are NOT expecting people to be using their library like this, so they left off the file extensions knowing full well that it wouldn't load in a browser??
Am I supposed to add an extra step in my client-side build process, Gulp, to add the extensions back on in the moment source code??
Or am I doing something else wrong?
Is it perhaps that everyone uses a "bundler" and these tools fix all this stuff somehow and so these issues never arise for 99% of web devs??
Thanks in advance.
You want to import a bundled version of the lib to be able to do that. Try:
import from 'https://unpkg.com/moment#2.29.1/dist/moment.js' ;
You can download the bundled version and add to your project. Don't forget to put the license as well and check if they are at least MIT or similar.
If you want to refer to the source code you will certainly need to build that. Specifically with libs that are using typescript.

Natively import ES module dependencies from npm without bundling/transpiling first-party source

Background
I'm trying to create a "buildless" JavaScript app, one where I don't need a watch task running to transpile JSX, re-bundle code, etc every time I save any source file.
It works fine with just first-party code, but I'm stuck when I try to import dependencies from npm.
Goal
I want to achieve this kind of workflow:
npm install foo (assume it's an ES module, not CommonJS)
Edit source/index.js and add import { bar } from 'foo'
npm run build. Something (webpack, rollup, a custom script, whatever) runs, and bundles foo and its dependencies into ./build/vendor.js (without anything from source/).
Edit index.html to add <script src="build/vendor.js" type="module"...
I can reload source/index.js in my browser, and bar will be available. I won't have to run npm run build until the next time I add/remove a dependency.
I've gotten webpack to split dependencies into a separate file, but to import from that file in a buildless context, I'd have to import { bar } from './build/vendor.js. At that point webpack will no longer bundle bar, since it's not a relative import.
I've also tried Snowpack, which is closer to what I want conceptually, but I still couldn't configure it to achieve the above workflow.
I could just write a simple script to copy files from node_modules to build/, but I'd like to use a bundled in order to get tree shaking, etc. It's hard to find something that supports this workflow, though.
I figured out how to do this, using Import Maps and Snowpack.
High-Level Explanation
I used Import Maps to translate bare module specifiers like import { v4 } from 'uuid' into a URL. They're currently just a drafted standard, but are supported in Chrome behind an experimental flag, and have a shim.
With that, you can use bare import statements in your code, so that a bundler understands them and can work correctly, do tree-shaking, etc. When the browser parses the import, though, it'll see it as import { v4 } from 'http://example.org/vendor/uuid.js', and download it like a normal ES module.
Once those are setup, you can use any bundler to install the packages, but it needs to be configured to build individual bundles, instead of combining all packages into one. Snowpack does a really good job at this, because it's designed for an unbundled development workflow. It uses esbuild under the hood, which is 10x faster than Webpack, because it avoids unnecessarily re-building packages that haven't changed. It still does tree-shaking, etc.
Implementation - Minimal Example
index.html
<!doctype html>
<!-- either use "defer" or load this polyfill after the scripts below-->
<script defer src="es-module-shims.js"></script>
<script type="importmap-shim">
{
"imports": {
"uuid": "https://example.org/build/uuid.js"
}
}
</script>
<script type="module-shim">
import { v4 } from "uuid";
console.log(v4);
</script>
snowpack.config.js
module.exports = {
packageOptions: {
source: 'remote',
},
};
packageOptions.source = remote tells Snowpack to handle dependencies itself, rather than expecting npm to do it.
Run npx snowpack add {module slug - e.g., 'uuid'} to register a dependency in the snowpack.deps.json file, and install it in the build folder.
package.json
"scripts": {
"build": "snowpack build"
}
Call this script whenever you add/remove/update dependencies. There's no need for a watch script.
Implementation - Full Example
Check out iandunn/no-build-tools-no-problems/f1bb3052. Here's direct links to the the relevant lines:
snowpack.config.js
snowpack.deps.json
package.json
core.php outputs the shim
plugin.php - outputs the import map
passphrase-generator.js - imports the modules. (They're commented out in this example, for reasons outside the scope of this answer, just uncomment them, run the bundle script, and they'll work).
If you are willing to use an online service, the Skypack CDN seems to work nicely for this. For instance I wanted to use the sample-player NPM module and I've chosen to use a bundle-less workflow for my project using only ES6 modules as I'm targeting embedded Chromium latest version so don't need to worry about legacy browser support, so all I needed to do was:
import SamplePlayer from "https://cdn.skypack.dev/sample-player#^0.5.5";
// init() once the page has finished loading.
window.onload = init;
function init() {
console.log('hello sampler', SamplePlayer)
}
and in my html:
<script src="./src/sampler/sampler.js" type="module"></script>
And of course you could just look inside the JS file the CDN generates at the above url and download the generated all-in-one js file it points to, in order to use it offline as well if needed.

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.

A very simple query - Loading plain old javascript file with webpack

Should be quite a common question for a webpack newbie but unfortunately couldn't find a solution -
My project uses webpack. I need to use a library but it needs to be used as the old way of adding script tag like
<script src="//messaging-public.realtime.co/js/2.1.0/ortc.js"></script>
However I am looking for some way through webpack (a loader or in some other way) such that I can use it like
import ortc from "realtime-framework"
or
import * as ortc from "realtime-framework"
You will need to either:
Install it from a package manager like npm;
Download the file locally and import it;
Or include it the normal way with a script tag, making sure it is included before your script.

Qt Creator import file not found

I am trying to learn Qt QML with Qt Creator. I want to put my javascript functions into a seperate file and 'import' it into the qml world. Have got the code as below for testing how this works.
Trouble is I get the following error when I run the project in Creator...
> Starting
> /home/dev/docs/projects/Qt/build-XmlModelView-Desktop-Debug/XmlModelView...
> QML debugging is enabled. Only use this in a safe environment.
> QQmlApplicationEngine failed to load component qrc:/main.qml:5 Script
> qrc:/MyFuncs.js unavailable qrc:/MyFuncs.js:-1 File not found
I have watched videos and followed the Qt online docs and looked at others code, but I can't see what is wrong.
I can only guess that some sort of path is not set correctly, but in the docs it says the default path includes the directory that the QML file is in. My .js and .qml files are in the same directory. Also I tried editing the resource file, but that crashed it completely.
I tried moving the .js file to different locations, absolute path in the import statement. My eyeballs are starting to fall out now.
Oddly IT DOES WORK if I use qmlscene to run main.qml
Can anybody help? Here is my code...
main.qml file:
import QtQuick 2.3
import QtQuick.Window 2.2
import "MyFuncs.js" as MyFuncs
Window {
id: window1
visible: true
Rectangle {
id: contentArea
MouseArea {
id: mouseArea1
anchors.fill: parent
onClicked: {
MyFuncs.myfunc();
}
}
}
main.cpp file:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
MyFuncs.js File:
function myfunc() {
console.log("function was called")
}
Thanks for any help. Lost a whole day, just don't know where to go on.
NOTE:
You can probably just add the JavaScript file to the resources--and then when your project hits complexity where you don't want to recompile for each little change you can do what I did here below:
You're loading the file via qrc:/MyFuncs.js which is the file path to the resource. The problem is that the JavaScript file (likely) was not copied or isn't on your path. (It means you need to bundle it) depending on the path of your scene you might have it show up. As an example here I need to copy my JavaScript and QML to the build directory which is just annoying:
Here's an example of my config file for a moderately sized project:
CONFIG += c++11
# Add more folders to ship with the application, here
folder_qml.source = qml
folder_qml.target = /
folder_js.source = js
folder_js.target = /
folder_img.source = img
folder_img.target = /
folder_icon.source = icon
folder_icon.target = /
DEPLOYMENTFOLDERS += folder_qml folder_js folder_img folder_icon
Notice the REALLY weird syntax here: this copies the js, qml, icon, and img folders,to / in the build which you would think dumps those files on the root. Think again! The build directory looks like this:
+ debug
+ icon //I added this explicitly
+ img //I added this explicitly
+ js //I added this explicitly
+ qml //I added this explicitly
+ release
Makefile
Makefile.Debug
Makefile.Release
Now my application can correctly reference the files as they exist on the path. When running inside the IDE (depending on the setup) you might have the files available to you, you might not.
Here's a snippit from my main.qml:
import QtQuick 2.2
import QtQuick.LocalStorage 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.1
import com.lightassistant 1.0
import "qrc:/js/lightassistant.js" as LA;
import "qrc:/js/statics.js" as Statics
To prove a point here:
If I change the qrc:/js/statics.js to qrc:/nope/js/statics.js here's the error:
` qrc:/nope/js/statics.js: File not found`
or
` qrc:/statics.js: File not found`
Now from inside the IDE things should be fine as it runs the executable inside the source code. The problems listed above here are in regards to deployment and there are MANY ways around that. I prefer this so I can run batch commands, you could also use [OS]qtdeploy tools and specify some paths to get around it.
This technique prevents the resource files from being recompiled every time you make a chance which can add HOURS to your workday if you're testing the QML. Copying files is fast and doesn't require bundling the resource file.
I hope this helps, I too, lost a few days to figuring this out a year and half ago.
I'm still not sure why my import needed the file to be in 'Resouces', others I've seen on youtube appeared to work without that. However, the code works now that I have added the .js file to resources by right clicking, not on resources but on the / folder within resources. Why didn't I try that before.
Thanks to both for help.

Categories

Resources