Comments (41)
FWIW I was able to work around setting a resolve alias in the webpack config
alias: {
deepmerge$: path.resolve(__dirname, 'node_modules/deepmerge/dist/umd.js'),
}
from deepmerge.
Defining alias in Webpack is working, but just for information, modules may not be in current project directory (case of workspaces for example). So it would be better not to define absolute path in Webpack configuration. This is how I did in my project:
alias: {
deepmerge$: 'deepmerge/dist/umd.js',
},
from deepmerge.
Could this be reopenend?
The problem still persists and I don't feel like const merge = require('deepmerge').default
is an ideal solution.
My app won't compile when I use import merge from 'deepmerge'
with TypeScript 2.8 and Webpack 3.10.0, so it's not just affecting jest tests.
from deepmerge.
I just added deepmerge
to my Ionic/Angular TypeScript project and hit the
Error:(25, 8) TS1192: Module '"node_modules/deepmerge/index"' has no default export.
The project have lot of external dependencies and it would be great to have this fixed regardless possible specific webpack (or other tools) limitations.
the workaround for me now is to add in tsconfig.json
:
"allowSyntheticDefaultImports": true
also to avoid IDE errors I had to add the above also in tsconfig-ng.json
which is being used by unit test.
from deepmerge.
@TehShrike I'm using webpack
. The error is TypeError: deepmerge is not a function
.
See code at https://github.com/richardschneider/ipfs-encryption/blob/master/src/keychain.js#L80
from deepmerge.
Just to update the issue, I have solved this by importing explicitly the file I want, es.js
, like this:
import merge from '../node_modules/deepmerge/dist/es.js';
I am not particularly happy about this, because if the name or path to the file change, the import will break. It is still the best solution I could find.
I have asked a question on StackOverflow to see if anybody had any insights to offer, but no answers thus far.
I guess you can close this issue if you have nothing to add.
Thanks.
from deepmerge.
I was also having this problem w/ Jest (also using TypeScript, but using Rollup to bundle my library), and I came up w/ a different solution that might work for other Jest users until jestjs/jest#2704 is merged/released. I created a manual mock that require()
s deepmerge and then exports
it out:
// __mocks__/deepmerge.ts
// (where __mocks__ is a sibling to node_modules)
import deepmerge = require('deepmerge')
export default function merge(...args) {
return deepmerge(...args)
}
Then I just use import merge from 'deepmerge'
in my source code. When running tests, Jest resolves that to the above mock, but during builds, Rollup resolves that to the actual ESM build of deepmerge.
FWIW, @TehShrike I think you're doing everything right on the package.main
/package.module
front. I think my problems would be solved if Jest was able to respect the module
field. Also, I'm not using the DefinitelyTyped typings, so ¯_(ツ)_/¯
from deepmerge.
A full-TS option (with better typing as well): dojo/framework/util
from deepmerge.
import * as merge
is incorrect - assuming your bundler is picking up the ES module, then you're loading the ESM build of the package, which only exposes a default export. import merge from 'deepmerge'
is correct.
I would guess that there is different bundling/module loading happening between typescript and jest. I'm not familiar with either of them, but my clue to you is to make sure that they're both either paying attention to the module
field in deepmerge's package.json (if you want them to pick up the ESM version), or they're both ignoring it (if you want them to pick up the UMD version).
from deepmerge.
I'm not using TypeScript, just JS on the browser and on node. v2.0.2 works on node, but fails with the error on a browser. Reverting to v1.5.2 works on both environments.
from deepmerge.
@richardschneider What bundler are you using? What is the error message?
from deepmerge.
I couldn't find any webpack config in that repo, but I'm no Webpack expert anyways.
In any case, I can guess at the problem pretty easily - your Webpack is configured to load in the ESM module, and is probably exposing default exports as a default
property instead of the object you get when you require
.
There are lots of ways you could fix this - you could const deepmerge = require('deepmerge').default
, or you could switch your project over to using ES modules and do import deepmerge from 'deepmerge'
, or you could configure Webpack to ignore the module
setting in package.json and just pull in main
, since it looks like you don't care about ES modules, or you could configure Webpack to return the default export as the object returned by require
instead of returning { default: deepmerge }
.
If you want your un-built code to work in node.js, I'm guessing you'll want to do one of the two latter options.
from deepmerge.
@GioSensation You still haven't responded to my earlier message - it looks like you have two bundler environments, and they're both resolving modules differently. This doesn't have anything to do with this package using Rollup to bundle, it has to do with your bundlers respecting the main
vs module
fields in package.json.
A quick search of issues in the Jest repo turns up this: jestjs/jest#2702
It looks like somebody in that thread figured out a workaround for Jest.
from deepmerge.
Thanks. I will look into it and wait for the Jest team to integrate that pull request.
Cheers!
from deepmerge.
As long as your bundler respects the module
field in package.json (which webpack claims to support), everything should work fine.
The package.json's module
field points to es.js, which is a traditional ES module that exports a single default.
The package.json's main
field points to umd.js, which is a bog-standard UMD file compatible with CommonJS and AMD bundlers.
Which one of those do you want your bundler to pick up? That is up to your project's configuration.
As far as I know, deepmerge's two entry points are the epitome of bundler-friendliness. Any issues should be the result of a misconfiguration or a bug in the bundler that you're using.
I don't know if it's a configuration issue or a bug, but it sounds like some combination of Typescript + Webpack has an issue out of the box.
from deepmerge.
@Tarnadas
The issue with typescript is that the types are wrong.
If you edit the file index.d.ts from node_modules/types/deepmerge and change the export from
export = deepmerge;
to export default deepmerge
you can import it as import deepmerge from 'deepmerge'
If you want to import as import merge from 'deepmerge'
you need to replace all references in that file from deepmerge to merge.
I am not sure if the typings reflect the most up to date version of the library. There is only one method that I use and for that one is working.
from deepmerge.
ooooh, is that why people are having difficulty with TypeScript?
Where are people getting these types from? Can somebody update them?
Does Typescript pull from module
by default?
from deepmerge.
There is a single repository that most common libraries types are there. It's mostly updated and maintainted by the community. https://github.com/DefinitelyTyped/DefinitelyTyped. The issue is that a lot of times they are not up to date with the library and this can cause issues when compiling.
In this case the problem is more with how TypeScript import works. TypeScript threats CommonJS/AMD/UMD modules in the same way as ES6 modules. When you do import * as merge from 'deepmerge'
is the same as merge = require('deepmerge')
. This doesn't work for your library.
The other way would be import merge from 'deepmerge'
which is the same as merge = require('deepmerge').default
. This would work for your library, but the typescript compiler has a configuration option called noImplicitAny. If this option is enabled the typescript does not compile if the type is any. That's the case for your library since you don't have typings.
This option is not enabled by default, but since @Tarnadas was complaining about compiling issues, I figured that this was enabled for him. I also assumed he was using the types from DefinelyTyped. That's why I suggested changing that file.
from deepmerge.
I'm having this issue too but deepmerge is being used by a transitive dependency so I can't change the import/require of the function. Any ideas?
from deepmerge.
I'm at a disadvantage here because I'm not familiar with TypeScript's module resolution. I'm also not terribly motivated to spend a day learning about it to fix this issue :-x
deepmerge offers a good import experience for both CommonJS consumers (setting module.exports
to a single function) and ES Module consumers (exporting the function as the default export).
I don't see any reason to change that in order to facilitate TypeScript. Besides, as more modules start shipping ES Modules, this problem will keep happening to TypeScript users.
That said, it would be nice to know how to fix it.
Are the typings on DefinitelyTyped correct? Could they be changed to fix the issue?
Should an issue be opened on TypeScript? A quick search turns up at least a couple issues related to CommonJS/ESM interop ({#3337](microsoft/TypeScript#3337), #2719), there may be some clues in there.
@pacey, does the library that is consuming deepmerge use the require
or import
syntax? Does the issue only happen when require
is used? How does TypeScript decide whether to use main
versus module
?
If there is some way to work around this TypeScript issue by fiddling with Webpack/Babel config, it would be good to get it on record here.
from deepmerge.
It may also just be an issue with Webpack. webpack/webpack#5756
from deepmerge.
Yeah it's quite possible to just be a Webpack issue @TehShrike. I'll try and get webpack/webpack#5756 resurrected!
from deepmerge.
@pacey can you make a bare-bones reproduction in a public repository that is just a single-file app that imports deepmerge and gets bundled with webpack?
from deepmerge.
I'm also getting this issue, but not with typescript: #97
from deepmerge.
I opened an issue with Webpack: webpack/webpack#6584
from deepmerge.
Cool - that's probably worth putting into the readme until the Webpack issue is fixed.
from deepmerge.
if you're just extending simple objects you can quickly roll your own solution, e.g:
export const deepObjectExtend = function (target: any, source: any) {
for (let prop in source) {
if (prop in target) {
deepObjectExtend(target[prop], source[prop]);
} else {
target[prop] = source[prop];
}
}
return target;
};
from deepmerge.
'is-mergeable-object' should be a dependency not dev-dep, shouldn't it?
from deepmerge.
The output is bundled with rollup before deploying, so is-mergeable-object
's code is included in the deployed version. You can see isMergeableObject
inlined in the version deployed to npm on unpkg.
from deepmerge.
I have a similar problem where it's looking in all places, just not the node_modules:
with
import merge from 'deepmerge'
it gives
ERROR in /Users/-----/.ghq/github.com/mesqueeb/VuexEasyFirestore/src/utils/setDefaultValues.js
Module not found: Error: Can't resolve 'deepmerge' in '/Users/-----/.ghq/github.com/mesqueeb/VuexEasyFirestore/src/utils'
@ /Users/-----/.ghq/github.com/mesqueeb/VuexEasyFirestore/src/utils/setDefaultValues.js 1:0-29 11:9-14
@ /Users/-----/.ghq/github.com/mesqueeb/VuexEasyFirestore/src/module/actions.js
@ /Users/-----/.ghq/github.com/mesqueeb/VuexEasyFirestore/src/module/index.js
@ /Users/-----/.ghq/github.com/mesqueeb/VuexEasyFirestore/src/index.js
@ ./src/store/store.js
@ ./src/store/index.js
Or should I open a new issue?
I too am able to fix the issue by writing
import merge from '../../node_modules/deepmerge/dist/es.js'
instead. But I don't think this is ideal. I'm not sure why this is happening only to deepmerge, not to other npm packages...
from deepmerge.
huh, that's super-weird. That does seem like a separate issue, since it just has to do with resolving the package, instead of returning the CJS versus ESM version of the package.
from deepmerge.
@TehShrike
Yeah, I'm not sure what the problem is. Maybe because I'm linking with npm link
to this seperate package I'm working on where I use the deepmerge
. However, other npm modules work fine there...
I also tried editing the main
prop in the package.json of deepmerge to the es version. Didn't work.
Once I am done developing, & rollup my package, i'll let you know if anything has changed.
from deepmerge.
@TehShrike
I was able to find exactly what the problem was.
I was working on an npm package which had recently added deepmerge
as a dependency.
However through npm link
I was testing my npm package inside another package which I was doing a webpack dev hot reload on.
Then it hit me. if I try to npm i deepmerge
in this package where I have the webpack running it might work!
And yes it did!
To all people trying to test deepmerge
inside another package which is being linked to yet another using webpack hot reload, don't forget to npm i deepmerge
in the package having the webpack hot reload enabled.
from deepmerge.
I'm having the same problem as @GioSensation where import merge from 'deepmerge'
is working fine in an Angular project but fails when running tests with Jest.
I added
moduleNameMapper: {
deepmerge: '<rootDir>/node_modules/deepmerge/dist/es.js',
},
to my jest.config.js which should be importing then the module from that file instead, and now I get a different error
export default deepmerge_1;
^^^^^^
SyntaxError: Unexpected token export
> 1 | import merge from 'deepmerge';
So now it seems to be importing the proper file, but still is throwing an error.
from deepmerge.
The DefinitelyTyped typedefs are bad. I uninstalled them and added the following to my project and it works:
declare module 'deepmerge' {
function deepmerge<T>(x: Partial<T>, y: Partial<T>, options?: deepmerge.Options): T;
function deepmerge<T1, T2>(x: Partial<T1>, y: Partial<T2>, options?: deepmerge.Options): T1 & T2;
namespace deepmerge {
export interface Options {
arrayMerge?(target: any[], source: any[], options?: Options): any[];
clone?: boolean;
isMergeableObject?(value: object): boolean;
}
export function all<T>(objects: Partial<T>[], options?: Options): T;
}
export default deepmerge;
}
If you (deepmerge maintainers) are interested in fixing this within your project, you can include the above in deepmerge/index.d.ts
. If you would rather offload the maintenance of TS definitions then perhaps I'll submit a PR to DefinitelyTyped (I'm not totally confident in my changes, but they at least make deepmerge basics work for me):
import deepmerge from 'deepmerge';
const opts: deepmerge.Options;
deepmerge(x, y);
deepmerge.all(x, y);
from deepmerge.
I'm now open to maintaining a type definition in this project, as long as there is a test that can be added to the npm run scripts, similar to the DefinitelyTyped tests.
A PR to this repo would be appreciated!
from deepmerge.
In the last delivery (2.2.1) a correction was made on the index.d.ts which is making the Typescript import impossible again… You should keep the export default
in order to be able to do
import merge from 'deepmerge'
Without this, Typescript users can only do
import * as merge from 'deepmerge'
from deepmerge.
See #124
from deepmerge.
OK, so this makes sense. But how should we configure Webpack, now, in order not to have the is not a function
error? I thought the solution was to take the ES module…
from deepmerge.
There's a workaround in the readme that has worked for some people
from deepmerge.
OK, will try. Thank you.
from deepmerge.
Related Issues (20)
- Deepmerge deletes values of ArrayBuffer and replaces to an empty object HOT 4
- How to use one object as target HOT 8
- Deno? HOT 7
- High CPU usage with large object merge HOT 1
- use recursive partial for type definitions HOT 1
- Will we ever see the v5? HOT 4
- When a particular property of the source object is undefined while the target one has a value, the value will be override by undefined HOT 2
- How to delete an element from an array with deepmerge. HOT 1
- How to avoid array concatenation HOT 18
- `is-mergeable-object` is a `devDependency` but used in `index.js` HOT 7
- An error occuren when merge axios config: config.signal.addEventListener is not a function HOT 3
- add ESM, support for module and browser HOT 5
- Possible to remove duplicate objects in arrays? HOT 1
- deepmerge_1.default) is not a function (No Webpack) HOT 4
- A class instance in an array in an object get formed into an object.
- It need filter on merge
- Add a way to merge into existing target object, just like Object.assign
- Feature Request: Passing a collision callback for colliding props
- [Feature request] Pass parent values to `customMerge()`
- When merging arrays the target defaults to empty array
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from deepmerge.