Add an external script to React and create new instance - javascript

I am trying to implement this github project to my React web app. It is an external script to put a fancy canvas in the background.
I have tried to load it:
import {WarpSpeed} from './warpspeed.js'
import WarpSpeed from './warpspeed.js'
And then create a new instance:
let x = new WarpSpeed("canvasID")
But it throws an error:
TypeError: __WEBPACK_IMPORTED_MODULE_4__helpers_warpspeed___default.a is not a constructor
I also tried to use react-load-script, but it does not make sense I cannot call new WarpSpeed after, because it is undefined.

The module you are trying to use will not work with commonjs importing. You will need to wrap the whole thing inside of a universal module definition.
Please use the one here:
https://gist.githubusercontent.com/tameemsafi/0d909a4060640b948f37ec59460f20d4/raw/c7f4e9020ccb1fb0a9dcf54221c67249030640eb/warpspeed-umd.js
I have wrapped it in a UMD IFFE which will allow you to use ES6 import. I also changed the window.requestAnimationFrame polyfill to a better version.
You can place the code inside of a file warpspeed.js.
CommonJS:
const WarpSpeed = require('./warpspeed.js');
ES6 (Requires transpiling to commonjs):
import WarpSpeed from './warpspeed.js'

According to this:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Import_a_module_for_its_side_effects_only
other info I've found and after checking source code of WarpSpeed.js, what you want seems impossible.
You can also confirm it here:
ES6 import equivalent of require() without exports
You should probably add proper export to WarpSpeed.js file.
Maybe fork the project, modify it so it is ES5+ compatibile and create pull request. Probably lib creator will be greateful ;)

Related

How to include functions of JavaScript files in the Node.js server?

I have a typescript file in which some functions have been added.
The following shows the actual address of the typescript file :
../myproject/src/util/validation/user-validation
All the functions are exported from the file. For instance,
export function validateSignUpData(userDetail:UserDetail):Array<String>{
let errorMessages = new Array<String>();
/* Some Code */
Now I am trying to use the exported function in Node server, though it throws an error which I do not comprehend.
Error: Cannot find module '../myproject/src/util/validation/user-validation'
This is how I tried to get the functions inside my Node server file:
app.post('/users',(req,res)=>{
let validator = require('../myproject/src/util/validation/user-validation');
let errorMessages = validator.validateSignUpData(req.body);
I googled require function, and it seemed that my code must work properly. Some forums suggests that typescript must be installed to resolve the issue, though I have already installed typescript!
I will be glad, if you help me!
Thank you.
The export keyword is used for ES6 modules (Related article also covering node.js). This is a new language feature that was shipped in 2015.
It uses export function name() {...} to export a function and import {name} from './path/to/file'; to import it somewhere else.
Node uses the CommonJs syntax (which is still largely popular).
The idea behind it is that any module (i.e. js-file) can export an object like this: module.exports = {key: "value"}. This object can then be imported using require('./path/to/file').
You can use es6 modules in node like this: How can I use an es6 import in node?.
There are 2 methods of modules in node js, es6 modules and requrejs
require is used together with module.exports
add this to your module
module.exports.validateSignUpData=validateSignUpData
and then the require function will export it.
The other way is to use es6 modules but it doesn't work under all circumstances
https://nodejs.org/docs/latest-v13.x/api/esm.html#esm_enabling

Angular import external javascript file, getting no exported member and compile errors

I am writing an angular component and got a open source module working with npm install. Now I made some some changes and want to import the javascript file like so
import { ModuleName } from './../../ModuleFolder/ModuleName';
When I place the cursor above the ModuleName inside the bracket, I see the highlighted red error saying Module has not export member 'ModuleName';
In my ts code, I have referenced the Module like so
object: ModuleName; which is also complaining.
I google and the post says using npm install but I don't want to add this module to my node_module list. I am moving the folder out to make my customization.
I also tried the following but it is not working
import './../../ModuleName.bundle.min.js';
I am wondering does the name of the Module needs to be registered somewhere to be able to reference it in my component?
Thanks for any help.
Use 'declare' after the import statements
declare const _moduleName;
For example:
I am using Swiper.js library using cdn. In my angular component, I refer it using a declare keyword.
declare const Swiper;
var mySwiper = new Swiper('.swiper-container', { /* ... */ });
I got external libraries working in Angular by following the following links
https://hackernoon.com/how-to-use-javascript-libraries-in-angular-2-apps-ff274ba601af

Importing modules from a CMS in typescript, gives module not found

When trying to import a module thats not in my node_modules Typescript tells me it cant find the module. The problem im facing is that the module is inside a CMS and i never get it as an actual module.
I can import it with es6 syntax, but behind the scenes its a Java API that returns javascript, and I can only call the functions without knowing 100% the structure of the code behind it (except the JavaDOC).
Ofcourse Typescript tries to import this as usual and cant find the module, example syntax: import PropertyUtil from 'PropertyUtil', where PropertyUtil is the module.
Is there any way I can solve this? I have a workaround currently with building fake modules from the Javadoc but I dont find it reliable enough..

How to access a variable from another JS file in webpack

I'm trying to implement webpack in a project, but can't seem to find a clear answer to this issue in their docs. I need to be able to access a certain variable globally from a JS file, for example:
toProps.js:
var myProp = "test";
In my entry point I do the following:
entry.js:
require('./toProps.js');
console.log(myProp);
But the variable myProp is undefined. This is an extremely simplified example, not my actual use case, but the point is that I'm working with an existing code base where there are these types of global references all over the place, but I want to implement some module and lazy loading with webpack.
How can I access the myProp variable?
Inside toProps.js:
var myProp = "test";
export default myProp;
Inside entry.js:
import myProp from './toProps.js';
From what I see, you haven't exported the variable. Therefore, it can't be an 'import' inside entry.js.
Edit 1: Learn more about exporting here.
Edit 2:
Okay, to make it a global variable, here's what I did:
Move props.js into /dist and link it inside index.html, before bundle.js, or whatever you've named the output file.
Now it's a global variable, so you don't actually need to export or import it anywhere.
To test this, I made a file called test.js, imported it into entry.js. Inside test.js is:
const logTest = () => {
console.log(myProp)
}
export default logTest;
Now inside entry.js, I invoked the function. It worked as expected and 'test' showed up in the console.
As you mentioned, your example is simplified, so this may not be viable for you. Maybe, you could move all the global variables to one file inside /dist, inside an object, as it's best not to pollute the global object.
Edit 3: Go with the answer from Jonas W. Totally forgot you could do that.
If you really need a global variable (no you dont!), use window:
window.myProp = "test";
Otherwise just export it from your file and import it everywhere you need it. That maybe adds some overhead to your code, but actually you always know where the value comes from, which makes debugging super simple.
Using webpack 4
To update this post for anyone that can read it, acctually you can use a plugin in webpack.config.js to resolve names that used in another .js files.
Take a look in https://webpack.js.org/plugins/provide-plugin/ example:
Usage: jQuery
To automatically load jquery we can simply point both variables it exposes to the corresponding node module:
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
});
Then in any of our source code:
// in a module
$('#item'); // <= just works
jQuery('#item'); // <= just works
// $ is automatically set to the exports of module "jquery"
If the source file to import belongs to maintainer, it's best to export first and import latter. Just like the answer of #Ibrahim.
I also encounter a situation to import third party source file just not using export syntax. So I think below is a solution while using webpack.
First, install exports-loader for your project.
npm install exports-loader --save-dev
Then, in your JS source file, import and use like below:
const WEBGL = require("exports-loader?WEBGL!three/examples/js/WebGL.js");
WEBGL.isWebGL2Available()
In my case, WEBGL is the inner variable I wish to import, three/examples/js/WebGL.js is the third party source file.
Hoping this is useful.

Defining an imported external module with WebPack + TypeScript

I'm trying to get WebPack set up with TypeScript and some external libraries, but having some trouble.
I'm importing the src version of jQuery in order to let WebPack choose the required modules (this was needed to get the Boostrap-SASS loader working), so am importing the library like this in my TS:
import jquery = require( 'jquery/src/jquery.js' );
When compiling, this throws the error cannot find external module 'jquery/src/jquery'. If I create a manual .d.ts file to define the library, like so:
declare module "jquery/src/jquery"{}
then the compiler works, but warns:
cannot invoke an expression whose type lacks a call signature
Alternatively, if I change the import line to
var jquery = require( 'jquery/src/jquery' );
(which I think is a CommonJS style import?) then it all compiles (and runs) fine. So, questions:
Is there a better way of requiring/including the source files using WebPack?
What's the correct way to define the module so it doesn't lack a call sig?
Should I be worried about using var instead of import or just roll with it if it's working?
I've only just picked up WebPack so it's entirely possible I'm doing something stupid. Please correct me if so!
Edit:
As I was thinking about how to phrase the question this came to me:
declare module "jquery/src/jquery" { export = $; }
which seems to let me use "import..." - but is that a good way to handle this?
Edit 2:
In reply to #basarat's answer below (my comment got a bit long to be read without line breaks):
I'm already using the jquery def from DefinitelyTyped, but it doesn't work by itself because the module I'm requiring is "jquery/src/jquery" and not just "jquery". If I use "jquery" then the compiled dist version of jquery is loaded, which doesn't work with the Bootstrap loader.
So the declare module "jquery/src/jquery" { export = $; } is, I think, extending the existing definition but using the path that I need to load it from.
import jquery = require( 'jquery/src/jquery.js' );
Use the definitely typed definition for jquery instead : https://github.com/borisyankov/DefinitelyTyped/blob/master/jquery/jquery.d.ts#L3158-L3160 which already allows you to do import jquery = require('jquery').
To answer my own question, this is what I ended up doing.
NB I don't know if this is the "correct" way of achieving this (I suspect not), so I'm open to anyone with a better answer!
In my TS definitions file tsd.d.ts I have the Definitely Typed jQuery definition:
/// <reference path="jquery/jquery.d.ts" />
but on its own this wasn't enough for the compiler to pick up the jQuery source files from within the node_modules folder.
So further down tsd.d.ts I've added:
declare module "jquery/src/jquery"
{
export = $;
}
The compiler can now locate the jQuery source files.
I also had to edit one of the jQuery source files for the WebPack compiler to play nicely with it: selector.js doesn't have a factory function included by default, and WebPack requires one to be present.
There's a loader that says it fixes this but I couldn't get it to work, so I just changed the code in selector.js to:
define([ "./selector-sizzle" ], function(){});
This all feels a little bit hacky... but it got me over this particular hurdle.

Categories

Resources