I have a small node package that I would like users to only used named imports in their project.
import { Logger } from 'logger';
However, there is nothing stopping the user from doing
import defaultImportedLogger from 'logger';
They will just learn the hard way when they find out that defaultImportedLogger is undefined because my project doesn't have an export default anywhere. Hence the default export is undefined.
If I try to import a named exports such as:
import { foo } from 'logger'
my editor will complain because foo isn't exposed. Why doesn't my editor complain in the default import situation?
The result of trying to import the default export when it wasn't defined depends on which bundler you're using. For example Rollup throws an error: "'default' is not exported by <filename>".
I don't think there's any way to prevent users from importing the default export. The best you can do is export a function which throws an error when called, with error message "Don't use the default export".
Related
I'm currently developing a TypeScript library to be used internally in my company's projects, which are a mix of JavaScript and TypeScript Node applications.
So, I want to be able to import the library's default class properly in JavaScript with CommonJS. However, I can only use my class in these programs if I import it with require('...').default.
I managed to make it work previously by adding a module.exports = MyClass at the end of the file, but the autocomplete of VSCode doesn't seem to catch up to that, still suggesting the default before showing the methods.
How can I make it so I can import my class by just using require('...') while still making sure the autocomplete is properly working?
Thanks.
EDIT:
For clarity, what I want to do is to be able to do this:
const MyClass = require('MyTypeScriptClass');
instead of:
const MyClass = require('MyTypeScriptClass').default;
Edit
I decided to not use export default when exporting from a library, since it seems to be what every other library does.
The TypeScript equivalent should be this:
class MyClass {
}
export = MyClass
Can also be inlined to export = class MyClass { ... if that is preferred.
(To import an export like this in a TypeScript project you need to set the esModuleInterop flag.)
trying to use passport-custom and the very first line, from pseudocode at npmjs, errors out:
import passportCustom from 'passport-custom';
The is no default import in index.js when I open it up under node_modules/passport-custom/lib
I must be missing something fundamental here, don't know what though
Try to use CommonJS const passportCustom = require("passport-custom") You probably have older version of Node.js which does not support ES6 modules.
There is no default export. So you will have to name the items you want to import (put them in curly braces).
//Example:
import { a,b,c,d} from 'youPackage';
//Your case:
import { passportCustom } from 'passport-custom';
Above are called named imports. When a package exports one item by default using: export default passportCustom ;, you could have use your code. You can access the code of the package to have a look for yourself.
I am building an NPM package and am looking for the best way to export my classes.
Right now, I am using this:
import {Swan} from './Swan';
import {Route, Router} from './Router';
import {View, TemplateView, IView} from './views';
export { Route, Router, Swan, View, TemplateView, IView };
This works. The only thing is, of course, each time I add a new class, I have to update the export statement.
Is there a way to export all the classes in all the files I specify without having to update the export statement here?
Is there a way to export all the classes in all the files I specify without having to update the export statement here?
There is no automatic "export everything" or export all classes in Javascript.
But, you could change how you define your classes so they are part of an internal object and you just export that object.
const myExports = {
TemplateView: class TemplateView {
...
},
iView: class iView {
...
}
};
export default myExports;
When you add a new class to this structure, it automatically becomes part of the exports.
On the other hand, I personally don't see what the big deal is to maintain the export list when you add a new item to the module that you want exported. Exports are SUPPOSED to be a thoughtful list of things that only contains the items that need to be exported and does not contain other functions used locally as part of the implementation. The only way that it can be a thoughtful list is if it's not automatic.
I have a simple application that is imported from webpack. The imported project exports a class like this...
export class BaseApp{...}
import { BaseApp } from "./MyClass"
import OtherThing from "./Other"
....
export { BaseApp, OtherThing }
Next I try to extend it in another node/express project...
import { BaseApp } from "#mine/util";
export class FullApp extends BaseApp{... }
I get...
class FullApp extends _mine_util__WEBPACK_IMPORTED_MODULE_0__["BaseA
pp"]{
^
TypeError: Class extends value undefined is not a constructor or null
How do I extend a class I am importing from Webpack?
Update here is an example project that demonstrates the issue...
https://github.com/jrgleason/simple-webpack-node
Impossible to say for certain when there is clearly much more to the source. If anyone else sees this error, the first thing to look for is circular dependencies: a file depends on some other file that (likely indirectly) depends on the first. JS must start somewhere, will not be able to ensure that a file is defined at the time that another file needs it, and will not try to go back and fill in the blanks later.
If you have more than a couple import / require statements, I recommend periodically running a checker like Madge to find and optionally visualize any loops before they become hard to undo.
npm i --saveDev madge
node node_modules/madge/bin/cli.js --warning --circular --extensions js ./
I want to develop a node module in TypeScript, but I'm having some problems with all the possible options to require, import, etc.
What I'm doing right now is having every class and interface in it's own file. So I would need to require all the dependencies which is kind of stupid, because I'm typing the class name twice, like this:
import Target = require('./Target');
export interface IFace {
getTarget(): Target.Target
}
I could write import t = require('./Target'); instead but then I need to write t.Target which I think is also pretty ugly.
And also I can't give it a module name (like FaceApp), because when I need to import two files, there's a naming conflict.
Obviously that would not be needed if everything would live in one file, but this is far from optimal I think.
So how do you guys organize your node module in TypeScript? I'd be happy to hear your suggestions.
You can avoid the name duplication by using the export = syntax. i.e. Do:
class Target{}
export = Target;
instead of export class Target.
Also grunt-ts transformers can help you with the import statement explosion : https://github.com/grunt-ts/grunt-ts/issues/85#issue-29515541
The way recommended by TypeScript is to do
export default class Target {}
and then you can do a true typescript import with
import Target from './Target'
alternatively, you can rename it
import NewName from './Target'
Also note that you can export multiple things from a file if they are related
export class SomeClass {}
export class OtherClass {}
And that on import, you can change the names
import { SomeClass as MySomeClass, OtherClass as MyOtherClass } from './Target'