MarcelWeidum
MarcelWeidum

Reputation: 145

MeteorJS javascript function defined in package is undefined

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?

Upvotes: 0

Views: 208

Answers (1)

Jankapunkt
Jankapunkt

Reputation: 8413

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.

Upvotes: 1

Related Questions