Flickity via webpack returning different result - javascript

I am installing Flickity using npm: npm i flickity.
Flickity version is 2.2.0
Then I call and use like this:
import Flickity from 'flickity'
const flickity = new Flickity(el, options)
console.log(flickity)
I have checked the function Flickity and realize that it is minified after building via webpack, and it seems to return the different result for flickity object. Therefore, it causes the action/methods on flickity object to behave differently. Please see the attached screenshot below for better illustration:
Development environment:
Minified via webpack:
Could anyone give suggestions on what is wrong in my situation to fix this issue?
Update: One important piece of information I haven't mentioned is that flickity object is initialized inside a vue component. It might be the reason for this problem.
carousel.vue
import Flickity from 'flickity'
export default {
data () {
return { options } // options object
}
mounted () {
this.instance = new Flickity(this.$el, this.options)
console.log(this.instance)
}
}
I am using vue 2.6.10. The result this.instance is different on the two environments as I stated above. I still need help on this issue.

The right syntax is:
import Flickity from 'flickity';
EDIT:
It seems to work correctly, take a look at my snippet (I've used a react template but also plain es6 should be fine)

Related

Migration from lodash 3 to lodash 4: what replaces the 'lodash/string/template'?

We try to migrate one Backbone.js project from lodash "3.10.1" to latest lodash "4.17.21" and seems like 'lodash/string/template' was removed in version 4.
In our code we have something like:
import template from 'lodash/string/template';
export default _.extend(window.app, {
...
template: (path, options) => template(someCustomMethod(path), options),
...
And with lodash 4 installed the bundler crashes with:
Error: Can't walk dependency graph: Cannot find module 'lodash/string/template'...
In case I import it this way:
import { template } from 'lodash';
Then compilation passes but when you try to load the app then an error occurs:
...Uncaught TypeError: Cannot set properties of undefined (setting '_url_prefix')
It comes from inside "Backbone.View" and seems related to lodash template.
Have someone stumbled upon such an issue? The Backbone.js version is 1.1.2, but I think it's not related - if I return back to lodash "3.10.1" then all works perfectly. Maybe the new lodash template version returns differently structured results?
It sounds like you want
import template from 'lodash/template';
and for the _url_prefix error it's impossible to say more without the full stack trace.

AlpineJS and Webpack Encore (Symfony 5.2.x)

I started a new Symfony 5.2.x application which will have only some minimal javascript. For that, I decided to use AlpineJS. For the static files, I'm using Webpack Encore.
I read AlpineJS documentation and I even have an example for how instantiate a new AlpineJS instance. I'm not using defer property when I'm including JS.
Here's a part of my code:
HTML:
<nav x-data="navbar()">...</nav>
app.js:
import 'alpinejs';
function navbar() {
return {
...
}
}
However, when I'm refreshing the page, there's an error when I access the console log. "TypeError: navbar() is not a function". What should I do in this case? Have anyone tried to use this framework with Webpack Encore?
You can fix this using window.navbar = navbar;, like so:
import 'alpinejs';
function navbar() {
return {
...
}
}
window.navbar = navbar;
Explanation of this: bundlers (like Webpack) try to keep functions scoped to their modules, ie. not to pollute the global window scope. However when Alpine.js reads x-data="navbar()" it tries to find navbar in the global/window scope (ie. window.navbar), hence the fix.

Property 'mask' does not exist on type 'JQuery<HTMLElement>

I recently was trying to use the jquery mask in my angular project, so i installed in my project with: npm i jquery-mask-plugin, so in my TS file i wrote:
ngOnInit() {
$('.date').mask('11/11/1111');
$('.time').mask('00:00:00');
$('.date_time').mask('00/00/0000 00:00:00');
$('.cep').mask('00000-000');
$('.phone').mask('0000-0000');
$('.phone_with_ddd').mask('(00) 0000-0000');
$('.phone_us').mask('(000) 000-0000');
$('.mixed').mask('AAA 000-S0S');
$('.cpf').mask('000.000.000-00', {reverse: true});
$('.money').mask('000.000.000.000.000,00', {reverse: true});
}
Just as it is on the main site, but instead of $(document).ready(function(e)) i preferred to use the ngOnInit() , but when i save, the console hit me with the error:
"Property 'mask' does not exist on type 'Jquery'"
What am i doing wrong? I have to import on the appModule? I have to declare it in the angular.json? I have to import in the component file that i'm going to use? What should i do??
Obs: If there's any other mask for angular that you think it's better, please tell me :)
Well, the 'official' mask library for Angular 2+ is https://www.npmjs.com/package/ngx-mask. I have used it on several occasions and it works quite well. You should import it in appModule and if you have lazy loaded modules that are also using the mask in them as well.

How to use imported third-party js (not addon/npm package) in controller/component?

I have put my js files eva.min.js/feather.min.js and so on in vendor dir, then I imported them in ember-cli-build.js app.import('vendor/eva.min.js'). But how to use it?
I tried something like import eva from 'eva'/'eva.min'/'eva.min.js' or import Eva from 'eva'; and so on, but it doesn't work.
app.import('vendor/eva.min.js');
app.import('vendor/bootstrap.min.js');
app.import('vendor/feather.min.js');
app.import('vendor/popper.min.js');
app.import('vendor/jquery-slim.min.js');
app.import('vendor/swipe.js');
import Swipe from 'swipe';
Console usually gives me the could not find the module error.
And I don't have a deep background in programming, so I would highly appreciate if you explained the problem as simple as possible.
UPD: I found all js code as npm package (it happens that the js files weren't third-party)
https://www.npmjs.com/package/feather
https://www.npmjs.com/package/popper.js
https://www.npmjs.com/package/jquery-slim
https://www.npmjs.com/package/swipe
https://www.npmjs.com/package/bootstrap
https://www.npmjs.com/package/eva-icons
But all your responses were helpful. Anyway in the near future I expect to use third-party libraries.
A quick way is to use scriptjs and it allows you to load any javascript into your component in the following way: (I am using Yammer as an example)
import $scriptjs from 'scriptjs';
componentDidUpdate() {
//script loader
setTimeout(function(){
$scriptjs('https://c64.assets-yammer.com/assets/platform_embed.js',
() => {
window.yam.connect.embedFeed(YammerHelper.loadComments());
});
}, 1000);
}
You should get the idea how to consume it. Check their docs with lots of examples.
This is not the best solution. But one way of using the third party js is,
1) say you have a function in your js file vendor/third-party.js
someFunction = function (element) {
...
console.log("works")
};
2) Then import it in your ember-cli-build.js
...
app.import('vendor/third-party.js');
...
3) After importing restart your server.
Use the function directly in your controller/component as
window["someFunction"]
Unless the JavaScript library being used explicitly supports the import X from 'y' syntax then when you import in the build using the app.import syntax you just use it in your app just as the plugin documentation describes.
So for Swipe you would do the following.
Based on this documentation: https://github.com/thebird/Swipe
// ember-cli-build.js
app.import('myswipe.js`);
// component.js
/* global Swipe */ // This silences the linter from throwing errors...
classNames: ['swipe'],
didInsertElement() {
this._swipe = Swipe(this.element, {
option1: option1
});
}
// component.hbs
<div class='swipe-wrap'>
{{yield}}
</div>
This codes creates a component to control your swipe plugin.
This code would create a swipe object and isolate it to the component.
Again when you use the app.import you are just loading the library on boot. The library does whatever it says it will do in the docs. Sometimes they register a global object, sometimes they dont.

How do you add external javascript libraries using ES6 style imports?

I'm having trouble understanding exactly how to use older javascript libraries within newer ES6 projects. I'm looking at a React project that's been compiled with webpack, written with ES6 and transpiled with Babel. Each component follows the import * from "" notation.
There's an external javascript library I want to use within the project: https://github.com/pchen66/panolens.js. The compiled library doesn't follow ES6 export format, and only has one global object PANOLENS.
What should I do if I want to include this into my project?
This is not the best.
Include it in your html :
<script src="js/three.min.js"></script>
<script src="js/panolens.min.js"></script>
<script src="bundle.js"></script>
<script>window.PANOLENS = PANOLENS</script>
Where bundle.js is your own builded javascript code.
Then, you will be able to use PANOLENS object anywhere.
Example component :
import react, {Component} from 'react'
export default class Test extends Component {
componentDidMount(){
var panorama, viewer;
panorama = new window.PANOLENS.ImagePanorama('asset/equirectangular.jpg' );
viewer = new window.PANOLENS.Viewer(
container: document.getelementbyid('viewer-container'), // A DOM Element container
controlBar: true, // Vsibility of bottom control bar
controlButtons: [], // Buttons array in the control bar. Default to ['fullscreen', 'setting', 'video']
autoHideControlBar: false, // Auto hide control bar
autoHideInfospot: true, // Auto hide infospots
horizontalView: false, // Allow only horizontal camera control
cameraFov: 60, // Camera field of view in degree
reverseDragging: false, // Reverse orbit control direction
enableReticle: false, // Enable reticle for mouseless interaction
dwellTime: 1500, // Dwell time for reticle selection in millisecond
autoReticleSelect: true, // Auto select a clickable target after dwellTime
passiveRendering: false, // Render only when control triggered by user input
);
viewer.add( panorama );
}
render(){
return(
<div id='viewer-container'></div>
)
}
}
It doesn't really matter if the module itself follows ES6 syntax. It will either follow commonJS or AMD, both of which webpack can handle, and at worst, you can just require/import the whole file into your bundle: https://www.npmjs.com/package/panolens.js.
EDIT: This npm module/repo does use module.exports if you look at the dist.
EDIT:
Yeah, it looks like someone has forked the library and made an NPM package out of it. Have you taken a look at https://github.com/sbolel/pano. There is an ES6 example.
Install the package:
npm install --save pano
Then import:
import Pano from 'pano'
import { Page } from 'pano'
// Pano.Page === Page
const panoPage = new Page('pano')
panoPage.init()
ORIGINAL:
You could load the script asynchronously using the method below, or if you are using a bundler, it would have a way to import external scripts. For example, Webpack has Externals for this.
After doing this, you can access the the global object PANOLENS, as per the documentation. You'll want to make sure the PANOLENS object is available before using it in your application.
Add the following to your static HTML:
<script src="https://github.com/pchen66/panolens.js" async></script>
If you are planning to only use the script in a certain React component (presuming you use React), you could use a library such as react-async-script-loader. This will allow you to lazy load a script on a particular component. It has a bunch of properties that can be used to determine when the script is ready to be used.
Again, after the script has successfully loaded, you may use the library by accessing it through the global PANOLENS variable.
So you would want some kind of module shimmer. If you are using webpack you should try this:
https://github.com/webpack/docs/wiki/shimming-modules
There are similar shims for browserify too:
https://github.com/thlorenz/browserify-shim
You could also fork the repo and shim it manually something like this, the implementations may vary though.
/**
* Panolens.js
* #author pchen66
* #namespace PANOLENS
*/
var PANOLENS = { REVISION: '3' };
module.exports = PANOLENS;

Categories