Blog logotrial and stderr

Testing NextJS getInitialProps with Enzyme

 •  Filed under nextjs, enzyme, react

If you're using NextJs, you probably want to test getInitialProps on your pages. You can call it from your un-instantiated imported class, and use the props it returns to instantiate an Enzyme wrapper. Here's a nice little pattern:

import { shallow } from 'enzyme'
import MyPage from '../components/my-page'

describe('My Page', () => {
  var wrapper
  
  beforeEach(async () => {
    const props = await MyPage.getInitialProps()
    wrapper = shallow(<MyPage {...props} />)
  })
})

Getting set up to test React

 •  Filed under react, testing

There's a bunch of guides telling you how to do this painful-looking JSDOM setup stuff. You probably don't need it. Use Enzyme's shallow rendering, which doesn't require a DOM to mount on. As this smart guy suggests, you can call lifecycle methods yourself to emulate mounting.

This is the best practices guide you're looking for.

Check out this mess of test boilerplate. This looks awful. Don't do it. You don't need it.

Reminder to Mongoose users who like their sanity

 •  Filed under mongoose

var schema = new Schema({..}, { bufferCommands: false })

Without this, uses of Mongoose models will fail silently and hang forever. The deepest programmer hell. Set bufferCommands to false when definining your schema so that using a Mongoose model when no mongo connection exists will produce logs. It will still hang forever. I'm not sure Mongoose provides a way to avoid that.

Reactstrap and React 16

 •  Filed under react

Starting a new NextJS project, I was getting errors like

TypeError: Cannot read property 'toLowerCase' of undefined
  at ReactDOMServerRenderer.renderDOM (/Users/bistenes/Code/project/node_modules/react-dom/cjs/react-dom-server.node.development.js:2776:27)

and

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.

which were obviously totally irrelevant to the actual problem. Turns out Reactstrap <5.0 is incompatable with React 16.

npm i --save reactstrap@next fixed it.

Bailing on MarkoJS

 •  Filed under markojs

Look, it's been fun, but my org has given me the opportunity to bail on MarkoJS (by insituting a massive pivot, obviating most of the code I wrote). I'm going to double down on NextJS.

MarkoJS is a very good idea, put together by very kind and helpful people. It's simply just not well executed enough, and the people can't be sufficiently kind and helpful to compensate for how not ready for general use it is.

I will miss Marko's unbelievable speed. It's the "great physical connection" part of the relationship that almost makes me forget about all the problems that developed between us.

You should use MarkoJS if you want to develop MarkoJS into something useable.

The biggest problems are

  1. the error messages are terrible
  2. errors have to be looked up in the compiled JS code, from which you have to infer what went wrong in the Marko code
  3. the documentation was obviously mostly written for old versions of Marko, and needs to be fully restructured to make sense for what Marko is now
  4. there's a lot of weird behavior that's just not documented at all outside PRs
  5. complex component relationships are completely undocumented, even in examples -- you'll note that every MarkoJS snippet everywhere has trivially simple data models
  6. any given Google search about MarkoJS will turn up a wealth of information about a deprecated MarkoJS-related project (Marko Widgets, Marko Router...) and almost nothing about MarkoJS as it presently exists
  7. no one uses it except a handful of highly enthusiastic eBay engineers, so you better hope one of them is online to answer your questions, and will continue to be, forever
  8. most of the documentation for MarkoJS refers to Lasso and wants you to use Lasso, but no one has actually used it for anything other than MarkoJS, so finding information about it is pretty much impossible

I hope MarkoJS takes off, because I think it's largely composed of good ideas. And is mind-blowingly fast.

24 hours of outage, probably due to Docker

 •  Filed under docker

All my sites on a particular server went down at 00:13 last night. Nothing in any logs. The docker containers running the websites themselves were responsive to curls from the server. So that left the https-portal container, which reverse-proxies all the sites, as the culprit. Not that I think this is https-portal's fault, actually -- this seems like docker being more generally unstable (I just found out about that article in diagnosing this problem -- holy hell). This was corroborated by some weird errors on trying to kill/restart the container in question.

I really love https-portal. I don't want to give it up. But it certainly is a critical point of failure.

(The name of this article is a little misleading -- I fixed the problem in 10 minutes, it just took me 24 hours to get around to doing so. Nothing big impacted, just a couple personal projects. Including this blog.)

(Failed) Conditional Bundling with Lasso

 •  Filed under markojs

In my project's shared npm package are included both my database models and some code that I'd like a client, bundled with Lasso, to be able to access. So I figured I could make the model only conditionally required, right?

const browser =
  typeof window !== 'undefined' ||
  process.browser ||
  process.env.IN_BROWSER === '1'

module.exports = {
  config: require('./config'),
  models: browser ? null : require('./models'),
}

Running marko-starter build, I see that browser == true, but the Lasso bundling still fails on code in models, indicating that the module is getting required regardless. Bummer.

The right way to solve this, of course, would be to use the browser field spec which Lasso ostensibly respects, but that doesn't seem to be working, and my requests for help have fallen on deaf ears. The Marko community is mostly very helpful people, but unfortunately it's a community of like four people that work for eBay.

So I suppose I'll now maintain two common packages, one browser-compatible, one not.