question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

cjs build is not compatible with @babel/preset-typescript

See original GitHub issue

The TypeScript works great when using the esm build as your entry point, but not when using cjs.

Essertially all of these constructions result in Server being undefined

import { Server } from 'miragejs'
Server //=> undefined
import * as mirage from 'miragejs`

mirage.Server //=> undefined
import mirage from 'miragejs'

mirage.Server //=> undefined

Note: our build is using rollup + @babel/preset-typescript

It seems like the problem stems from the exported symbols being different than the default export. Currently, mirage-cjs.js looks like:

var index = {
  Factory,
  Response,
  hasMany,
  belongsTo
};

exports.ActiveModelSerializer = ActiveModelSerializer;
exports.Collection = Collection;
exports.Factory = Factory;
exports.IdentityManager = IdentityManager;
exports.JSONAPISerializer = JSONAPISerializer;
exports.Model = Model;
exports.Response = Response;
exports.RestSerializer = restSerializer;
exports.Serializer = Serializer;
exports.Server = Server;
exports._Db = Db;
exports._DbCollection = DbCollection;
exports._RouteHandler = RouteHandler;
exports._SerializerRegistry = SerializerRegistry;
exports._assert = assert;
exports._ormAssociationsAssociation = Association;
exports._ormAssociationsBelongsTo = BelongsTo;
exports._ormAssociationsHasMany = HasMany;
exports._ormPolymorphicCollection = PolymorphicCollection;
exports._ormSchema = Schema;
exports._routeHandlersBase = BaseRouteHandler;
exports._routeHandlersFunction = FunctionRouteHandler;
exports._routeHandlersObject = ObjectRouteHandler;
exports._routeHandlersShorthandsBase = BaseShorthandRouteHandler;
exports._routeHandlersShorthandsDelete = DeleteShorthandRouteHandler;
exports._routeHandlersShorthandsGet = GetShorthandRouteHandler;
exports._routeHandlersShorthandsHead = HeadShorthandRouteHandler;
exports._routeHandlersShorthandsPost = PostShorthandRouteHandler;
exports._routeHandlersShorthandsPut = PutShorthandRouteHandler;
exports._utilsExtend = extend;
exports._utilsInflectorCamelize = camelize;
exports._utilsInflectorCapitalize = capitalize;
exports._utilsInflectorDasherize = dasherize;
exports._utilsInflectorUnderscore = underscore;
exports._utilsIsAssociation = isAssociation;
exports._utilsReferenceSort = referenceSort;
exports._utilsUuid = uuid;
exports.association = association;
exports.belongsTo = belongsTo;
exports.createServer = createServer;
exports.default = index;
exports.defaultPassthroughs = defaultPassthroughs;
exports.hasMany = hasMany;
exports.trait = trait;

In all of the expressions above, the compiled typescript is either referencing or deconstructing the index object, which does not have a reference to Server. It seems to me like it would more cleanly interoperate by just having the default export reference itself:

exports.ActiveModelSerializer = ActiveModelSerializer;
exports.Collection = Collection;
exports.Factory = Factory;
exports.IdentityManager = IdentityManager;
exports.JSONAPISerializer = JSONAPISerializer;
exports.Model = Model;
exports.Response = Response;
exports.RestSerializer = restSerializer;
exports.Serializer = Serializer;
exports.Server = Server;
exports._Db = Db;
exports._DbCollection = DbCollection;
exports._RouteHandler = RouteHandler;
exports._SerializerRegistry = SerializerRegistry;
exports._assert = assert;
exports._ormAssociationsAssociation = Association;
exports._ormAssociationsBelongsTo = BelongsTo;
exports._ormAssociationsHasMany = HasMany;
exports._ormPolymorphicCollection = PolymorphicCollection;
exports._ormSchema = Schema;
exports._routeHandlersBase = BaseRouteHandler;
exports._routeHandlersFunction = FunctionRouteHandler;
exports._routeHandlersObject = ObjectRouteHandler;
exports._routeHandlersShorthandsBase = BaseShorthandRouteHandler;
exports._routeHandlersShorthandsDelete = DeleteShorthandRouteHandler;
exports._routeHandlersShorthandsGet = GetShorthandRouteHandler;
exports._routeHandlersShorthandsHead = HeadShorthandRouteHandler;
exports._routeHandlersShorthandsPost = PostShorthandRouteHandler;
exports._routeHandlersShorthandsPut = PutShorthandRouteHandler;
exports._utilsExtend = extend;
exports._utilsInflectorCamelize = camelize;
exports._utilsInflectorCapitalize = capitalize;
exports._utilsInflectorDasherize = dasherize;
exports._utilsInflectorUnderscore = underscore;
exports._utilsIsAssociation = isAssociation;
exports._utilsReferenceSort = referenceSort;
exports._utilsUuid = uuid;
exports.association = association;
exports.belongsTo = belongsTo;
exports.createServer = createServer;
exports.default = index;
exports.defaultPassthroughs = defaultPassthroughs;
exports.hasMany = hasMany;
exports.trait = trait;

exports.default = exports;

Our workaround here was to force the usage of the esm build, but for those for whom this isn’t an option, it’s worth considering a fix.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:9 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
samselikoffcommented, Jul 30, 2020

Gotcha, ok - thanks for opening + documenting this. I agree the 4 dangling modules that are on the default export is bizarre. Let’s not worry about it for now, maybe we can clean this up when we ship v1 but I think the best bet might be removing that default export altogether.

If someone else runs into this we can definitely address it then!

0reactions
cowboydcommented, Jul 30, 2020

I couldn’t get it to work, but maybe there was something else going on with our config. Looking at the cjs build, it felt like

import * as mirage from 'miragejs';

mirage.Server

Should have worked, but it didn’t. Instead it got me a reference to the default export.

It could be that we don’t have es module interop with TypeScript configured correctly in babel, but for whatever reason it’s always handing me the default export.

I’m not sure what to recommend. I’d be happy to test adding everything to the default export for you, but going forward we’re actually going to use the esm build. I just wanted to make sure and note the problem in case someone runs into it in the future.

Read more comments on GitHub >

github_iconTop Results From Across the Web

[2.3] Cannot find module @babel/preset-typescript #2746
I've tried clearing my cache, rebuilding, etc. No luck. It says Cannot find module '@babel/preset-typescript' . I'm in a TypeScript Expo project ...
Read more >
babel/preset-typescript
This preset is recommended if you use [TypeScript](https://www. ... This is so that we know that the import is not a type import,...
Read more >
Documentation - Using Babel with TypeScript
This technique is a hybrid approach, using Babel's preset-typescript to generate your JS files, and then using TypeScript to do type checking and...
Read more >
@babel/preset-typescript | Yarn - Package Manager
Intro. Babel is a tool that helps you write code in the latest version of JavaScript. When your supported environments don't support certain...
Read more >
Automating a React Library's Build Process with RollupJS and ...
Browsers and certain environments cannot run TypeScript and JSX code. Therefore, we must install Babel to compile this code into JavaScript code ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found