Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keep bundled /public and /private node_modules symlink content #9666

Merged
merged 4 commits into from Feb 21, 2018

Conversation

hwillson
Copy link
Contributor

Many npm based packages provide supporting assets that need to be made available, when used on the web. For example, to use the font-awesome package properly, the node_modules/font-awesome/fonts files need to be made accessible to incoming web requests.

With Meteor, an easy way to handle this would be to create a symlink to node_modules/font-awesome/fonts from within an application's /public directory. This would then allow all of font-awesome's font files to be accessed directly by incoming clients. Unfortunately, while this approach does work in development when using the Meteor Tool, it does not work when production bundles are created.

Meteor's isobuild process uses a helper class called SymlinkLoopChecker, to make sure the build process doesn't get caught up in an infinite loop trying to follow circular symlinks. Currently, a shared SymlinkLoopChecker instance is used to watch for symlink loops during both the _findSoures and _findAssets parts of the isobuild process. _findSources is called first, and covers source files that an application uses from the node_modules directory. The SymlinkLoopChecker tracks all of the node_modules directories covered, so they can be watched for in the future (to prevent duplicate inclusions). Next, _findAssets is called using the same SymlinkLoopChecker. This means that if there are any node_modules symlinks used in the public or private directories, they will be marked as being duplicates (and stripped), since they were already covered in the _findSources run.

This commit changes things a bit so that both _findSources and _findAssets use their own SymlinkLoopChecker instance. This opens up an applications symlink capabilities a bit, while still preserving some circular symlink safeguards. By doing this, a production application bundle can now maintain the contents of node_modules based symlinks, used in public and private.

So in the case of font-awesome for example

public/fonts --> ../node_modules/font-awesome/fonts

becomes the following in the production application bundle

bundle/programs/web.browser/app/fonts/[all fonts files]

Fixes #7013.

Many npm based packages provide supporting assets that need
to be made available, when used on the web. For example, to
use the `font-awesome` package properly, the
`node_modules/font-awesome/fonts` files need to be made accessible
to incoming web requests.

With Meteor, an easy way to handle this would be to create a
symlink to `node_modules/font-awesome/fonts` from within an
application's `/public` directory. This would then allow all
of `font-awesome`'s font files to be accessed directly by
incoming clients. Unfortunately, while this approach does work
in development when using the Meteor Tool, it does not work when
production bundles are created.

Meteor's isobuild process uses a helper class called
`SymlinkLoopChecker`, to make sure the build process doesn't get
caught up in an infinite loop trying to follow circular symlinks.
Currently, a shared `SymlinkLoopChecker` instance is used to watch
for symlink loops during both the `_findSoures` and `_findAssets`
parts of the isobuild process. `_findSources` is called first, and
covers source files that an application uses from the `node_modules`
directory. The `SymlinkLoopChecker` tracks all of the `node_modules`
directories covered, so they can be watched for in the future (to
prevent duplicate inclusions). Next, `_findAssets` is called using
the same `SymlinkLoopChecker`. This means that if there are any
`node_modules` symlinks used in the `public` or `private`
directories, they will be marked as being duplicates (and stripped),
since they were already covered in the `_findSources` run.

This commit changes things a bit so that both `_findSources` and
`_findAssets` use their own `SymlinkLoopChecker` instance. This
opens up an applications symlink capabilities a bit, while still
preserving some circular symlink safeguards. By doing this, a
production application bundle can now maintain the contents of
`node_modules` based symlinks, used in `public` and `private`.

So in the case of `font-awesome` for example

```
public/fonts --> ../node_modules/font-awesome/fonts
```

becomes the following in the production application bundle

```
bundle/programs/web.browser/app/fonts/[all fonts files]
```

Fixes meteor#7013.
@hwillson hwillson changed the title Keep bundled /public and /private node_modules symlink content [WIP] Keep bundled /public and /private node_modules symlink content Feb 13, 2018
@hwillson
Copy link
Contributor Author

Marking as a work in progress as I'd like to test this a bit more.

@hwillson hwillson changed the title [WIP] Keep bundled /public and /private node_modules symlink content Keep bundled /public and /private node_modules symlink content Feb 13, 2018
@hwillson
Copy link
Contributor Author

Additional testing done - ready for review! 😅

@benjamn benjamn added this to the Release 1.6.2 milestone Feb 21, 2018
@benjamn benjamn merged commit a58dc51 into meteor:devel Feb 21, 2018
lorensr pushed a commit to meteor/guide that referenced this pull request Oct 14, 2018
* Update using-npm-packages.md

This adds some documentation for this Issue #7013 PR #9666 that was released in Meteor 1.7.

meteor/meteor#9666

* use node_modules consistently

use node_modules consistently

* Lowercase npm package name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants