Reputation: 1512
Only started using Meteor for the first time about a week ago so still feeling my way around.
I've come unstuck with how to use jQuery plugins installed via npm.
I've run :
meteor npm install overlayscrollbars --save
Which has added it to my package.json
file...
"dependencies": {
"@babel/runtime": "^7.0.0-beta.51",
"meteor-node-stubs": "^0.4.1",
"overlayscrollbars": "^1.5.0",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"simpl-schema": "^1.5.0"
},
...but I have no idea how to use it inside Meteor?
I'm not using the Blaze templating engine, I'm using React instead.
I found some posts answering a similar question but they were all related to using Blaze and on very old outdated versions of Meteor.
I've got jQuery running, tried and tested with some console.log outputs, and tried adding the js plug-in file in main.html
with standard <script>
tags but Meteor doesn't like this at all. I also tried importing it into the project :
import overlayScrollbars from 'overlayscrollbars';
And also tried :
const overlayScrollbars = require('overlayscrollbars');
But these did nothing, and to be honest I'm pretty sure that this was entirely the wrong approach anyway.
I also tried adding the entire plug-in source to the client side app.js
but again this did nothing.
When viewing the source of my app in a browser I can see that the file I want to use isn't even being loaded by Meteor - PasteBin - Just an answer on how to get this part done would be a massive help.
I know it's not working as I'm seeing console errors when I try to initiate the plug-in, saying that the function doesn't exist.
I can't seem to find a guide anywhere.
Could somebody please either point me in the right direction of some docs or explain the procedure I need to follow to use any jQuery plug-in inside Meteor please?
** Edit to show how I'm calling it in main.js (is this the correct syntax for using jQuery in Meteor?)
Meteor.startup(() => {
Tracker.autorun(() => {
ReactDOM.render(<p>Sidebar</p>, document.getElementById('sidebar'));
ReactDOM.render(<App/>, document.getElementById('app'));
$(function() {
$('.main-content').overlayScrollbars({ });
});
})
});
** Edit after answer...
The issue I was having was due to not importing the plug-in on the correct page, I was only importing it on the app.js file and not the template that rendered the component.
Also, to clear up the way it is initiated (dropping the doc ready) the call was moved into the component like this :
componentDidMount() {
$('.main-content').overlayScrollbars({ });
}
Thanks to Fred for all the help. From what I've gathered with my limited exposure to Meteor so far, it's a fantastic platform and I'm sticking with it for sure, but you really have to keep up with the updates as things break between versions quite often as the methods are changed. In other words, if you're a newcomer like me, using the latest version, don't bother trying to follow any Meteor tutorials that are more than a year old unless you are prepared for a fair bit of debugging and digging through the docs to see why the old code no longer works. But then again, doing it this way is ultimately going to give you a much broader knowledge base which is what we are all striving for :)
Upvotes: 4
Views: 425
Reputation: 5671
I'll take you through the steps of working out how overlayscrollbars
works so we can understand the correct way to include it in your app.
I start by looking at the source's package.json
file, specifically the main:
key which points to js/OverlayScrollbars.js
I look at js/OverlayScrollbars.js
to see if it exports a module. You can see on lines 14-21 that it uses the UMD pattern to specify it's exports.
Because Meteor uses CommonJS for module management, the module.exports
object is what you get when you import something from 'overlayscrollbars';
I also notice at the bottom on line 6039 that it puts OverlayScrollbars
onto the global scope even if it's in a module environment.
And if jQuery is detected, it also registers as a jQuery plugin on lines 6042-6058
Now we know that we can import it if we want, but it should also be available globally.
The next key thing is to make sure the module runs, so that it actually ends up on the global scope. My preference for this is to use import syntax in each file that depends on it, so that when you end up changing that file, or testing it in isolation, it will bring all it's dependencies along for the ride.
So how DO I import it?
You were completely right with import overlayScrollbars from 'overlayscrollbars';
So the question now is why didn't it work?
I started a quick new project with meteor create test
and added the package with meteor npm install overlayscrollbars --save
and added import overlayScrollbars from 'overlayscrollbars';
to /client/main.js
.
overlayScrollbars
was usable in that file.OverlayScrollbars
was on the window / global scopeoverlayScrollbars
was a method on jQuery objectsSo the issue must be something else. What error are you seeing? Where have you put the import statement?
Looking at your calling code:
You don't need the autorun as you're not calling any reactive data sources. (And if you did it would cause unwanted whole app re-renders)
I'd move the scrollbar code into the componentDidMount
hook of the component that renders .main-content
. that way the element is guaranteed to exist when the code is run.
There's no need to wrap it in a $(function(){...})
block. The document.ready event isn't relevant for React apps
One last edit
For jQuery plugins that don't have a UMD pattern usually a straight import 'plugin-name';
will work.
If that doesn't work (often because of a broken UMD section), in Meteor you can copy the files into a client/compatibility/
folder and they will be loaded without any module wrapping, exposing their variables to the global scope as a last resort. This is the equivalent of adding a script tag directly
Upvotes: 2