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 getLib1-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.confboot: []
section with my other boot files (all those boot files, including Axios, work fine). I’ve addedimport Lib1 from '../plugins/Lib1.js
to the top of the<script>
block ofIndex.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 startquasar 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 callgetStuff()
and other functions exported by Lib1), I can see from the call stack that my method is trying to find the functions in myLib1.js
file, but it’s not finding them because of theLib1-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 inLib1.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 themodule.exports
object are recognized and passed to Vue. I understand there’s nodefault 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 thedefault export
issue in this case. Rewriting the entireLib1.js
andLib2.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 usingVue.prototype...
instead ofVue.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 theLib1
file are not being imported properly by Quasar/Vue because the boot loading syntax in mysrc/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 standardexport default
syntax? -
UPDATE: I was able to successfully import all the functions from my
Lib1
module (and its dependencies inLib2
) 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
inLib1
.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. -
Don’t mix
require
statements withimport
. Useimport
along withexport ...
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!