BootFile.default is not a function



  • I have a small JS library that was written for Node.JS that I need to import into my Quasar project. The library works fine when bundled into the bundle.js file of a standard Webpack project, but in Chrome I get Lib1-boot.default is not a function (my Quasar boot file) when I try to use the library in my Quasar project.

    Here’s my Quasar (Quasar CLI v1.0) setup:

    I’ve successfully added many boot files to other projects so I’m familiar with the process. In this case, I’ve created the boot file with quasar new boot 'Lib1-boot'. That file contains the following:

    // src/boot/Lib1-boot.js
    
    import Lib1 from '../plugins/Lib1.js'
    
    export default async ({ Vue }) => {
    Vue.use(Lib1)
    };
    

    I’ve added Lib1-boot to my Quasar.conf boot: [] section with my other boot files (all those boot files, including Axios, work fine). I’ve added import Lib1 from '../plugins/Lib1.js to the top of the <script> block of Index.vue with my other imports. (I use VSCode so it’s easy to see that all my imported files are successfully detected and loaded when I start quasar dev and my app loads fine. )

    For context, here’s a simplified version of the code in my Lib1.js file:

    // src/plugins/Lib1.js
    
    // import library functions
    
    var pb = require('./Lib2.js'); // A dependency of the Lib1 file in the same directory, which I've also created a `Lib2-boot.js` file for in `src/boot`.
    
    Object.assign(module.exports, Lib2); // I think Quasar/Vue is probably choking on this.
    
    module.exports.createMeParent = function(args) {
        var myFunc = createMe(args);
        return {
            getStuff: function(data) { return myFunc(data, pb.getStuffReq); },
    
     // lots of other function definitions that should be imported from Lib2  . . . .
    

    In my Index.vue template, when I click the button that’s attached to my myFunction() method (which tries to call getStuff() and other functions exported by Lib1), I can see from the call stack that my method is trying to find the functions in my Lib1.js file, but it’s not finding them because of the Lib1-boot.default is not a function error. So I know I’m calling the function from my method correctly, but it’s simply not finding any of the exported functions in Lib1.js.

    I suspect that these import statements in my Lib1 file . . .

    // src/plugins/Lib1.js
    
    var pb = require('./Lib2.js');
    Object.assign(module.exports, pb);
    

    . . . need to somehow be adapted to the logic of my Lib1-boot file so that all the functions in the module.exports object are recognized and passed to Vue. I understand there’s no default export defined in my lib files, which is probably part of the problem, but my knowledge of Quasar boot files (and Node.JS syntax) doesn’t go beyond the examples that I’ve seen in the docs and various forum posts; so I’m not sure how to resolve the default export issue in this case. Rewriting the entire Lib1.js and Lib2.js files doesn’t seem like it should be necessary.

    As I’ve been troubleshooting, I noticed that some libraries (e.g., Axios) are imported into Quasar with a different export default syntax using Vue.prototype... instead of Vue.use, e.g.:

    export default async ({ Vue }) => {
      Vue.prototype.$axios = axios
    }
    

    So I tried using the same Vue.prototype.$Lib1 = Lib1 syntax, but that didn’t help.

    I’ve spent a long time troubleshooting this. I think I’m close to resolving it, but I need some help please on how to properly import all the Lib1.js functions into my Quasar project. Please help!



  • Looks like it should be export default when looking at this: Lib1-boot.default is not a function



  • Thank you for your reply.

    It seems like the problem is caused because the functions in the module.exports object in the Lib1 file are not being imported properly by Quasar/Vue because the boot loading syntax in my src/boot/Lib1-boot file is not written with the syntax that the Quasar boot process is looking for.

    Does anybody understand why the Lib1.js functions are not being imported with the standard export default syntax?



  • UPDATE: I was able to successfully import all the functions from my Lib1 module (and its dependencies in Lib2) by simply bypassing the boot files and importing them directly into my Index.vue file like this:

    import { func1, func2, func3, func4 . . . funcN} from './Lib1'
    

    After solving a config issue with Babel, I realized the main issue was I needed to import them all by name because there is no default export in Lib1.

    So everything works this way now, but is there any significant disadvantage to doing it this way other than the inconvenience of having to import the modules in every page/component that I need them in? In other words, am I missing out on any other significant benefits by importing the modules directly into my pages/components, e.g., tree-shaking, code-splitting, etc.?

    Finally, now that we know what the problem was, can somebody please explain how I would apply the named imports to the boot files? So far, I’ve only seen boot file configurations like this . . .

    import Lib1 from '../plugins/Lib1.js'
    
    export default async ({ Vue }) => {
    Vue.use(Lib1)
    };
    

    . . . but what do we do when there is no default export? When I tried to import them in the boot file like I can in the page/component <script> block, it would not compile. So, as soon as I know how named imports would work in the boot files I think I can use the boot files, too, which would be great.



  • @Julia boot file https://quasar.dev/quasar-cli/cli-documentation/boot-files#Introduction, you have access to vue/store/route before it’s instantiated, you can use someting like binding your lib to a vue prototype then you can call it using this.$yourLib.someFunction somewhere in your sfc file. you can change probably how you do the exports on your lib, or maybe try to import it in boot file using a wildcard ie. import * as lib1 from 'yourPath'. tree shaking is ok tho if you don’t need to instantiate anything before vue app, since you might not want to use some of your function. some reading https://vuejs.org/v2/cookbook/adding-instance-properties.html.


  • Admin

    Don’t mix require statements with import. Use import along with export ... syntax.



  • Thank you all for your feedback!

    @metalsadman Your suggestions guided me to the solution I was hoping to find. Now I have all the imports declared in the boot file and it’s easy to access all the functions from any component with this.$Lib1… Thank you!


Log in to reply