Open Cartman34 opened 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!
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.
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:
ux
repositories.
OS
Ubuntu 22.04
, Symfony6.1
, node18.5
, npm8.19.2
, yarn3.2.3
, reactjs18.2
In fact, with many changes to the Symfony ecosystem over the past year, it's hard to put together all needed information.
C)
"keywords": ["symfony-ux"]
part in bundle's composer.json
/assets
folder, but I noticed that it does not matter whether it is according to the old or new convention - it just worksJS part
in app
:
The thing I do is set up package.json
in the application to use symlinks for my package (for development time)
/package.json
"resolutions": {
"@vendor_name/my-shiny-new-bundle": "portal:$HOME/path/to/bundle/assets"
}
yarn link $HOME/path/to/bundle/assets
in bundle
:
First, I did some alpine combinations with symlinks in the opposite direction,
"devDependencies": {
"@hotwired/stimulus": "portal:../up/stairs/to/the/{app}/node_modules/@hotwired/stimulus",
"core-js": "portal:../up/stairs/to/the/{app}/node_modules/core-js",
"react": "portal:../up/stairs/to/the/{app}/node_modules/react",
"react-dom": "portal:../up/stairs/to/the/{app}/node_modules/react-dom",
...
}
but at the end it turned out, that devDependencies
are not needed at all
flex installs the package and adds to package.json
something like:
"@vendor_name/my-shiny-new-bundle": "file:vendor/vendor_name/my-shiny-new-bundle/assets"
"Don't forget to run npm install --force or yarn install --force to refresh your JavaScript dependencies!"
of course, just yarn
I'm using
yarn ^3
so there is no flag--force
, instead you can use--check-cache
, the wordinstall
is not needed
All this results in:
Symlinking from ...
➤ YN0072: │ The application uses portals and that's why --preserve-symlinks Node option is required for launching it
So, last piece of cake:
Go into webpack.config.js
:
const webpackConfig = Encore
// ...
// some magic
// ...
.getWebpackConfig()
webpackConfig.resolve.symlinks = true
module.exports = webpackConfig
As tested, it works great for both
dev-server
andwatch
app
andbundle
at the same time and even in the same IDE
There is no core-js
or even react
issues, but of course it depends on setup.
Hope it helps someone
Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?
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.