Using ember-inflector in Node

My addon uses ember-inflector and I’m trying to figure out if it can be used in Node.

I’m trying to require() some of my addon’s ES6 modules in node via esm, and I have it working for many modules. But it’s failing for ember-inflector.

Here’s the import statement from my ES6 module:

import { singularize, pluralize } from 'ember-inflector';

When I try to run esm on this module, I get

Missing export name ‘singularize’ in ES module: file:///~/Projects/oss/ember-cli-mirage/node_modules/ember-inflector/index.js

I think these imports work in the browser because of some RequireJS/AMD semantics that don’t transfer nicely to Node.

I’ve tried importing different paths but haven’t gotten anywhere.

Is there something simple I’m missing for how to use this package in Node, or is it not possible because it is really designed as an Ember addon?

I have tried using this in node too, I think it needs to be refactored better to make that possible.

In particular, it does import Ember from 'ember' right at the beginning of its index.js file, not because you actually need it when consuming the library, but because it’s trying to install deprecations on the Ember global.

It also tries to import capitalize from @ember/string despite that not being a thing it can correctly resolve in node.

These are very solvable and can be done in a way that would remain compatible with traditional consumption as an addon, but somebody needs to do the refactor. I don’t even think it would take very long.

I’m willing to help out here.

First question: what should we do about the /addon portion of the path being removed in the Browser environment, but not in the Node environment?

I got Mirage’s use of ember-inflector down to this:

import Inflector from "ember-inflector/lib/system/inflector";
import defaultRules from "ember-inflector/lib/system/inflections";

const inflector = new Inflector(defaultRules);
const singularize = inflector.singularize.bind(inflector);
const pluralize = inflector.pluralize.bind(inflector);

but in Node, the path is expected to be

ember-inflector/addon/lib/system/inflector

I’d like the interface to be the same for both environments. Is that possible? If not, what are the alternatives?

I think you can set “main” in package.json to addon/index.js and set ember-addon.main to index.js so it keeps working as an addon.