0

I have created a custom package in Meteor adding javascript to the application.

My package.js:

Package.describe({
    name: 'markel:theme',
    version: '1.0.0',
    summary: 'Theme package',
});

Package.onUse(function(api) {
    // Import all JS files required by the template

    api.addFiles(['assets/js/custom.js']);
});

In custom.js:

function theme_test() {
    console.log('Theme test');
}

When meteor loads the package in the application, it places the function in IIFE. So the javascript is in (function(){here}). So my function will return undefined.

How can I define that function and use it?

7
  • Do you intend to import it? Please describe what you intend to do with it. Commented May 25, 2020 at 5:35
  • @Jankapunkt I want to use the functions I define in custom.js. So if I call theme_test() in a template helper it logs 'Theme test' to the console. Commented May 25, 2020 at 15:20
  • But the code neither shows, whether it is exported or added to global scope. The IIFE part in your example is hard to grasp. Can you may extend the code so it can be easily reproduce? Commented May 25, 2020 at 15:22
  • @Jankapunkt if you know how to install a local package, this is everything you need to reproduce it. Commented May 26, 2020 at 15:34
  • What I mean is, how do you make theme_test available to your project? Usually you either use export or add it to global, in this example it is just in scope of custom.js there is no way to use it outside of this module. Commented May 26, 2020 at 15:36

1 Answer 1

1

I hope one of these options will solve your issue, as I found it hard to reproduce any undefined values.

Option 1 - Use modules

While you can auto-add files via api.addFiles you can optionally still export them explicitly:

package.js

Package.describe({
    summary: 'Theming',
    version: '1.0.0',
    name: 'marcelweidum:theme',
    git: 'https://github.com/MarcelWeidum/stack-question.git'
});

Package.onUse((api) => {
    api.use('ecmascript') // required to use import/export
    api.addFiles([
        'js/custom.js'
    ], 'client');
    api.mainModule('main.js')
});

package/js/custom.js

export const theme_test = function theme_test () {
    console.log('Here am I!');
}

console.log('Loaded');

package/main.js (in root folder of the package)

export { theme_test } from './js/custom'

client/main.js

import { theme_test } from 'meteor/marcelweidum:theme'
theme_test()

will give you on the console:

Loaded
Here am I! 

Option 2 - use api.export

You can export the theme using an implicit global that is made accessible immediately using api.export:

package.js Package.describe({ summary: 'Theming', version: '1.0.0', name: 'marcelweidum:theme', git: 'https://github.com/MarcelWeidum/stack-question.git' });

Package.onUse((api) => { api.addFiles([ 'js/custom.js' ], 'client'); api.export('MyTheme') });


*package/js/custom.js*

function theme_test () { console.log('Here am I!'); }

MyTheme = MyTheme || {} MyTheme.theme_test = theme_test

console.log('Loaded');


*client/main.js*
```javascript
MyTheme.theme_test()

will give you on the console:

Loaded
Here am I! 

Option 3 - Import file explicitly

This will hover load the file's content only at the point it's imported

package.js Package.describe({ summary: 'Theming', version: '1.0.0', name: 'marcelweidum:theme', git: 'https://github.com/MarcelWeidum/stack-question.git' })

Package.onUse((api) => { api.use('ecmascript') })


*js/custom.js* (in root folder of the package)
```javascript
export const theme_test = function theme_test () {
    console.log('Here am I!');
}

console.log('Loaded');

package/js/custom.js

export const theme_test = function theme_test () {
    console.log('Here am I!');
}

console.log('Loaded');

client/main.js

import { theme_test } from 'meteor/marcelweidum:theme/js/custom'
theme_test()

will give you on the console:

Loaded
Here am I! 

Option 4 use bare option, in case the file is used by a compiler plugin:

If you don't want the file to be wrapped inside a closure, for example because it will be used by a custom compier plugin, then add the bare option:

Package.describe({
    summary: 'Theming',
    version: '1.0.0',
    name: 'marcelweidum:theme',
    git: 'https://github.com/MarcelWeidum/stack-question.git'
});

Package.onUse((api) => {
    api.addFiles([
        'js/custom.js'
    ], 'client',  { bare: true });
});

This will still load the file but you will have to use your isobuild plugin to handle the file.

Sign up to request clarification or add additional context in comments.

2 Comments

Only option 1 is working, but to do that for every function is not doable. For example: if I want to load bootstrap.js in my package, I can't make for .tooltip() an export and every other function. I know there is already a package for bootstrap but it is just an example.
If you want the Bootstrap tooltoip class you can use option 3: import { Tooltip } from 'bootstrap/js/src' which imports the class Tooltip for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.