I don’t have a shareable repo or example so i’m really just wondering if anyone has ever seen such a thing before? obviously if someone has an actual fix that would be super too, but even directional suggestions would be great.
the purescript compiler certainly produces the
index.js in the
output directory all right but the bundle that is served by both
webpack-dev-server (i’ve tried both) assigns a null to the handle, like so:
var Comms_S101_Inbound = __webpack_require__(/*! /Users/afc/work/from Git/marrakesh/lib/Comms/S101/Inbound.purs */
var Comms_S101_ServerInterface = null;
var Control_Applicative = __webpack_require__(/*! /Users/afc/work/from Git/marrakesh/.psc-package/psc-0.11.7-20180524/prelude/v3.1.1/src/Control/Applicative.purs */
This is probably due to a circular dependency somewhere.
I would try using the
circular-dependency-plugin for webpack. We used it with
purs-loader in the past and it even found things like this: https://github.com/purescript/purescript/issues/3079
Thanks for the suggestion, @paulyoung, circular dependencies seems like a good bet alright.
In this case the only circular dependency that the
circular-dependency-plugin throws up is an explicit one in
contravariant's Data.Comparison module.
But that’s not to say that i haven’t somehow got a cycle in our own code that isn’t found by the plugin. I’ll try to rule that out before adopting other approaches.
Purs does not allow real circular dependencies. It does allow a self dependency for the purpose of reexports and curiously still emits a require even though it doesn’t let you reference it in code.
So there is no point looking for circular dependencies in our own source?
In that case, i’m stumped once again as to why Webpack ends up with a
null for a module that appears to compile normally and produce a perfectly ordinary
index.js in the output directory
@afc do you have much JS in your codebase that isn’t produced by PureScript?
well, it’s got some legacy JS files, React, D3, SVGs, some fonts, LESS…the usual gamut of assets.
I find it just absurd that Webpack as a tool can EVER emit code that has
var X = null in the bundle. It just seems unimaginably crappy to me. As i was saying to colleagues on internal Slack this morning i’m sort of dumbfounded that all the tooling problems i ever have come from the mass market language.
Purescript, by comparison, has never let me down. Both language / compiler and tooling.
Incidentally, i renamed the offending file - the one that Webpack simply won’t handle - to Foo and stripped all the code out of it AND removed all its includes except
Prelude (unit, pure) and it still fails to resolve in Webpack. This makes me think it really isn’t circular references, or some weird hidden characters in the file / module name.
At this point I won’t be surprised if it turns out to be a hard limit on module numbers or something like that.
Is there a webpack option you can use to see verbose output when building?
Yes, you can get quite a lot of info by getting Webpack to dump out stats.
However, i have now moved on to looking at the
purs-loader…i may have the problem licked now, will post my findings shortly
Okay so the problem turned out to be errant whitespace at the front of the file in question (minus many points to me for not spotting this but also a giant gritting of teeth at the knowledge that this was probably caused by my failing MacBook Pro keyboard accepting a Cmd-Tab as a Tab at some point in the past).
There is a regex in
var srcModuleRegex = /(?:^|\n)module\s+([\w\.]+)/i;
And this regex fails to capture the situation where the module is not the first thing in the file.
I will file an issue on the repo, i think, just as an FYI. One could change the regex but…is leading whitespace even valid PureScript? and there are many ways a regex could fail. I’m inclined to think a warning that no match has been found would be better.
-- | This is a valid module with a module comment.
module Foo where
foo :: Unit
foo = unit
Yes, that works okay because the 'module Foo` is first thing on the line, directly following a newline.
If i would have had a comment there i might have noticed the spaces before “module”
FWIW, I’ve found the least frustrating way to bundle with Webpack is to require and watch the actual compiler artifacts and just run purs separately. That’s how SlamData does it, and we moved from purs-loader to requiring the artifacts a few months ago at Awake.