Closed zsherman closed 6 years ago
@zsherman hmm nothing seems to have changed in moment
itself--usage has always been as a function. are you sure it's installed and being imported correctly in your application?
Do you mean to say that moment is exported as a default export (export default moment
)? That gets compiled down to a simple module.exports
in commonJS. The source here suggests that a function is the module export: https://unpkg.com/moment@2.14.1/moment.js
Anything interesting about your build system that may cause moment to not be loaded or bundled correctly?
Hmm don't think I'm doing anything special, when I inspect moment in the chrome debugger I'm seeing that it is indeed an object, not a function:
For what it's worth, I have no issues with the DayPicker
, only with anything that relies on dateInput
.
My guess is it's the way it's being imported here https://github.com/palantir/blueprint/blob/master/packages/datetime/src/common/dateUtils.ts#L8, which I thought pulls the export into a new object, which I can reproduce locally. Importing like import moment from 'moment'
pulls in a function.
which I thought pulls the export into a new object
not quite; import * as moment
assigns module.exports
of the entry point of the package to the moment
symbol in the scope. module.exports
is often an object literal, but it can be any value and in the case of the moment library it is a function.
can you provide a minimal repro of your error? what build system or module loader are you using? where exactly are you stepping through code to get moment
to show up like that in the chrome debugger? I don't think there's anything wrong with the way @blueprintjs/datetime
imports moment; you'll notice that most TS code on github does it this way.
thanks @adidahiya, so here's the webpack config my app is based off of https://github.com/react-boilerplate/react-boilerplate/blob/master/package.json, I was able to run into the same error with a fresh install so I'm suspicious that it's something to do with the way modules are being imported there.
In order to inspect the value of moment I'm just placing a breakpoint at the line where it's failing and added adding a watcher here https://www.dropbox.com/s/jbv22lp0bpaxbxh/Screenshot%202017-04-07%2010.10.03.png?dl=0.
@adidahiya here's an example repo with a fresh install of blueprint, if you installs deps and load up the homepage you should see the error https://github.com/zsherman/blueprint-test
I can confirm this. When importing with * syntax, I indeed receive an object with moment as a key. This is in line with how moment is being exported as "export default moment" here: https://github.com/moment/moment/blob/develop/src/moment.js#L82
When importing as "import moment from 'moment'" only then do I receive a function.
Also worth noting that moments module.exports is not a function, but as per es6 module export spec, it is an object with moment assigned to the default key.
this seems like an actual issue with moment & typescript: https://github.com/moment/moment/issues/3650
they clearly use ES6 export default
in the main file, but at the same time our import * as moment
has worked swimmingly for months. seems to be an issue related to how you run the code in the browser.
The source of moment uses export default
, but the transpiled code ends up as module.exports = ...
, meaning that the obnoxious export = ...
syntax in the typings is correct, despite what the original source would have you believe, and import * as moment from 'moment'
is correct as long as you aren't using allowSyntheticDefaultImports
.
having the exact same issues with datetime@1.14.0
& moment@2.18.1
.
Any possibles workaround or idea for temporary fixing this?
The root cause is probably an unfortunate combination of compiler flags, possibly across languages/compilers, causing a disconnect between what you think you're writing and what is actually coming out the other end.
@opavader / @zsherman are you using Typescript or plain Javascript? Babel also does some weird stuff around these "synthetic defaults" (which I think causes more problems than it solves), so I'd poke around the transpiled output of your project, Blueprint and your version of moment to see which ones are in agreement and which are importing the wrong thing.
I'm also using reactboilerplate
and I have the same issue. Fixed adding the package moment-es6
.
I@seansfkelley Using typescript. I downgraded my moment
version to 2.14.1 but even then same error. Setting allowSyntheticDefaultImports
to false
will break other packages in use. My compiler options in tsconfig.json
is
"compilerOptions": {
"noUnusedParameters": true,
"noUnusedLocals": true,
"skipLibCheck": true,
"noEmit": true,
"target": "es6",
"module": "commonjs",
"noImplicitAny": false,
"sourceMap": true,
"inlineSourceMap": false,
"inlineSources": false,
"preserveConstEnums": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"jsx": "preserve",
"lib": [
"dom",
"es5",
"es6",
"es7",
"es2017.object"
],
"allowSyntheticDefaultImports": true,
"baseUrl": "./",
"paths": {
"ArchApp/*": [
"src/*"
]
}
},
Super hacky, but this is how I solved my problem with moment/typescript/webpack:
let moment = require("moment");
if ("default" in moment) {
moment = moment["default"];
}
Yeah, I did the same. Wierd that even https://github.com/moment/moment-timezone/issues/449 has the same issue.
@wshaver Your solution works for me, I had extra problems because I was creating a library with ng-packagr and it works now. Thanks.
Word "require" makes my ionic app execution fail (ts error) with @wshaver solution.
2.0.0-rc.3 now uses Typescript's new esModuleInterop
and the latest version of tslib
, which should fix any moment import issues.
additionally, datetime@2.0
no longer depends on moment
so that should further solve this problem. (timezone
still uses moment-timezone
though)
@seansfkelley thanks. You saved my weekend :-)
So definitely, to get moment work as a function, if you are using ES6 and babel, you must import it in this way:
import moment from 'moment'
and not, as written in the documentation
import * as moment from 'moment'
This isn't resolved though really, as tests should be agnostic and not force you to have to change how you import into modules for them to work.
Can we re-open this please?
import moment from 'moment'
the solution import moment from 'moment' worked for me
My guess is it's the way it's being imported here https://github.com/palantir/blueprint/blob/master/packages/datetime/src/common/dateUtils.ts#L8, which I thought pulls the export into a new object, which I can reproduce locally. Importing like
import moment from 'moment'
pulls in a function.
Consider import moment, * as MyObjectMoment from 'moment';
So definitely, to get moment work as a function, if you are using ES6 and babel, you must import it in this way:
import moment from 'moment'
and not, as written in the documentationimport * as moment from 'moment'
you are doing well dear
This isn't resolved though really, as tests should be agnostic and not force you to have to change how you import into modules for them to work.
Can we re-open this please?
This module is declared with using 'export =', and can only be used with a default import when using the 'allowSyntheticDefaultImports' flag.
import * as temp from 'moment'; const moment = temp["default"];
that's bad practice though to redefine imports.
import moment from 'moment'; for me
This module is declared with using 'export =', and can only be used with a default import when using the 'allowSyntheticDefaultImports' flag.
This isn't resolved though really, as tests should be agnostic and not force you to have to change how you import into modules for them to work.
Which part of this issue is specific to tests?
This is an old issue, but @seansfkelley's comment https://github.com/palantir/blueprint/issues/959#issuecomment-295346290 is still essentially correct (albeit with updated code links: moment default
export source, moment transpiled export, moment export type definition). So I don't think this requires a change in Blueprint. This issue can be resolved by tweaking your build tooling. If you can demonstrate a clear repro of a bug that warrants a change in Blueprint, please file a new issue and link to a repo and point out how the build system works (or breaks).
import * as moment from 'moment'
can not work for me still not working...................
It seems that moment@2.14 exports moment as a function by default but it's being imported with the syntax
import * as moment from 'moment'
, yet this file https://github.com/palantir/blueprint/blob/master/packages/datetime/src/common/dateUtils.ts #callsmoment
as a function in multiple places, which leads to this error. Has anyone seen this or been able to reproduce? Might be missing something here...Also obligatory shoutout for the awesome lib, thanks for all your hard work.
Bug report
Steps to reproduce
DateRangeInput
and pass in valid datesActual behavior
TypeError: moment is not a function
is thrownExpected behavior
Should not throw an error.