Has anyone had success with snowpack in a PureScript project?
I’m exploring migrating this template, which works with parcel, but I’m not sure how to modify the entry point:
//index.js
require("../output/Main/index.js").main();
As is, I’m getting a require is not defined
error with snowpack.
Attempted to fix by editing index.js
and index.html
like so:
//index.js
import("../output/Main/index.js").main();
Added type="module"
to index.html
:
<script type="module" src="./index.js"></script>
But these don’t work because output/Main/index.js
isn’t a ES Module, right?
//output/Main/index.js
//...
module.exports = {
main: main
};
We’d need it to look like:
//output/Main/index.js
//...
export {
main
};
Would this be more straightforward with ES module output (planned for 0.15)?
Reasons for giving snowpack a try are:
- Parcel lacks config flexibility for more complex projects, especially if paths are used and manipulated within the PS code. Parcel will flatten directory structures and mangle names.
- Webpack took a way longer time than anticipated to setup for dev builds, and I’m expecting another deep dive is required for production builds.
- Esbuild doesn’t play nice with my dev server and I keep getting broken pages with automatic rebuild.
2 Likes
This suggests that CommonJS is supported for npm modules: https://www.snowpack.dev/#import-npm-packages
It also looks like there also at least used to be a way to make CommonJS work through a config option: https://github.com/pikapkg/snowpack/issues/62
So it seems that snowpack supports CommonJS now for whatever it considers to be dependencies, so perhaps you could convince it that the PureScript output directory is a dependency of your app and get things working that way.
I have been meaning to look into Snowpack (using a version of the compiler which includes the es modules PR) once 0.14 is out. I think it’s very exciting. I haven’t used it at all yet, though. I suspect it will indeed be easier with ES modules. You could try using Snowpack with that branch now if you wanted?
1 Like
I’m not able to build the kl0tl:es-modules
branch from this PR. Example error:
purescript> /home/miles/projects/purescript/complier/.stack-work/dist/x86_64-linux-tinfo6/Cabal-2.4.0.1/build/Language/PureScript/CST/Parser.hs:149:15: error:
purescript> Not in scope: type constructor or class ‘Kind’
purescript> |
purescript> 149 | happyIn42 :: (Kind ()) -> (HappyAbsSyn t109)
purescript> |
Do I need a stack clean
? Wanted to double-check before committing to a long build.
Also, that branch is based on 13.6, and I don’t want to miss out on all the great stuff in 13.8 if I use this custom build in my workflow. Hoping that rebasing this branch on 13.8 isn’t a rabbit hole.
It looks to me like you do need a stack clean
. You could mention on the PR that you’d like to try it out and would the author mind rebasing, maybe? They’ll need to rebase it at some point anyway.
I think in general stack is bad about invalidating the output of happy
.
I’ve gotten past the initial blocker, but discovered that snowpack needs the FFI JS code to use ES Modules too.
For example, in purescript-prelude/src/Record/Unsafe.js (written to output/Record.Unsafe/foreign.js
), we need this CommonJS code:
// Incompatible with snowpack
exports.unsafeHas = function (label) {
return function (rec) {
return {}.hasOwnProperty.call(rec, label);
};
};
to use ES Module syntax instead:
// Works with snowpack
const unsafeHas = function (label) {
return function (rec) {
return {}.hasOwnProperty.call(rec, label);
};
};
export {
unsafeHas
};
Here’s the project repo for anyone who’d like to work on this some more.
I suspect this would eliminate many of the performance benefits of snowpack, since any tiny change to output
would require a full re-bundle. Ideally, snowpack would just re-serve what gets modified in output
on a per-file basis.
Correction. I was confused by seeing the 13.6 tag in the build log. That branch is actually closer to 14.0 than 13.8. There are only a few minor 13.8 commits missing. FYI, using this custom build requires a 14.0-compatible package set.
Perhaps you might be able to set up something like https://github.com/tbranyen/babel-plugin-transform-commonjs to transform commonjs FFI modules to ES modules? I suppose it’s a bit unfortunate in that it sort of adds a new build step when the aim here is presumably to reduce the number of build steps.
1 Like
Linking to plugin development thread: Snowpack Plugin