简体   繁体   中英

Using multiple packages in Meteor 1.3+ that include the same npm package

I would like to know how to create / use multiple packages in Meteor 1.3+ that use the same npm dependency.

I have migrated to Meteor 1.3+ and with that am trying to use the npm versions of the angular & angular-meteor packages but I am struggling to fully understand how npm is used in packages & cannot seem to get it working as needed.

I have an existing Meteor application where I have split functionality into Meteor packages to promote modularity & reusability - instead of directly in the Meteor root.

I have tried several different ways of structuring this to no avail.

The structure I would ideally like

This is my preferred way of doing it because I then don't need to worry about what npm packages my Meteor packages depend on.

If I structure my application as follows:

Meteor App
   Meteor Package A
      NPM Package angular@1.5.5
      NPM Package angular-meteor@1.3.10
   Meteor Package B
      NPM Package angular@1.5.5
      NPM Package angular-meteor@1.3.10

I achieve this by using Npm.depends() in each package's package.js file; which creates a .npm folder in that package:

Npm.depends({
  'angular': '1.5.5',
  'angular-meteor': '1.3.10'
});

In the js files I have the following at the top of any file that uses either angular and/or angular-meteor .

// Included only when angular is needed
import angular from 'angular';
// Included only when angular-meteor is needed
import angularMeteor from 'angular-meteor';

The problem with this method is that I then get the following error in the browser console once for each package that has the duplicate npm dependency: WARNING: Tried to load angular more than once. ; since I would imagine Meteor is trying to include angular for each package that uses it.

From what I can gather this is unlike Meteor packages which Meteor knows to only include once; which is how I was using it before migrating to Meteor 1.3+

Alternative

The only way I can seem to get it to work is if I include the npm dependencies directly in the meteor app.

Keeping everything the same as above but removing the Npm.require() from the package.js files. I then do meteor npm install --save angular angular-meteor so that the angular & angular-meteor packages are added directly into the meteor app & only ever included once in the whole project.

The structure then becomes:

Meteor App
   NPM Package angular@1.5.5
   NPM Package angular-meteor@1.3.10
   Meteor Package A
   Meteor Package B

Although this works now the problem with this method is twofold:

  • If I need to use a 3rd party package (that I have no control over) that uses Npm.depends() for a npm package that I have already included in my project I will get the same duplicate error as above.
  • I then also need to manage npm dependencies for packages at the application level which is not ideal since I need to remember to remove dependencies when & only when they are no longer needed by any of the remaining packages.

I am not yet marking this as answered since I have not found a solution to my problem but I have made some progress with regards to error messages that might help others.

Part of my problem was related to the fact that I was still using the Meteor package for angular-ui-router instead of updating my project to use the npm version. The error WARNING: Tried to load angular more than once. was generated because the Meteor version of angular-ui-router is dependent on the Meteor package angular ; which appears to be included in a different way to npm packages such that Meteor does not detect that it is already loaded & loads it again.

As for my problem of wanting to use Npm.require() for npm packages within the browser... from what I can gather there is no way of doing this from within Meteor packages. There is the hack of running npm install within the package & including each needed file in the package.js file using api.addFiles( ... , 'client' ) but this has obvious drawbacks such as not knowing which Meteor packages include which files from their npm dependencies - so you could end up with 2 Meteor packages each trying to include bootstrap (for example), resulting in duplicate includes within the Meteor app.

Since I am of the opinion that Meteor will deprecate Meteor packages in some future release of Meteor - in favour of pure npm packages - I am going to leave this train of thought and resign myself to using npm install at the root level for all npm packages that I need to use. With the above assumption that it cannot be done, it would stand to reason that I won't run into conflicts with other packages using Npm.require() for a npm package I have added through npm install .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM