How can I fully get rid of DDP?


#1

Objective: get rid of anything unnecessary for a proper, clutter-free Meteor Apollo integration.

Looking at the dependency tree:

$ meteor list --tree
accounts-password@1.5.1
├─┬ accounts-base@1.4.2
│ ├─┬ callback-hook@1.1.0
│ │ └── ecmascript@0.10.5 (top level)
│ ├─┬ check@1.3.0
│ │ ├── ecmascript@0.10.5 (top level)
│ │ └─┬ ejson@1.1.0
│ │   ├─┬ base64@1.0.11
│ │   │ └── ecmascript@0.10.5 (top level)
│ │   └── ecmascript@0.10.5 (top level)
│ ├─┬ ddp@1.4.0
│ │ ├─┬ ddp-client@2.3.1
│ │ │ ├── callback-hook@1.1.0 (expanded above)
│ │ │ ├── check@1.3.0 (expanded above)
│ │ │ ├─┬ ddp-common@1.4.0
│ │ │ │ ├── check@1.3.0 (expanded above)
│ │ │ │ ├── ecmascript@0.10.5 (top level)
│ │ │ │ ├── ejson@1.1.0 (expanded above)
│ │ │ │ ├─┬ random@1.1.0
│ │ │ │ │ └── ecmascript@0.10.5 (top level)
│ │ │ │ ├─┬ retry@1.1.0
│ │ │ │ │ ├── ecmascript@0.10.5 (top level)
│ │ │ │ │ └── random@1.1.0 (expanded above)
│ │ │ │ └── tracker@1.1.3
│ │ │ ├─┬ diff-sequence@1.1.0
│ │ │ │ ├── ecmascript@0.10.5 (top level)
│ │ │ │ └── ejson@1.1.0 (expanded above)
│ │ │ ├── ecmascript@0.10.5 (top level)
│ │ │ ├── ejson@1.1.0 (expanded above)
│ │ │ ├─┬ id-map@1.1.0
│ │ │ │ ├── ecmascript@0.10.5 (top level)
│ │ │ │ └── ejson@1.1.0 (expanded above)
│ │ │ ├─┬ mongo-id@1.0.6
│ │ │ │ ├── ejson@1.1.0 (expanded above)
│ │ │ │ ├── id-map@1.1.0 (expanded above)
│ │ │ │ └── random@1.1.0 (expanded above)
│ │ │ ├── random@1.1.0 (expanded above)
│ │ │ ├─┬ reload@1.2.0
│ │ │ │ └── ecmascript@0.10.5 (top level)
│ │ │ ├── retry@1.1.0 (expanded above)
│ │ │ ├─┬ socket-stream-client@0.1.0
│ │ │ │ ├── ecmascript@0.10.5 (top level)
│ │ │ │ └── retry@1.1.0 (expanded above)
│ │ │ └── tracker@1.1.3
│ │ └─┬ ddp-server@2.1.2
│ │   ├── callback-hook@1.1.0 (expanded above)
│ │   ├── check@1.3.0 (expanded above)
│ │   ├── ddp-client@2.3.1 (expanded above)
│ │   ├── ddp-common@1.4.0 (expanded above)
│ │   ├── diff-sequence@1.1.0 (expanded above)
│ │   ├── ecmascript@0.10.5 (top level)
│ │   ├── ejson@1.1.0 (expanded above)
│ │   ├─┬ minimongo@1.4.3
│ │   │ ├── diff-sequence@1.1.0 (expanded above)
│ │   │ ├── ecmascript@0.10.5 (top level)
│ │   │ ├── ejson@1.1.0 (expanded above)
│ │   │ ├─┬ geojson-utils@1.0.10
│ │   │ │ └─┬ modules@0.11.5
│ │   │ │   └── modules-runtime@0.9.2
│ │   │ ├── id-map@1.1.0 (expanded above)
│ │   │ ├── mongo-id@1.0.6 (expanded above)
│ │   │ ├─┬ ordered-dict@1.1.0
│ │   │ │ └── ecmascript@0.10.5 (top level)
│ │   │ ├── random@1.1.0 (expanded above)
│ │   │ └── tracker@1.1.3
│ │   ├── mongo-id@1.0.6 (expanded above)
│ │   ├── random@1.1.0 (expanded above)
│ │   ├── retry@1.1.0 (expanded above)
│ │   ├─┬ routepolicy@1.0.12
│ │   │ ├── underscore@1.0.10
│ │   │ └── webapp@1.5.0 (top level)
│ │   ├── underscore@1.0.10
│ │   └── webapp@1.5.0 (top level)
│ ├─┬ ddp-rate-limiter@1.0.7
│ │ └─┬ rate-limit@1.0.9
│ │   ├── ecmascript@0.10.5 (top level)
│ │   └── random@1.1.0 (expanded above)
│ ├── ecmascript@0.10.5 (top level)
│ ├── ejson@1.1.0 (expanded above)
│ ├─┬ localstorage@1.2.0
│ │ └── random@1.1.0 (expanded above)
│ ├── mongo@1.4.5 (top level)
│ ├── random@1.1.0 (expanded above)
│ ├─┬ reactive-var@1.0.11
│ │ └── tracker@1.1.3
│ ├─┬ service-configuration@1.0.11
│ │ ├── accounts-base@1.4.2 (expanded above)
│ │ └── mongo@1.4.5 (top level)
│ ├── tracker@1.1.3
│ └── underscore@1.0.10
├── check@1.3.0 (expanded above)
├── ddp@1.4.0 (expanded above)
├── ecmascript@0.10.5 (top level)
├── ejson@1.1.0 (expanded above)
├── email@1.2.3
├─┬ npm-bcrypt@0.9.3
│ └── modules@0.11.5 (expanded above)
├── random@1.1.0 (expanded above)
├── sha@1.0.9
├─┬ srp@1.0.10
│ ├── check@1.3.0 (expanded above)
│ ├── random@1.1.0 (expanded above)
│ ├── sha@1.0.9
│ └── underscore@1.0.10
└── underscore@1.0.10
alanning:roles@1.2.16
├── accounts-base@1.4.2 (expanded above)
├── check@1.3.0 (expanded above)
├── mongo@1.4.5 (top level)
├── tracker@1.1.3
└── underscore@1.0.10
apollo@2.0.0
├── accounts-base@1.4.2 (expanded above)
└── ecmascript@0.10.5 (top level)
ecmascript@0.10.5
├─┬ babel-compiler@7.0.5
│ └─┬ ecmascript-runtime@0.5.0
│   ├─┬ ecmascript-runtime-client@0.6.2
│   │ ├── modules@0.11.5 (expanded above)
│   │ └─┬ promise@0.10.2
│   │   └── modules@0.11.5 (expanded above)
│   └─┬ ecmascript-runtime-server@0.5.0
│     └── modules@0.11.5 (expanded above)
├─┬ babel-runtime@1.2.2
│ └── modules@0.11.5 (expanded above)
├─┬ dynamic-import@0.3.0
│ ├─┬ http@1.4.0
│ │ ├── modules@0.11.5 (expanded above)
│ │ └─┬ url@1.2.0
│ │   └── modules@0.11.5 (expanded above)
│ ├── modules@0.11.5 (expanded above)
│ └── promise@0.10.2 (expanded above)
├── ecmascript-runtime@0.5.0 (expanded above)
├── modules@0.11.5 (expanded above)
└── promise@0.10.2 (expanded above)
es5-shim@4.7.3
├── modules@0.11.5 (expanded above)
├─┬ server-render@0.3.0
│ ├── ecmascript@0.10.5 (top level)
│ └── webapp@1.5.0 (top level)
└─┬ shim-common@0.1.0
  └── ecmascript@0.10.5 (top level)
hot-code-push@1.0.4
├─┬ autoupdate@1.4.0
│ ├── check@1.3.0 (expanded above)
│ ├── ddp@1.4.0 (expanded above)
│ ├── ecmascript@0.10.5 (top level)
│ ├── http@1.4.0 (expanded above)
│ ├── mongo@1.4.5 (top level)
│ ├── random@1.1.0 (expanded above)
│ ├── retry@1.1.0 (expanded above)
│ ├── tracker@1.1.3
│ └── webapp@1.5.0 (top level)
└── reload@1.2.0 (expanded above)
meteor@1.8.4
mongo@1.4.5
├─┬ allow-deny@1.1.0
│ ├── check@1.3.0 (expanded above)
│ ├── ddp@1.4.0 (expanded above)
│ ├── ecmascript@0.10.5 (top level)
│ ├── ejson@1.1.0 (expanded above)
│ └── minimongo@1.4.3 (expanded above)
├─┬ binary-heap@1.0.10
│ ├── id-map@1.1.0 (expanded above)
│ └── underscore@1.0.10
├── callback-hook@1.1.0 (expanded above)
├── check@1.3.0 (expanded above)
├── ddp@1.4.0 (expanded above)
├── diff-sequence@1.1.0 (expanded above)
├── ecmascript@0.10.5 (top level)
├── ejson@1.1.0 (expanded above)
├── minimongo@1.4.3 (expanded above)
├─┬ mongo-dev-server@1.1.0
│ └── modules@0.11.5 (expanded above)
├── mongo-id@1.0.6 (expanded above)
├── npm-mongo@2.2.34
├── random@1.1.0 (expanded above)
├── tracker@1.1.3
└── underscore@1.0.10
nicolaslopezj:apollo-accounts@3.2.2
├── accounts-base@1.4.2 (expanded above)
├─┬ accounts-oauth@1.1.15
│ ├── accounts-base@1.4.2 (expanded above)
│ ├── check@1.3.0 (expanded above)
│ ├─┬ oauth@1.2.1
│ │ ├── base64@1.0.11 (expanded above)
│ │ ├── check@1.3.0 (expanded above)
│ │ ├── localstorage@1.2.0 (expanded above)
│ │ ├─┬ logging@1.1.19
│ │ │ ├── ejson@1.1.0 (expanded above)
│ │ │ ├── modules@0.11.5 (expanded above)
│ │ │ └── underscore@1.0.10
│ │ ├── mongo@1.4.5 (top level)
│ │ ├── reload@1.2.0 (expanded above)
│ │ ├── routepolicy@1.0.12 (expanded above)
│ │ ├── service-configuration@1.0.11 (expanded above)
│ │ ├── underscore@1.0.10
│ │ ├── url@1.2.0 (expanded above)
│ │ └── webapp@1.5.0 (top level)
│ ├── random@1.1.0 (expanded above)
│ ├── underscore@1.0.10
│ └── webapp@1.5.0 (top level)
├── check@1.3.0 (expanded above)
├── ecmascript@0.10.5 (top level)
├── http@1.4.0 (expanded above)
├── npm-bcrypt@0.9.3 (expanded above)
├── oauth@1.2.1 (expanded above)
├─┬ oauth2@1.2.0
│ ├── oauth@1.2.1 (expanded above)
│ ├── random@1.1.0 (expanded above)
│ └── service-configuration@1.0.11 (expanded above)
├── random@1.1.0 (expanded above)
├── service-configuration@1.0.11 (expanded above)
└─┬ tmeasday:check-npm-versions@0.3.2
  └── ecmascript@0.10.5 (top level)
shell-server@0.3.1
└── ecmascript@0.10.5 (top level)
standard-minifier-css@1.4.1
└─┬ minifier-css@1.3.1
  └── ecmascript@0.10.5 (top level)
standard-minifier-js@2.3.2
├── babel-compiler@7.0.5 (expanded above)
├── ecmascript@0.10.5 (top level)
└─┬ minifier-js@2.3.3
  └── babel-compiler@7.0.5 (expanded above)
static-html@1.2.2
├─┬ caching-html-compiler@1.1.2
│ ├─┬ caching-compiler@1.1.11
│ │ ├── ecmascript@0.10.5 (top level)
│ │ └── random@1.1.0 (expanded above)
│ ├── ecmascript@0.10.5 (top level)
│ ├─┬ templating-tools@1.1.2
│ │ ├── ecmascript@0.10.5 (top level)
│ │ ├─┬ spacebars-compiler@1.1.3
│ │ │ ├─┬ blaze-tools@1.0.10
│ │ │ │ ├─┬ htmljs@1.0.11
│ │ │ │ │ └─┬ deps@1.0.12
│ │ │ │ │   └── tracker@1.1.3
│ │ │ │ └── underscore@1.0.10
│ │ │ ├─┬ html-tools@1.0.11
│ │ │ │ └── htmljs@1.0.11 (expanded above)
│ │ │ ├── htmljs@1.0.11 (expanded above)
│ │ │ └── underscore@1.0.10
│ │ └── underscore@1.0.10
│ └── underscore@1.0.10
├── ecmascript@0.10.5 (top level)
├── templating-tools@1.1.2 (expanded above)
└── underscore@1.0.10
swydo:graphql@0.4.0
└── ecmascript@0.10.5 (top level)
webapp@1.5.0
├─┬ boilerplate-generator@1.4.0
│ ├── ecmascript@0.10.5 (top level)
│ └── underscore@1.0.10
├── ecmascript@0.10.5 (top level)
├── logging@1.1.19 (expanded above)
├── routepolicy@1.0.12 (expanded above)
├── underscore@1.0.10
└─┬ webapp-hashing@1.0.9
  ├── ecmascript@0.10.5 (top level)
  └── underscore@1.0.10

We have so many dependencies on ddp from and others.
If I do DISABLE_WEBSOCKETS it will fallback to polling and bunch of XHR requests happen.

I see that ddp is so wired into Meteor. Any ideas how I can let it loose ?


#2

Currently using this solution: https://github.com/cult-of-coders/fusion . Will do extensive research on this part. 700kb bundle with React I believe it’s a bit too much.


#3

You can meteor remove meteor-base and then add back the packages you want.

meteor-base comprises:

  • meteor
  • webapp
  • underscore
  • hot-code-push
  • ddp

However, as you’ve seen most of Meteor’s “good stuff” needs ddp: methods, pub/sub, etc.


#4

I tried doing that, but mongo still requires ddp :smiley: , accounts-base still requires ddp.


#5

Yes - it’s deeply (ddply) embedded :smile:


#6

Depends on what you want to do, but, I’ve actually used meteor for a server-only rest api (webapp raw connect handlers and express) project where I served the / get endpoint through the /private/index.html file as a static asset and then set up a catch all route to simply respond with a 404.

This allowed me to set up dedicated rest endpoints (think /grapql and /graphiql) and no meteor code would ever be served to the client.

Yes, technically there is a bundle produced, but it is not delivered because of the / route.

From that point on, this is essentially a no-ddp server app.

Now, the interesting thing is, there’s nothing stopping you from populating the /private/index.html file through a webback (or rollup, or parcel…) build, coming in from an external directory or perhaps a dot directory like .clientSrc/entry.js which is essentially ignored by meteor. I know, quite hacky, but would be a good starting point, no?


#7

Just to add, Meteor 1.6.2 will give us a quick option for creating non-DDP based applications:

meteor create --minimal some-minimal-app

This results in the following core packages being used:

static-html             # Define static page content in .html files
standard-minifier-css   # CSS minifier run for production mode
standard-minifier-js    # JS minifier run for production mode
es5-shim                # ECMAScript 5 compatibility for older browsers
ecmascript              # Enable ECMAScript2015+ syntax in app code
shell-server            # Server-side component of the `meteor shell` command
webapp                  # Serves a Meteor app over HTTP

See this commit for the full details, or try things out using the latest 1.6.2 beta (1.6.2-beta.13 as of this post).


#8

@hwillson very nice!

@serkandurusoy I think the best solution would be to have a diff microservice for ui only and server-rendering. I am now a bit torn whether or not to use create-react-app for this or Meteor. (For the frontend part).

I still think meteor is very powerful, but now even create-react-app has ssr and lazy loading, perendering of static html files. Another point for create-react-app is that it evolves on the frontend niche and has by far more support than Meteor.

However Meteor remains king on server and reactivity.


#9

I was thinking of running a Meteor 1.6.2 --minimal application, and just using server side Meteor + Express.js to host a small micro-email service for my apps (I want to take out the email code from my clients).

@hwillson @serkandurusoy @robfallows @anyone
Any chance I could throw said minimal Meteor app code on AWS Lamda (Serverless) and be done with?


#10

But to my understanding, with 1.6.2 it should be possible to create a ssr-enabled react app with no ddp involved, right?

But yes, cra and other webpack based solutions have the advantage to have more focus on ui development workflows, nonetheless apart from hot module reloading, I don’t see much reason to move away from the benefit of using a single consistent build tool for both backend and frontend.

Yet again, one of the main sweet spots of a microservice architecture is the fact that it gives the service full autonomy and allow you to choose whatever stack serves you the best.

I guess I’d still evaluate pros and cons of a meteor-only vs mixed vs something-else per project.


#11

You can’t just “throw” it on lambda.

But considering lambda is basically a nodejs host environment, in essence, it is technically possible.

There used to be https://github.com/DispatchMe/meteor-lambdify (from ages ago) which kind of outlines the quite involved process very well.

Oh and warns against using this in production :slight_smile:

Think of it like this, lambda is an “environment” for “functions” wheras meteor gives you an application, full of functions and a feature-packed environment making it counterintuitive.


#12

or Apex Up which is better suited for sites,(and yes on AWS)


(not affiliated…)


#13

What are you using to get SSR support for create-react-app?

I was under the impress that CRA was never going to get it. The README still says:

If you want to do server rendering with React and Node.js, check out Next.js or Razzle. Create React App is agnostic of the backend, and just produces static HTML/JS/CSS bundles.


#14

Thanks. Yeah, he outlined why it doesn’t work, but I didn’t fully understand why. From the github page:

We’ve tried to use this in production and it doesn’t really work. The problem is that Lambda keeps the node process running, and this relies on the boot process working the same every time. But, if your node process is still running, the files loaded with require are cached, so the process doesn’t boot in the same way every time. We have moved to running a Meteor worker in AWS Elastic Beanstalk’s worker tier.

Bottom line, I’d really like to setup micro-services like this, it’s too bad a minimal Meteor app (without DDP and all the rest) cannot do this for us. And in the case of Meteor’s email capabilities, I’m use to it, and like the API. What is the alternative?


#15

I didn’t actually use ssr with it. Was just browsing and saw that it’s possible.


#16

@moberegger @diaconutheodor I think under a post like this where each message discusses quite innovative things like no-ddp meteor, meteor on lambda, meteor+webpack, meteor+cra I think we should keep an open mind about CRA and SSR as well :slight_smile:

In fact, you can set up a node server outside the src directory in a cra app and have that node server ssr your cra app from those sources! :slight_smile:


#17

If you’re angling for autoscaling cost-aware deployments, then you can deploy meteor on elastic beanstalk. Definitely much harder to get going compared to Galaxy, but nonetheless, you’d get autoscaling with lower hosting costs, but overall devops costs might prove to be higher, depends on your free time :slight_smile:


#18

Take a peak at https://github.com/jbaxleyiii/ReactNYC-SSR whenever you get a chance. It’s a very good example of getting SSR working with React, Apollo, and Meteor.

I feel like this is an area where Meteor shines. Compare the above example to the NextJS Apollo example, and the ceremony required to get it working with the getInitialProps API. Furthermore, to get something comparable working with CRA would require comparatively more effort, I think.


#19

Definitely agreed, especially being able to use unified universal build tool for that out of box is also a huge plus!


#20

Agreed. Sticking to Meteor for now. And I don’t have to wait for 1.6.2 I can already create that minimal repo already for the frontend only.