fxpio / foxy

A fast, reliable, and secure NPM/Yarn/pnpm bridge for Composer
https://foxypkg.com
MIT License
173 stars 21 forks source link

Asset paths in libraries #23

Closed SamMousa closed 5 years ago

SamMousa commented 5 years ago

Suppose I have a library that needs some npm package(s). Normally I would just assume these assets are manually installed (and therefore located in the node_modules folder). Obviously when using foxy this will no longer be the case.

How would my library know where to look for the assets? Should foxy create something like symlinks to the main node_modules folder? Or should it somehow make the location of that folder available to the PHP world?

On the PHP side with composer we basically no longer care about paths since we have autoloading; for assets however we still need the path or the URL or a way to publish them without knowing the path. Ideally we would want to support this without requiring changes in the libraries themselves...

francoispluchino commented 5 years ago

All assets dependencies are installed in the node_modules directories (if you haven't changed the NPM configuration). So, you work with the assets in the same way as if you added them to your project's package.json file.

You have no change to make to your asset libraries, but add only the package.json file with the required dependencies to your PHP library, and add the foxy/foxy dependency in your composer.json file of your PHP library (see the doc to use Foxy with the PHP library). Foxy automatically adds the dependencies so that NPM or Yarn can install them. After, you can use your favorite workflow for the assets, such as Webpack, Grunt, Gulp, etc...

For more details, you can read the FAQ, and mainly:

Given that the multitude of possible ways to load asset dependencies, Foxy doesn't handle this part, and leaves it to specialized JS tools like Webpack. However, you can create for example, a Webpack plugin to automatically add the imports of JS widgets to your assets/app.js file.

SamMousa commented 5 years ago

I've read the docs, I know where they go by default in when using npm.

But normally I know where that is relatively to my code.. When a library is included I do not know the root dir so how would I know where to find node modules?

Suppose I want to include a JS file from an npm package in a page rendered by PHP?

francoispluchino commented 5 years ago

Can you further develop your example? I'm not sure where you want to include the JS library.

The link in the html tag generated by your PHP server? Or from another JS file?

SamMousa commented 5 years ago

The link in the HTML tag generated by PHP.

francoispluchino commented 5 years ago

Ok, as I said, this part is not managed by Foxy, but it must be managed by the asset manager of your application or Framework (eg. Assetic, Symfony Assets with Symfony Webpack Encore, Laravel Mix, or other).

SamMousa commented 5 years ago

I understand, but my library would not necessarily know that it is being used by a framework, right? So if normally I assume that the assets are installed relative to my package.json (which is what npm and yarn) do, then that assumption doesn't hold when using foxy.

I know Foxy doesn't currently help with that, but it might be worth considering how one could solve that problem?

francoispluchino commented 5 years ago

Given that there is no standard, everyone manages their asset dependencies as they wish. The current trend is to use Webpack to pack all the assets, and your library can make a choice of this or that technique. But perhaps in your case, Composer Asset Plugin is wiser, although I think the problem will still be present.

Regarding Foxy, I will perhaps give a use case where it is very useful, and which is behind the creation of this plugin to replace Composer Asset Plugin. I have a SaaS application that is based on an internal "platform", and each reusable feature is cut into a module (technically Symfony bundles with configuration extras). For the front-end, it's a packaged SPA with Webpack (and Symfony Webpack Encore).

So, the platform has on one side, a configurator/generator for the PHP server with a Composer plugin and a Symfony Bundle, and on the other, a Webpack plugin to automatically configure the web app. Between the 2, Foxy that serves as a link in the dependencies.

To be more precise, each PHP module indicates the asset dependencies and a small configuration in the package.json file dedicated to the platform-specific Webpack plugin. This Webpack plugin automatically imports Front-end widgets into the SPA application (which therefore also has its own mechanism for building routes, menus, etc...). As for the PHP module, it take of the loading of the business logic, defining the entities and fields for the ORM, defining new API routes, listeners, filters, etc... Of course the loading of the module is managed by Symfony Flex, but the whole configuration system is a Composer plugin over Flex and an additional Symfony bundle.

However, in the final application, I have a "classic" website system, and I use the fxp/require-asset with fxp/require-asset-bundle library to include the asset links (js and css) built by Webpack and dedicated to each page.

In this way, Foxy only do what it has to do, that is, include the asset dependencies in the project, and let the platform take care of packaging and managing everything, creating the final application.

I'm aware that this is a workload to do if you do not use an Framework including an assets manager, but like there is no standard, and a multitude of ways to do it, and the utility of Foxy only resides in dependency resolution, I do not think this feature should be included in this plugin. But you can very well create this component using Foxy (which I did, but dedicated to my platform, and therefore not public).

I hope this will help you better understand Foxy's purpose.

SamMousa commented 5 years ago

I use the Yii2 framework; the common approach there is basically a global alias to the npm or bower directory.

I understand your scenario and that sounds logical; but many older PHP widgets use a combination of PHP rendering and referencing assets. For a library that's hard to do in a generic sense unless you depend on a framework.

I was hoping this project could offer some more guidance for a generic approach that could be framework agnostic.

Anyway from your answers I conclude that that is not a goal for now. I'll give it some more thought and if I think of a clean way of doing this I'll make a proposal for it.

francoispluchino commented 5 years ago

Yii2 uses fxp/composer-asset-plugin to manage the asset dependencies, even though they now use Asset Packagist, which uses this Composer plugin. It is therefore preferable that the Yii Framework changes his component, and updates the management of the assets in the framework, but in this case, there will be a compatibility break. Or else, you can try to create a library for Yii2 that creates a gateway between a "javascript bundler" (webpack, grunt, gulp, etc.) and the Yii2 asset manager (eg. my previous message).

What is certain, is that the paradigm of asset management has evolved a lot lately, and it becomes more and more difficult to not use JavaScript tools such as nodejs, npm/yarn, webpack, typescript, scss, etc. to create the frontend, even if it is not a SPA.

I remember that @schmunk42 wanted to integrate Foxy with Yii2, but I don't know if he had time to do it or not. Maybe you should see with him directly?

schmunk42 commented 5 years ago

We talked about this during a chat about Yii integration ;)

francoispluchino commented 5 years ago

It seems to me that there are proposals to replace CAP by Foxy in Yii Framework, so I close this issue. Do not hesitate to reopen it if necessary.