symfony / webpack-encore

A simple but powerful API for processing & compiling assets built around Webpack
https://symfony.com/doc/current/frontend.html
MIT License
2.23k stars 198 forks source link

How to develop a webpack package locally ? #1129

Open Cartman34 opened 2 years ago

Cartman34 commented 2 years ago

Hi,

I am developing a Symfony bundle using classic Sf features (views, controllers, entities,...;) but with also JS stimulus controllers and SCSS. So, the project stack is Npm + Webpack Encore + Stimulus + PHP + Symfony 6.1.

By installing the local composer package, Flex should consider my bundle as an embedded node module, but Flex does nothing, I linked it manually, this works but not perfectly and I would do it the legit way.

To develop the bundle, I created a package.json in the assets folder in a separate project. The package is added to the project by its local path on my file system using "file:", then I run npm run watch, this is working properly, sometimes I am getting errors with missing core-js. But by developing locally, I would changes to be detected by webpack to compile the new changes. Using "file:", yarn/node seems to create a copy of my sources, so it won't listen the sources for changes.

I also tried using link: but webpack is failing to compile.

So the whole thing is a bunch of wonky repairs and I did not find a good tutorial to explain how to do that with Webpack Encore + Sf 6.1.

How to develop a webpack package locally ? How is this recommended ? Considering, I can not run a symfony or docker server, everything is on a local VM and PhpStorm is deploying automatically on it..

NB: I am looking for information, I tried stackoverflow with no success.

weaverryan commented 2 years ago

Yea, this is not a super easy process. You should (and it sounds like you already are) follow the examples from the symfony/ux repository - e.g. https://github.com/symfony/ux/tree/2.x/src/Autocomplete

What I usually do (and there is almost definitely some room for improvement) is this:

A) I have a WIP version of my bundle locally B) I create a brand new Symfony project that I will use for testing the bundle. C) I install the bundle using a "path" repository - https://getcomposer.org/doc/05-repositories.md#path - just a simple way of getting the bundle installed "properly" into your app... but it really just points at your local directory. D) I then usually (to easy dev) delete the vendor/ directory of the bundle and replace it with a symlink. e.g. rm -rf vendor/symfony/ux-autocomplete then replace it with a symlink to where the bundle actually lives on my system. Then, php changes to the bundle will be used instantly.

Now, about the JS part, which is what you're really asking about.

By installing the local composer package, Flex should consider my bundle as an embedded node module, but Flex does nothing, I linked it manually, this works but not perfectly and I would do it the legit way.

Make sure you have the symfony-ux keyword - https://github.com/symfony/ux/blob/990fb8e717486bf775a7cc6683725f8d81b49968/src/Autocomplete/composer.json#L6 - that is actually the trigger (and that needs to be documented).

If your bundle is setup correctly (and it sounds like it is), you should now have the file: part in your package.json pointing to the bundle in vendor/. And so, in theory, everything should work (assuming the js "package" in your bundle has been packaged up into a dist directory - we use rollup for this).

Let me know what issues you hit. The process is cumbersome, and I'd welcome any automation or documentation for this. Additionally, I often will disable the Stimulus controller I'm working on in assets/controllers.json, but instead register it manually in assets/bootstrap.js... but point directly to the vendor version of the file (e.g. import '../vendor/symfony/..../dist/controller). The reason is that the path will now look like it is NOT in node_modules/, and so yarn watch will rebuild when it sees changes and you can, in theory, even point this at your source typescript files and those can be parsed (whereas normally if you point Webpack at .ts files in node_modules, it will not parse them as it expects node_modules stuff to already be in normal JS).

Cheers!

Cartman34 commented 2 years ago

Hi, a great thank you ! You saved my day by fixing the half of the issues !

About A/B/C, I am doing this way. About D, My bundle has no vendor as it does not run by itself, I never ran composer in it, I edit it's composer.json manually, is it good ?

About symfony-ux keyword, this was the missing part. It seems there is a lack of documentation about this, maybe it should be here => https://symfony.com/doc/current/frontend/ux.html And many (All ?) UX projects are using the former folder structure (Resources/assets/src/). It's now handling package.json and controllers.json I think a complete & solid example should go with documentation (Autocomplete ?).

In bundle, my assets are in assets/ folder, as required by documentation, my bundle has no compiled ressources as it has to consider the style and customization of main projet, so the main project compiled it, it could contain SCSS files, JS services, JS stimulus controllers, other JS classes...

I will try your tips, I tried to override watch options to change ignored properties in webpack.config.js with no real success.

    .configureWatchOptions(function (watchOptions) {
        watchOptions.ignored = /node_modules([\\]+|\/)+(?!sowapps)/;
    })

It's inspired from something I found on the internet

But for this part, I am still stuck with core-js issue. I will answer you in the mentioned issue.

EDIT: I tried to register controller using

import MyController from '../vendor/author/package/assets/controllers/input/my_controller.js';
app.register('author--package--input-my', MyController);

But I am still having the core-js issue.

anatholius commented 2 years ago

Hi @Cartman34, @weaverryan

I am also trying to figure out how to create a bundle (and also libraries), with nice DX, containing frontend resources according to Symfony UX solutions.

I was able to create a setup for local development to use existing solutions completely without hacking core files. So I wanted to share this adventure and verify it doesn't break any rules (or does it only work for me?)

Here's what I did:


There is no core-js or even react issues, but of course it depends on setup.


Hope it helps someone

carsonbot commented 3 weeks ago

Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?