You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
More support for Laravel-specific npm stuff with Laravel 8.x / Mix 6.x, e.g. npm mix [--production] #2819
I'd like to be able to contribute some stuff to deployer 7.x to help with server-side building of Laravel assets, i.e. via Laravel Mix 6.x.
Laravel out-of-the-box is set up with the assumption that developers will usually build assets locally, and upload the compiled files to the production server during deployment, e.g. with rsync. However, using node and npm on the server to build assets as part of the deployment process itself can be preferable, and sometimes quicker.
The kind of thing I'm doing with deployer 6.x currently is (within the laravel recipe):
So that's what I'd want to replicate, but it feels like these should be optional tasks built-in to deployer, rather than having them done manually like this. What I'm a bit stuff on initially is whether this kind of thing would want to go into recipe/laravel.php or contrib/npm.php within deployer 7.x, or somewhere else entirely? I like, for example, how npm:install in deployer 7.x already copies node_modules over from the previous release.
Really happy to have a crack and coding this up and submitting a PR, but I could do with a few initial pointers..
Anyone else feel like they'd use this functionality if it was there?
We could still supply often-used tasks without having them called in the recipe. That way, devs who prefer a push-only approach can still make use of the predefined tasks.
..and because this is specific to Laravel Mix (https://laravel-mix.com/), instead of a pure npm command, would you suggest this should be in a new file e.g. contrib/laravel-mix.php, rather than in contrib/npm.php ?
I imagine the basics of the code being something like:
The addition of the --production flag would need to be configurable on/off, but ideally it would by default be included only if APP_ENV=production was detected in an existing .env file. How might that be achieved?
I'd put that in the Laravel recipe since recipes are on a framework-basis and Mix isn't it's own framework.
Deployer doesn't natively support dotenv, so if you really want to rely on the APP_ENV var, you'd have to create some custom parsing of the .env file. I usually handle this in Deployer by parsing the host data inside a task;
// This is Deployer 7 code$host = Task\Context::get()->getHost();
$labels = $host->getLabels();
Hey guys, I'm not sure I understand the benefits of having Laravel mix specific tasks available on Deployer.
I use Deployer to both install and compile frontend assets and never needed such thing. By default, Laravel projects have lots of scripts in their package.json that delegate to Laravel mix with various predefined configurations. To compile your assets in your deployment flow, you simply need to create one custom task on your deploy.yaml or deploy.php file that calls npm run prod or any other script you might prefer.
I don't think this should be included in the Laravel recipe or any other recipes because we would open a can of worms were Deployer would be responsible for knowing which script is the right one to call for each framework. For instance, another framework might go with the npm run build convention.
I think all we need is a little documentation that educate people on how to do add a little task to compile their assets and let them choose their own npm script based on their need.
All of them by default. But I've never seen anyone or any project not rely on npm scripts to delegate to mix.
I appreciate your input @lorisleiva, but it seems that the ultimate endpoint of your argument would be that there shouldn't be any framework-specific recipes included with deployer at all, and everything should instead be spelled out 'by hand'.
The whole idea of framework-specific recipes is exactly so that deployer can, in those scenarios, take responsibility for knowing what steps and commands each different framework requires. That's not a can of worms! That's a helpful thing.
While there is a Laravel-specific recipe, then I think it can carry optional tasks to perform whatever on-server processes users may need. For example, there are optional artisan: tasks for just about anything you might want to do with artisan, even if these are not typical things that would be performed in a production environment. That's why they're optional.
An example of how an on-server mix build process could be made simpler, and provided for optional use within the Laravel recipe might be to have a task called e.g. mix:build which encapsulated both the npm:install and npm:run:prod tasks you included in your example (although npm run prod is a little outdated now in current Laravel/Mix setups vs. npx mix [--production]).
it seems that the ultimate endpoint of your argument would be that there shouldn't be any framework-specific recipes included with deployer at all, and everything should instead be spelled out 'by hand'.
It is not.
I built most of these Laravel artisan tasks and carefully selected the ones that could be helpful for developers to use even including third-party packages such as Horizon and Telescope.
I know that developer experience is one of the most important aspects of OSS and my point is not that developers should do everything "by hand". However, when maintaining OSS, it is also important to take a step back and try to predict if a feature request would be helpful to a majority of users because, no matter how small the feature is, once it's added to the feature set, it has to be maintained and is a lot more difficult to remove later.
The point I am making here is the following: I don't think adding "Laravel Mix" specific tasks is worth it.
Additionally, I do think that, if we did, it would unnecessarily legitimate the need for this repository to maintain more ways to compile assets when — 99% of the time — npm scripts are used to abstract that for you.
although npm run prod is a little outdated now
That's not correct. If you look at the latest official documentation of Laravel mix, you will see that using npm script is the recommended convention, just like it is in most project.
In conclusion, improving the developer experience in OSS is about accepting the right feature requests and challenging the ones that could compromise it which is why I am challenging this one.
Perhaps the contrib/npm support in deployer 7.x does actually mean that once 7.x is released, adding on-server asset building for Laravel will actually be simple enough (compared to deployer 7.x).
I simply started this thread to work out if there was something here worth contributing to deployer.
Also to bear in mind is that fact that, as I mentioned at the start, Laravel doesn't come out-of-the-box with on-server builds in mind anyway, that's very much a "you're on your own" realm for Laravel devs. I'm sure many 1st-party paid apps that Laravel maintains probably do build this way, but it's not really documented anywhere as a supported approach.
Regards the 'outdated' thing, I was referring to the fact that in the latest Laravel skeleton's package.json, the 'traditional' dev and prod commands actually defer to running just mix [--production], rather than a longer command chain..
No worries, I'll try to provide more helpful content in this (rather long) comment. 😄
That's absolutely fine if you prefer using the underlying mix command directly. My point is mostly that I've never seen anyone rely on this directly in the Laravel community because you've got these handy recommended npm scripts that are all ready to use. But, say you wanted to use mix with custom options instead, you could also call mix directly in your deploy.yaml file like this.
Although, personally I'd still use npm run prod and update the npm script so other developers are aligned with the definition of "compiling assets for production".
"scripts": {// ..."prod": "npm run production","production": "mix --production --some-custom-options"},
One generic task that could improve developer experience is an npm:run task that uses an option to know which npm script to run. Something like that.
// Give a good default used by most frameworks out there.set('npm_run_script', 'build');
desc('Runs an npm script.');
task('npm:run', function () {
cd('{{release_or_current_path}}');
run('{{bin/npm}} run {{npm_run_script}}');
});
This would allow you to compile your assets in Laravel that way.
Maybe. The advantage of the former is that we can change the npm script when executing the deploy command like this.
dep deploy -o npm_run_script=staging
Or even set up different scripts per host in the host configurations.
Regarding the Laravel convention when it comes to building and deploying assets, I've seen mostly three techniques:
Build locally and deploy. This expects you to run npm run prod before every deployment and will simply push the compiled assets to your new release.
Build inside your deployment script. This is handy because you can run npm run watch locally and not need to worry about compiling assets for production before deploying. However, if compiling your assets takes a lot of time and resources, you might actually end up with a little downtime on your server as your PHP server may not have enough resources left to handle its requests (depending on your server setup of course).
Build inside a CI/CD pipeline and deploy. This is kind of the best of both worlds where you expect a CI/CD pipeline such as GitHub actions to build your assets and then push this to a new release using Deployer. It's not easy to set up though.
Most of the projects I've worked with tend to use the second option because it's easy, handy and good enough in most cases.
I don't think it's necessarily a bad idea but when I look at tools like vercal they defer to npm scripts too. I would personally delegate to the npm scripts because mix can be run with multiple options and even sometime need run multiple times for certain scenarios. Building for prod may not always be as simple as mix -p. Especially for those using laravel-mix-merge-manifest and custom mix files for an SSR build. I hope to make that less of a need in the future (… been working on it for a while now in my spare time) but it's sill something to consider.
Reacted by Anton Medvedev, Loris Leiva and Jonny Nott
Activity
peterjaap commentedon Dec 7, 2021
We've had a similar discussion about this on Magento 2; #2734
Especially this comment by @antonmedv is relevant; #2734 (comment)
antonmedv commentedon Dec 7, 2021
Npm install & npx mix steps looks really simple to implement on user side.
Why to include it in common recipe? What if user builds only API?
jonnott commentedon Dec 7, 2021
Exactly, I don't think it should be in the standard laravel recipe. But what if npx mix was optionally available via contrib/npm?
peterjaap commentedon Dec 7, 2021
We could still supply often-used tasks without having them called in the recipe. That way, devs who prefer a push-only approach can still make use of the predefined tasks.
antonmedv commentedon Dec 7, 2021
Contrib is the right place for a such recipe)
jonnott commentedon Dec 7, 2021
Great.
..and because this is specific to Laravel Mix (https://laravel-mix.com/), instead of a pure npm command, would you suggest this should be in a new file e.g.
contrib/laravel-mix.php, rather than incontrib/npm.php?I imagine the basics of the code being something like:
The addition of the
--productionflag would need to be configurable on/off, but ideally it would by default be included only ifAPP_ENV=productionwas detected in an existing.envfile. How might that be achieved?jonnott commentedon Dec 7, 2021
@JeffreyWay @thecrypticace 👀
peterjaap commentedon Dec 8, 2021
I'd put that in the Laravel recipe since recipes are on a framework-basis and Mix isn't it's own framework.
Deployer doesn't natively support dotenv, so if you really want to rely on the
APP_ENVvar, you'd have to create some custom parsing of the .env file. I usually handle this in Deployer by parsing the host data inside a task;lorisleiva commentedon Dec 8, 2021
Hey guys, I'm not sure I understand the benefits of having Laravel mix specific tasks available on Deployer.
I use Deployer to both install and compile frontend assets and never needed such thing. By default, Laravel projects have lots of scripts in their
package.jsonthat delegate to Laravel mix with various predefined configurations. To compile your assets in your deployment flow, you simply need to create one custom task on yourdeploy.yamlordeploy.phpfile that callsnpm run prodor any other script you might prefer.I don't think this should be included in the Laravel recipe or any other recipes because we would open a can of worms were Deployer would be responsible for knowing which script is the right one to call for each framework. For instance, another framework might go with the
npm run buildconvention.I think all we need is a little documentation that educate people on how to do add a little task to compile their assets and let them choose their own npm script based on their need.
Here's an example.
peterjaap commentedon Dec 8, 2021
I agree with @lorisleiva as well in broad lines. I guess it depends on what percentage of Laravel installs use Mix. Are there any figures on that?
lorisleiva commentedon Dec 8, 2021
All of them by default. But I've never seen anyone or any project not rely on npm scripts to delegate to mix.
jonnott commentedon Dec 8, 2021
I appreciate your input @lorisleiva, but it seems that the ultimate endpoint of your argument would be that there shouldn't be any framework-specific recipes included with deployer at all, and everything should instead be spelled out 'by hand'.
The whole idea of framework-specific recipes is exactly so that deployer can, in those scenarios, take responsibility for knowing what steps and commands each different framework requires. That's not a can of worms! That's a helpful thing.
While there is a Laravel-specific recipe, then I think it can carry optional tasks to perform whatever on-server processes users may need. For example, there are optional
artisan:tasks for just about anything you might want to do with artisan, even if these are not typical things that would be performed in a production environment. That's why they're optional.An example of how an on-server mix build process could be made simpler, and provided for optional use within the Laravel recipe might be to have a task called e.g.
mix:buildwhich encapsulated both thenpm:installandnpm:run:prodtasks you included in your example (althoughnpm run prodis a little outdated now in current Laravel/Mix setups vs.npx mix [--production]).lorisleiva commentedon Dec 8, 2021
It is not.
I built most of these Laravel artisan tasks and carefully selected the ones that could be helpful for developers to use even including third-party packages such as Horizon and Telescope.
I know that developer experience is one of the most important aspects of OSS and my point is not that developers should do everything "by hand". However, when maintaining OSS, it is also important to take a step back and try to predict if a feature request would be helpful to a majority of users because, no matter how small the feature is, once it's added to the feature set, it has to be maintained and is a lot more difficult to remove later.
The point I am making here is the following: I don't think adding "Laravel Mix" specific tasks is worth it.
Additionally, I do think that, if we did, it would unnecessarily legitimate the need for this repository to maintain more ways to compile assets when — 99% of the time — npm scripts are used to abstract that for you.
That's not correct. If you look at the latest official documentation of Laravel mix, you will see that using npm script is the recommended convention, just like it is in most project.
In conclusion, improving the developer experience in OSS is about accepting the right feature requests and challenging the ones that could compromise it which is why I am challenging this one.
jonnott commentedon Dec 8, 2021
@lorisleiva Agree with what you're saying.
Perhaps the
contrib/npmsupport in deployer 7.x does actually mean that once 7.x is released, adding on-server asset building for Laravel will actually be simple enough (compared to deployer 7.x).I simply started this thread to work out if there was something here worth contributing to deployer.
Also to bear in mind is that fact that, as I mentioned at the start, Laravel doesn't come out-of-the-box with on-server builds in mind anyway, that's very much a "you're on your own" realm for Laravel devs. I'm sure many 1st-party paid apps that Laravel maintains probably do build this way, but it's not really documented anywhere as a supported approach.
Regards the 'outdated' thing, I was referring to the fact that in the latest Laravel skeleton's
package.json, the 'traditional'devandprodcommands actually defer to running justmix [--production], rather than a longer command chain..lorisleiva commentedon Dec 8, 2021
No worries, I'll try to provide more helpful content in this (rather long) comment. 😄
That's absolutely fine if you prefer using the underlying
mixcommand directly. My point is mostly that I've never seen anyone rely on this directly in the Laravel community because you've got these handy recommended npm scripts that are all ready to use. But, say you wanted to usemixwith custom options instead, you could also call mix directly in yourdeploy.yamlfile like this.Although, personally I'd still use
npm run prodand update the npm script so other developers are aligned with the definition of "compiling assets for production".One generic task that could improve developer experience is an
npm:runtask that uses an option to know which npm script to run. Something like that.This would allow you to compile your assets in Laravel that way.
However, one could also argue: is this really much better than what we had before?
Maybe. The advantage of the former is that we can change the npm script when executing the deploy command like this.
Or even set up different scripts per host in the host configurations.
Regarding the Laravel convention when it comes to building and deploying assets, I've seen mostly three techniques:
npm run prodbefore every deployment and will simply push the compiled assets to your new release.npm run watchlocally and not need to worry about compiling assets for production before deploying. However, if compiling your assets takes a lot of time and resources, you might actually end up with a little downtime on your server as your PHP server may not have enough resources left to handle its requests (depending on your server setup of course).Most of the projects I've worked with tend to use the second option because it's easy, handy and good enough in most cases.
thecrypticace commentedon Dec 8, 2021
Throwing my two cents in here:
I don't think it's necessarily a bad idea but when I look at tools like vercal they defer to npm scripts too. I would personally delegate to the npm scripts because mix can be run with multiple options and even sometime need run multiple times for certain scenarios. Building for prod may not always be as simple as
mix -p. Especially for those using laravel-mix-merge-manifest and custom mix files for an SSR build. I hope to make that less of a need in the future (… been working on it for a while now in my spare time) but it's sill something to consider.