tern icon indicating copy to clipboard operation
tern copied to clipboard

Problem with load of cutom tern plugin

Open angelozerr opened this issue 9 years ago • 4 comments
trafficstars

@marijnh I would like to share with you, a problem that many people told me with my custom tern plugin :

  • https://github.com/angelozerr/tern-lint/issues/64
  • https://github.com/angelozerr/tern-jasmine/issues/3
  • https://github.com/angelozerr/tern-node-express/issues/16

The issue is that if a tern plugin declares in the package.json a tern version (ex : 0.15.0) < available tern version (ex : 0.17.0) and you have the following case after installing tern + custom tern plugin (ex: tern-lint) :

  • node_modules
    • tern (0.17.0)
    • tern-lint
      • node_modules
        • tern (0.15.0)

It doesn't work. For instance in this case, tern-lint which provides a custom query 'lint' is not loaded by tern 0.17.0 (see issue at https://github.com/angelozerr/tern-lint/issues/64)

If user remove at hand folder tern (0.15.0), it works again. I have found a solution to fix that. The custom tern plugin must do require to the parent tern folder:

(function(root, mod) {
  if (typeof exports == "object" && typeof module == "object") {// CommonJS
    function _require(mod) {try {
        return require("../" + mod);
      }
      catch(e) {
        return require(mod);
      }
    }
    return mod(exports, _require("tern/lib/infer"), _require("tern/lib/tern"), _require("acorn/dist/walk"));
  }
  if (typeof define == "function" && define.amd) // AMD
    return define(["exports", "tern/lib/infer", "tern/lib/tern", "acorn/dist/walk"], mod);
  mod(root.tern || (root.tern = {}), tern, tern, acorn.walk);
})(this, function(exports, infer, tern, walk) {

This code is very uggly, but today I have not found other solution. Perhaps this problem could be fixed with tern, I don't know?

angelozerr avatar Jan 26 '16 13:01 angelozerr

I think there is something in the docs about this, particularly peer dependencies. http://ternjs.net/doc/manual.html#plugin_third_party Does that work?

puremourning avatar Jan 26 '16 20:01 puremourning

I just ran into this myself, because when I went looking for examples, I examined the built-in plugins, and coincidentally referred to @angelozerr's modules on NPM as well.

Perhaps the built-in plugins should implement an initialize method too, so that we have uniform way of doing things.

jacksonrayhamilton avatar Feb 21 '16 19:02 jacksonrayhamilton

I think the most important part is that with multiple versions of the tern server in the path, the globals go wrong, in particular the registrations. I had to change the architecture in ycmd to work around this, but I don't think it is actually solved. For example, i have tern 0.17.0 and tern-lint "requires" tern "^0.16.0", which isn't "compatible" which means that i get this:

/Users/ben/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/tern_runtime
├─┬ [email protected] 
│ ├── [email protected] 
│ ├─┬ [email protected] 
│ │ ├── [email protected] 
│ │ ├── [email protected] 
│ │ └── [email protected] 
│ ├─┬ [email protected] 
│ │ ├── [email protected] 
│ │ └── [email protected] 
│ ├─┬ [email protected] 
│ │ ├── [email protected] 
│ │ └── [email protected] 
│ └── [email protected] 
└─┬ [email protected] 
  └── [email protected] 

FWIW changing the package.json of @angelozerr's tern-lint from:


  "dependencies": {
    "tern": "^0.16.0",
    "acorn": "^2.6.4",
    "glob": "3",
    "minimatch": "0.2"
   },

to

  "peerdependencies": {
    "tern": "^0.16.0"
   },

Solves the issue, leaving this:

(tests)Bens-MBP:tern_runtime ben$ npm install --production
npm WARN prefer global [email protected] should be installed with -g
/Users/ben/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/tern_runtime
├─┬ [email protected] 
│ ├── [email protected] 
│ ├─┬ [email protected] 
│ │ ├── [email protected] 
│ │ ├── [email protected] 
│ │ └── [email protected] 
│ ├─┬ [email protected] 
│ │ ├── [email protected] 
│ │ └── [email protected] 
│ ├─┬ [email protected] 
│ │ ├── [email protected] 
│ │ └── [email protected] 
│ └── [email protected] 
└── [email protected] 

puremourning avatar Feb 21 '16 23:02 puremourning

This might be less of a problem with NPM 3, which installs only a single version of a package whenever possible. In general, the way NPM treats loading multiple versions of a library as completely expected is a bit of a pain, and I don't know a good way for a package to work around it.

marijnh avatar Apr 11 '16 09:04 marijnh