-
Notifications
You must be signed in to change notification settings - Fork 130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use CommonJS export for "module": "node16" + ESM #171
base: master
Are you sure you want to change the base?
Conversation
The change in simov#19 to switch to an ESM-style export seemed like the right solution at the time. However, module systems have evolved since then and the `export default` fails when "module": "node16" is configured in tsconfig.json Since `slugify` is a CommonJS module, it seems like using a CommonJS-style export is indeed the right choice for this package.
cc @andrewbranch in case you can see an error in my logic about |
slugify’s JS uses a UMD wrapper that includes module.exports = factory()
module.exports['default'] = factory() so technically the declare module slugify {
type ExtendArgs = {
[key: string]: any;
}
export function extend (args: ExtendArgs): void;
const _default: typeof slugify;
export { _default as default };
}
declare function slugify(
string: string,
options?:
| {
replacement?: string;
remove?: RegExp;
lower?: boolean;
strict?: boolean;
locale?: string;
trim?: boolean;
}
| string,
): string;
export = slugify;
export as namespace slugify; Note the |
Also, I will note that this kind of problem is not yet detectable by https://arethetypeswrong.github.io, but it’s next on my list. |
Edit: I realized that the issue I described in my comment was not caused by the changes proposed in this PR. Actually, merging this PR will be solving my problem |
Is there a reason to use I think it’s purely stylistic, but I’m curious to know if there are any differences. I would write it like this: declare namespace slugify {
type ExtendArgs = {
[key: string]: any;
}
interface Options {
replacement?: string;
remove?: RegExp;
lower?: boolean;
strict?: boolean;
locale?: string;
trim?: boolean;
}
}
interface Slugify {
(string: string, options?: slugify.Options | string): string;
default: Slugify;
extend: (args: slugify.ExtendArgs) => void;
}
declare const slugify: Slugify;
export = slugify;
export as namespace slugify; |
There’s no difference, and |
Hi there 👋 First of all, thanks for
slugify
, it's very useful!The ESM-style export (
export default slugify
) causes an error when using the"module": "node16"
option intsconfig.json
and"type": "module"
inpackage.json
:Demo on StackBlitz - run
yarn tsc
in the Terminal at the bottom to reproduce:https://stackblitz.com/edit/node-wshdsj?file=tsconfig.json,package.json,index.ts&file=tsconfig.json,index.ts
Background
The change to ESM-style export in #19 seemed like the right solution at the time, because bundlers such as webpack +
ts-loader
did not understand the CommonJS syntax (export = slugify
).However, module systems have evolved since then and now the
export default
fails when"module": "node16"
is configured intsconfig.json
inside of a project which is an ES Module ("type": "module"
inpackage.json
).Since
slugify
is a CommonJS module, it seems like using a CommonJS-style export is indeed the right choice for this package.See more information about the problem of misconfigured declaration files in packages here:
default
CJS or ESM exports with modulenodenext
. microsoft/TypeScript#49189 (comment)