How can I modify the Meteor (meteorite) that is ru

2019-09-16 04:23发布

问题:

One of the benefits of open source projects is that you can open up the code, see what it does and even modify it to help you understand under the hood.

How can I modify the base code of meteor(ite) so that I can insert my own console log statements to view how the code is working? I run my application as a meteorite app ( mrt )

Things I have tried but have not got working: * editing my .meteor source tree * editing my .meteorite source tree * editing the /myApp/.meteor/local/build

Additional details: My specific use case (though the answer should be more general than answering just this) is that I am getting an error "Exception in queued task: Error: Meteor does not currently support objects other than ObjectID as ids" and want to console.log what the id is (ie, if its not a ObjectID, then what is it?)

Here is the full error:

I20130826-10:36:36.038(-6)? Exception in queued task: Error: Meteor does not currently support objects other than ObjectID as ids
I20130826-10:36:36.039(-6)?     at Function.LocalCollection._idStringify (packages/minimongo/minimongo.js:845)  
I20130826-10:36:36.039(-6)?     at _.extend._nextObject (packages/mongo-livedata/mongo_driver.js:549) 
I20130826-10:36:36.039(-6)?     at _.extend.forEach (packages/mongo-livedata/mongo_driver.js:570)  
I20130826-10:36:36.039(-6)?     at _.extend.getRawObjects (packages/mongo-livedata/mongo_driver.js:621) 
I20130826-10:36:36.039(-6)?     at _.extend._pollMongo (packages/mongo-livedata/mongo_driver.js:897)  
I20130826-10:36:36.040(-6)?     at Object._.extend._unthrottledEnsurePollIsScheduled [as task] (packages/mongo-livedata/mongo_driver.js:841)  
I20130826-10:36:36.040(-6)?     at _.extend._run (packages/meteor/fiber_helpers.js:144)  
I20130826-10:36:36.040(-6)?    at _.extend._scheduleRun (packages/meteor/fiber_helpers.js:122)

The error message is found in the following files in myApp/ directory:

  • .//.meteor/local/build/programs/client/packages/minimongo.js
  • .//.meteor/local/build/programs/client/packages/minimongo.js.map
  • .//.meteor/local/build/programs/ctl/packages/minimongo.js
  • .//.meteor/local/build/programs/ctl/packages/minimongo.js.map
  • .//.meteor/local/build/programs/server/packages/minimongo.js
  • .//.meteor/local/build/programs/server/packages/minimongo.js.map

and in ~/.meteor

  • .//packages/minimongo/2c0b2ba53f/browser/packages/minimongo.js
  • .//packages/minimongo/2c0b2ba53f/browser/packages/minimongo.js.map
  • .//packages/minimongo/2c0b2ba53f/os/packages/minimongo.js
  • .//packages/minimongo/2c0b2ba53f/os/packages/minimongo.js.map
  • .//packages/minimongo/80c0a81364a8a504110b56f3e9a2cba2d4e731ee/minimongo.js

回答1:

It looks like you're asking a couple of things here so let me break it down into different answers:

Modifying Meteor

It depends how you want to do it. If you take one of the packages over at https://github.com/meteor/meteor/tree/devel/packages and place them in your /packages folder and run

meteor add packagename

Where packagename is the name of the package. This package will override meteor and let you use it with its code modifications instead.

If you want to alter meteor itself so that it affects all your other projects too, you need to look for the latest build under ~/.meteor.

If you modify the files in the .meteor directory of your project, the ones from ~/.meteor are going to overwrite them and you won't see your changes.

I would suggest it might be better to use the first style as it won't interfere with your other meteor projects.

Modifying Meteorite

When it comes to Meteorite, you could use npm link to let you use a git clone of the meteorite project on github. This will let you use it as an npm module and yet let you modify the code to see how its working under the hood.

The Error

Meteor allows you to use two types of _id, an ObjectID via Meteor.Collection.ObjectID or a string (so long as its unique, and typically looks something like what Random.id() gives out.

If you follow the trace it looks like you're trying to use a collection where the _id is neither an ObjectID or a string. This might happen if you made your collection outside of meteor somehow. To get passed the error modify your collection outside of meteor and use _ids that are either strings or an ObjectIDs



回答2:

Answering the specifics related to the error message I was receiving, @Akshat's answer is correct for general purpose "modifying Meteor" .

My Error:

I20130826-10:36:36.038(-6)? Exception in queued task: Error: Meteor does not currently support objects other than ObjectID as ids
I20130826-10:36:36.039(-6)?     at Function.LocalCollection._idStringify (packages/minimongo/minimongo.js:845)  
I20130826-10:36:36.039(-6)?     at _.extend._nextObject (packages/mongo-livedata/mongo_driver.js:549) 
I20130826-10:36:36.039(-6)?     at _.extend.forEach (packages/mongo-livedata/mongo_driver.js:570)  
I20130826-10:36:36.039(-6)?     at _.extend.getRawObjects (packages/mongo-livedata/mongo_driver.js:621) 
I20130826-10:36:36.039(-6)?     at _.extend._pollMongo (packages/mongo-livedata/mongo_driver.js:897)  
I20130826-10:36:36.040(-6)?     at Object._.extend._unthrottledEnsurePollIsScheduled [as task] (packages/mongo-livedata/mongo_driver.js:841)  
I20130826-10:36:36.040(-6)?     at _.extend._run (packages/meteor/fiber_helpers.js:144)  
I20130826-10:36:36.040(-6)?    at _.extend._scheduleRun (packages/meteor/fiber_helpers.js:122)

Minimongo inspects objects to try and decide how to stringify them with the following code see call to _looksLikeObjectID(id):

myApp/packages/minimongo/minimongo.js

LocalCollection._idStringify = function (id) {
  if (id instanceof LocalCollection._ObjectID) {
    return id.valueOf();
  } else if (typeof id === 'string') {
    if (id === "") {
      return id;
    } else if (id.substr(0, 1) === "-" || // escape previously dashed strings
               id.substr(0, 1) === "~" || // escape escaped numbers, true, false
               LocalCollection._looksLikeObjectID(id) || // escape object-id-form strings
               id.substr(0, 1) === '{') { // escape object-form strings, for maybe implementing later
      return "-" + id;
    } else {
      return id; // other strings go through unchanged.
    }
  } else if (id === undefined) {
    return '-';
  } else if (typeof id === 'object' && id !== null) {
    throw new Error("Meteor does not currently support objects other than ObjectID as ids");
  } else { // Numbers, true, false, null
    return "~" + JSON.stringify(id);
  }
};

myApp/packages/minimongo/objectid.js

LocalCollection._looksLikeObjectID = function (str) {
  return str.length === 24 && str.match(/^[0-9a-f]*$/);
};

The object indeed was built outside of meteor (as @Akshat suspected) because I was hydrating an object from an API. The object had a value called "length" and it was indeed < 24 . this caused it to fall out of the "string" style interpretations and into the } else if (typeof id === 'object' && id !== null) { throw new Error("Meteor does not currently support objects other than ObjectID as ids"); } section .

an example object that will mess the _looksLikeObjectID inspection up is as follows:

var aCube = {
    width: 10,
    height: 10,
    length: 10, // <--- messes things up because .length < 24
    _id: ObjectId("521d23ad1d01960000000001")
}

so if you're getting this err, check to see if the object has a .length field. a work around is to nest the "length" field inside something else:

var aCube = {
    data: { 
        length:10
    }
};