Photoswipe and Require.js configuration - require

I have a module which is dependent upon both, PhotoSwipe and PhotoSwipeUI_Default. I am requiring both modules, like so and inside of my module I am initialising my gallery. EG:
define("modules/lightboxStart", ["vendor/PhotoSwipe", "vendor/PhotoSwipeUI_Default"], function (PhotoSwipe, PhotoSwipeUI_Default) {
var StartGallery = function(){
var lightBox = new PhotoSwipe($pswp, PhotoSwipeUI_Default, items, options);
lightBox.init();
}
StartGallery()
}
The gallery then works as expected but require is throwing a mismatched anonymous define module error in PhotoSwipe.js.
After looking through the docs I came to the conclusion that I need to run both scripts(PhotoSwipe and PhotoSwipeUI_Default) through the require.js API.
I then defined each, like so:
define('PhotoSwipe', function() {
//PhotoSwipe script here
return PhotoSwipe
})
And
define('PhotoSwipeUI_Default', function() {
//PhotoSwipeUI_Default script here
return PhotoSwipeUI_Default
})
This then eliminates the mismatched anonymous define module error I was getting earlier, but I am getting this error now instead:
PhotoSwipe is not a function
How could I fix this? I am essentially trying to access the PhotoSwipe function within PhotoSwipe.js and pass through my arguments but I am unable to do so without generating a load of js errors on the page and I can not figure out why.
Help much appreciated!

define( ["modules/lightboxStart", "vendor/PhotoSwipe", "vendor/PhotoSwipeUI_Default"], function (lightboxStart, PhotoSwipe, PhotoSwipeUI_Default) { //i think so}

Related

Cypress: Cannot use cy.task() to load dataset to Mongo before tests

I'm trying to use cy.taks() to load certain datasets to mongo before a test is run. But I'm getting errors. I've got a module where I export 2 functions, one from dropping a collection, and the other to load an object to a collection. Here is my cypress/plugins/index.js:
module.exports = (on, config) => {
on("task", {
"defaults:db": () => {
const {dropCollection, createUser } = require("../../lib/connectDB");
dropCollection("users");
createUser(userData)
},
});
};
Here is my /lib/connecDB.js:
export function dropCollection(collection) {
return mongoose.connection.dropCollection(collection);
}
export async function createUserInDB(userData) {
await User.create(userData);
}
So when I run the test, I'm getting:
cy.task('defaults:db') failed with the following error:
Unexpected token 'export'
Tried as well importing these function outside the index.js export, but getting same result.
I'd say it is something about export/import. The functions are exported as ES6, and imported as ES5.
I've tried to import the function the ES6 like:
import { dropCollection, createUser } from '../lib/connectDB'
And then export the plugin function also as ES6, but then I get:
Error: The plugins file is missing or invalid.
Your `pluginsFile` is set to `C:\Users\someRoute\cypress\plugins\index.js`, but either the file is missing, it contains a syntax error, or threw an error when required. The `pluginsFile` must be a `.js`, `.ts`, or `.coffee` file.
I've also tried to import required modules outside the function like:
const globalDbUtils = require('../lib/connectDB')
And then use the functions as
globalDbUtils.dropCollection("collectionName")
globalDbUtils.createUser(userData)
But I'm getting last error. I've tried pretty much everything, I tried to import Mongoose models straight, mongo client etc...Also I tried to import just one function and return it (just copy/pasting official doc...) but cannot make it work. I researched for a couple of days getting nothing, I found there is a npm package that helps u doing this, but since cypress allows you to do this by using no more plugins, I'd like to do it with no more tools than cypress itself.
Anyone knows what I am doing wrong?
Thanks in advance!
You need to use require instead of import at the top of your file and when exporting at the bottom use
module.exports = { createUserInDB }
Instead of exporting as you are currently doing.

Using aws-sdk.js with require.js in a browser

I'm trying to figure out how to use the browser-based aws-sdk.js with require.js when building a web app.
If I try to build a class and include aws-sdk in the require.js define, once I try to create an instance and reference the AWS class, it says it is undefined.
For example, I have a function that checks to see if the credentials are an instance of AWS.Credentials and if not, it tries to initialize it with an STS token it retrieves via Rest.
The problem is, the code dies on the if(this.credentials instanceof AWS.Credentials) saying AWS is undefined. It even dies on my simple check of the needsRefresh.
This is what my define looks like - I'll include the 'needsRefresh' wrapper for an example of the sort of thing that is throwing the Undefined error:
define(['require','aws-sdk','jquery'],
function (require, AWS, $) {
// Aws helper class
function AwsHelper() { };
AwsHelper.prototype = {
credentials: null,
tokenNeedsRefresh: function () {
//////////////////////////////////////////////////////////////////
// errors out on the following line with: //
// TypeError: Cannot read property 'Credentials' of undefined //
//////////////////////////////////////////////////////////////////
if(this.credentials instanceof AWS.Credentials) {
return this.credentials.needsRefresh();
} else return true;
}
};
return AwsHelper;
}
);
I also tried the following format at the top of the file:
define(function (require) {
var AWS = require("aws-sdk"),
$ = require("jquery");
/* .. */
If I remove all onLoad references to the refresh code running, it will load and I can create an instance. But as soon as I call any function that references the AWS class, it dies.
How do I make sure that AWS class definition is still in global space once an instance is spawned?
Dunno what difference the paths will make (it's finding and loading the code just fine - I can see AWS Class in namespace in the debugger as it's loading but it's not in the namespace on the function call), but added on request:
requirejs.config({
baseUrl: '/js',
paths: {
lib: 'lib',
ImageUploader: 'ImageUploader'
}
});
I decided to try to play with this again and seemed to have figured out how I was going about it incorrectly. I have yet to integrate it back into my existing code setup, but I think I have a working solution.
The thing I was doing wrong was I was trying to set up the AWS class so I could load it as a module (thus why I tried wrapping it as the require.js suggested).
Playing with it this time around, I noticed something I hadn't before. I had an AWS that was undefined in the local scope and an other AWS that held the class definition in the global scope. So it was trying to specify AWS in my define that was creating the local 'null' version:
define(
["jquery","aws-sdk","dropzone","app/MyUtilities"],
function ($, AWS, Dropzone, MyUtilities) {
"use strict";
function MyClass() {};
return MyClass;
}
);
jquery and dropzone have whatever is needed to make sure they load that way, but aws-sdk seems to do some of it's own asynchronous loading. Thus the scope variable in the function is undefined.
Technically, it seems the only thing I needed defined as a module in the function wrapper is my own utilities module. So by switching it to:
define(
["app/MyUtilities","jquery","aws-sdk","dropzone"],
function (MyUtilities) {
"use strict";
function MyClass() {};
return MyClass;
}
);
... it seems $ and jquery are defined as needed, Dropzone is defined as needed and AWS is defined as needed. (and I don't get my errors when accessing the static AWS.config or AWS.Credentials definitions as I did before)

How to access a closure function in a require.js module?

I am trying to use require.js to load my modules dependencies and so far it is working, but I have a doubt. I've created a little function to test the modules and placed it in a file called panelTest.js:
define(['./panel/View', './panel/TitleView'], function(View, TitleView) {
return function test(container) {
// main view
var panel = new View(container, 'main');
var panelTitle = new TitleView(panel.getContainer(), 'main-title');
panelTitle.setTitle('Properties Panel');
//panelTitle.addCss('pjs-panelTitle');
panel.addView(panelTitle);
// sections
var top = new View(panel.getContainer(), 'top');
panel.addView(top);
var middle = new View(panel.getContainer(), 'middle');
panel.addView(middle);
var bottom = new View(panel.getContainer(), 'bottom');
panel.addView(bottom);
};
});
In the html that uses the modules I included this script tag as shown in the require.js documentation to load panelTest.js.
<script data-main="panelTest.js"
src="require.js"></script>
My question is how can I call the test function from outside the module, since the container parameter it is supposed to come from outside the module.
You have to access the module through the appropriate channels provided by RequireJS. You could do it like this in a script tag that appears after the one that loads RequireJS:
require(['panelTest'], function (panelTest) {
panelTest(/* some value */);
});
Given the code you show, your panelTest module does not seem to really make sense as a "main module" so I would not put it as data-main.
If you want to use it from anther module, put the module in its own file and define it like this:
define(['panelTest'], function (panelTest) {
panelTest(/* some value */);
});

Electron app: Reference mainWindow object in another module?

I am building an electron app, where the mainWindow object is created following the quick start: http://electron.atom.io/docs/tutorial/quick-start/.
As per this quick start, it is created asynchronously. The problem that I run into, is that for instance when I want to send messages from main to renderer process, I need to reference the mainWindow object. If this happens to be in a module that I require, then I need a means to make this module know of the mainWindow object.
I could of course prepend it with global., but I know that this is very much advised against. So I wish to do it more elegantly.
I came across this post: Asynchronous nodejs module exports; which appears to offer a solution. Taking the main.js file from the quick start (see above link, it's explicitly shown there), it appears I would add to the createWindow function
if( typeof callback === 'function' ){
callback(mainWindow);
}
and export the main.js module as
module.exports = function(cb){
if(typeof mainWindow !== 'undefined'){
cb(mainWindow);
} else {
callback = cb;
}
}
Then, in a higher-level script, I would require as follows:
let main = require('./main.js');
let lib = require('./lib.js'); // Library where I need a mainWindow reference
main(function(window) {
lib.doSomething(window);
});
where lib.js looks like
module.exports.doSomething = function(window) {
// Do something with window object, like sending ipc messages to it
window.webContents.send('hello-from-main', "hi!");
}
Although the simple case in the original post 'Asynchronous nodejs module exports' works fine, I cannot get it to work like described above; running the app it complains Uncaught Exception: TypeError: Cannot read property 'webContents' of null. This is also the case if I directly require lib.js within main()'s callback (which I know is also advised against).
I confess that I do not fully understand the simple case of the post, as I am rather new to node. This prevents me from fixing my own implementation of it, which I agree is blunt copy/pasting which reasonably should be expected to fail. Could somebody help me with how to correct above method, or advise me of a different approach to make it work? Thank you!
I have created the npm package electron-main-window for the same.
Install:
$ npm install electron-main-window
or
$ yarn add electron-main-window
Usage:
// Import ES6 way
import { getMainWindow } from 'electron-main-window';
const mainWindow = getMainWindow();
// Import ES5 way
const mainWindow = require('electron-main-window').getMainWindow();
// e.g:
if(mainWindow !== null ){
mainWindow.webContents.send('mainWindowCommunication', "This is a test message");
}
Whooops! The devil is in the details... I had defined on top of main.js
let mainWindow = null, callback;
which caused the error! Should be
let mainWindow, callback;
then it works perfectly!
P.s. Instead of deleting my post, I opted for keeping it and answering myself for future reference of other people who need asynchronous exporting.

Testing React component with global dependency

I have included a JS dependency (Foo.js) in my index.html file. When I call Foo.js in my React component, it finds the Constructor in the global namespace and instantiates it. This works great when I deploy it, but when I go to build a test around Component.js, the test can't find Foo.js
<!--Index.html-->
<head>
<script src="Foo.js"></script>
</head>
// Component.js
var bar = new Foo(); // Works in deployment but not in Jest tests
When running my test I get this error:
RefererenceError: Foo is not defined
Now I thought I would be clever and in my Component.js file declare Foo to be window.Foo, which worked in getting rid of the undefined dependency in my Jest tests.
// Component.js
var Foo = window.Foo;
var bar = new Foo();
Suddenly my Reference error went away and I was happy. So I continue to write tests and now I get a funky error that I think has to do with that global dependency again.
TypeError: undefined is not a function
I believe that my error is still coming from Jest not properly mocking a dependency that is on the window object. I don't need to test the dependency, I just need it to be defined so I can get to writing tests for the rest of the Component. Does anyone have a thought on what I could possibly be doing wrong?
So I finally figured out how to fix this. In my browser environment and my testing environment I have two completely separate window objects. In my test, before I require in my component I have to set window.Foo to an anonymous function. It will look like this:
// Component.js
var bar = new Foo(); // Works in browser but not in test
// ...Rest of code
// Component.test.js
describe('Component.js', function() {
let Component;
beforeEach(function() {
window.Foo = function() {};
Component = require('./Component.js'); // When it requires in component,
// it will now have Foo declared on the window object
});
});
I have to explicitly declare any window objects in my test environment for any components to find those functions.

Resources