module.exports does not contain a default export - javascript

I am trying to export my theme in my react app using `module.exports =
module.exports = {
defaultFontColor: "#282828",
name: "Planswell",
primary: primary,
deemphasizedPrimary: "#e7f6ee",
secondary: "#E4A432",
danger: "#DF5F2B"...}`
in my file whatever.js, and i try to import it in another file using import whatever from "themes/whatever.js";
All was working well, but i updated Babel, and am now getting the error Attempted import error: 'themes/whatever.js' does not contain a default export (imported as 'whatever').
What changed with Babel that caused this error? And how do I fix it?

If the only export in your whatever.js is
module.exports = {mod1, mod2, ...}
Then, assuming whatever is actually a module in your file, you should have never been able to import it using
import whatever from "themes/whatever.js";
The only way that would be possible is if in your whatever.js you did:
export default whatever;
Otherwise, you will have to destructure the import like so:
import {whatever, mod1, mod2, ...} from "themes/whatever.js";
Again, all this assumes that whatever is actually a module inside your whatever.js file e.g const whatever = () => {.... You don't make that part clear.

The error you're getting should help you guide your way. When using module.exports = {...} syntax, the default export is the object.
You should try importing specific exported properties of the module such as import { someModule } from 'themes/whatever.js'. Optionally you can use
import * as whatever from 'themes/whatever.js'
// Use it
whatever.myFunction()
Babel is pretty complex tool so I would check from which version you upgraded to and then looked at the change log to see what has changed. Babel has plethora of presets and plugins so it could be any combination, sorry no simple answer here.
To me it seems like perhaps you're using some different type of module.
Maybe you are using #babel/preset-env with combination of browserslist settings and you transpile to ES6 modules?

in your whatever.js you have exporting the as an object that contain your component so you have to export it like this
import {whatever} from "themes/whatever.js";
for your example to work you have to export your component without brackets
export {whatever}

Related

How do you find out which functions are exported by a node/npm package?

Following my earlier question, and the Mozilla documentation on import, I now understand that I must do something like the following to use the functionality in a module:
import * as name from "module"; or
import {functionName} from "module";
Coming from using CommonJS, I never thought about which functions were exported by a package because I just used to require them like:
const vueServerRenderer = require('vue-server-renderer') // get the module
vueServerRenderer.createRenderer() // use a function in that module
How can someone find out which functions are being exported by a module such as express or vueServerRenderer so I know how to use the correct import statement like:
import express from 'express' instead of import * as express from 'express'?
You need to read the module source.
Every export statement exports something. It may be a function, an array, a string, a class etc.
Every export statement without default needs to be destructured on import:
import { NonDefaultThing1, NonDefaultThing2 } from 'somewhere'
An export statement with default must be imported directly without the {}:
import DefaultThing from 'somewhere'
Some modules have default export but also non-default exports. You can pick and choose what to import:
import DefaultThing, { NonDefaultThing7 } from 'somewhere'
If you use an IDE that can parse javascript such as Microsoft Visual Studio Code you can get autocompletion/intellisense of the import statement. There are even plugins that does auto-import: just use a class or function or something from a module and it will automatically add the required import statement at the top of your file.
TLDR: The default export.
Say a particular library named "module" has the following code
function functionName() {
// function body
}
export default functionName;
Now, in your code, if you put
import blah from "module";
then blah will point to functionName.

export was not found -- but names still work

I'm sure this is obvious, but I'm not seeing why this isn't working at the moment...
I have a file in a Vue project that exports keycodes in a couple different formats, one to be used for constants (allCodes) and another to be used for Vue (keyCodes):
export default {
allCodes,
keyCodes
};
When I try to import one of them using deconstruction like this, I get an error:
import { allCodes } from '#/helpers/keycodes';
21:17-25 "export 'allCodes' was not found in '#/helpers/keycodes'
warning in ./src/mixins/GlobalKeyPressHandler.js
However, importing then referring to the key by name works:
import object from '#/helpers/keycodes';
console.log('allCodes', object.allCodes);
What gives?
If you want named exports it should be
export {
allCodes,
keyCodes
};
Currently you are exporting an object as default.
BTW "I try to import one of them using deconstruction like this" if you mean that you are trying to use destructuring assignment in imports it wont work. Named import statement is not object destructuring though it looks alike in simplest case.
If you want to have default export than you should make assignment below the import statement
export default {
allCodes,
keyCodes
};
// importing side
import keycodes from '#/helpers/keycodes';
const { allCodes } = keycodes;

NPM package: best practices and exposing multiple import paths

I created an NPM package that uses Webpack and Babel for transpiling/bundling.
In my package.json, I've got main set to "main": "build/index.js". And in my Webpack config, I have entry set to entry: { app: './src/index.js' }. My entry file is shown below.
Everything works fine when the package is installed. However, with this setup, two import paths are exposed for every helper:
This is a problem for editors that support auto imports, since they will sometimes auto import from 'my-package/build/utils/helper1' rather than the preferred path of 'my-package'.
So, two questions:
Is there any way to prevent the longer import path from being exposed?
What is considered best practice when creating NPM packages. Is my setup acceptable, or should I be doing something different?
Entry File:
import helper1 from './utils/helper1';
import helper2 from './utils/helper2';
export {
helper1,
helper2,
};
const myPackage = {
helper1,
helper2,
};
export default myPackage;
you can utilize Webpack resolve
I often use the first way:
export {
helper1,
helper2,
};
Recently, I found that we can use Object.freeze() to export. This is a good article.
I would suggest probably merge your helper1 and helper2 in one file and name it helpers, then you can put them in the class myPackage so that you then export them as a module like this
import myPackage from './utils/helper';
// OR import {helper1, helper2} from './utils/helpers';
export default class myPackage {
helper1,
helper2,
};
OR
import {myPackage} from './utils/helpers';
// OR import {helper1, helper2} from './utils/helpers';
module.exports.myPackage = (helper1, helper2) => {
this.helper1 = helper1;
this.helper2 = helper2;
};
I hope this helps.

Why does require not behave the same as import when same structure is given

It seems I have a fundamental lack of understanding when it comes to import vs require. From what I've read I know the difference is that require is based on a module loaders like CommonJS while import is actually an ES6 feature.
Assuming the following:
import ExamplePost from 'example-post.md'
This is an example import with MDX JS as appropriate loader and I
set this in my React render function like:
render () {
return <ExamplePost />
}
The above works perfectly fine, but
as I want to dynamically load different Markdown files and I have read that ES6 import are static I intended to go like:
let postName = 'example-post'
const ExamplePost = require(`${postName}.md`)
Unfortunately it doesn't work, I am getting: ExamplePost is not defined
I'm setting both examples at the top of the document. I also inspected both versions and I can see a difference in the outcome:
ES6 import returns: [Function]
Require returns: Object [Module] { default: [Function] }
Help to get me on the right track on why the require above does not work the same?
You import the default export of module and require the module itself.
const ExamplePost = require(`${postName}.md`).default
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
Also check Can't require() default export value in Babel 6.x

How to fix eslint errors in meteor with react tutorial

I've followed meteor tutorial, and when I finished I've decided to install eslint.
Now I see
Prefer default export import/prefer-default-export
for this line: export const Tasks = new Mongo.Collection('tasks'); in imports/api/tasks.js file. It contains also some Meteor methods. Here it is full source code: tasks.js.
I was trying to fix this eg. with
const Tasks = new Mongo.Collection('tasks');
export { Tasks as default };
But then browser stopped rendering the view.
Here is the server/main.js content, which imports tasks.js:
import '../imports/api/tasks.js';
How can I fix lint error without breaking applications functionality?
You could add an .eslintrc file to your project root and adapt the rule:
{"rules": {"import/prefer-default-export": ["off"]}}
UPDATE:
If you want to keep the rule, then you need to export Tasks as default like so:
const Tasks = new Mongo.Collection('tasks');
export default Tasks;
Now you have to change all the imports in the rest of your codebase from a named import to a default import. The named import looks like this
import { Tasks } from '/imports/api/tasks';
see e.g. here, whereas the new default import has to look like this
import Tasks from '/imports/api/tasks';
This should do it. Let me know if it works for you.

Categories