使用Composer在生产环境中安装npm和bower包(即无devDependencies)

15

在我的composer.json文件中,我在scripts部分中有以下内容:

    "post-install-cmd": [
        "php artisan clear-compiled",
        "php artisan optimize",
        "npm install",
        "bower install"
    ]
当运行“composer install”时,它将导致npm和bower安装其所有依赖项,默认情况下包括devDependencies。当进行生产部署时(例如,“composer install --no-dev”),我想启动“npm install --production”和“bower install --production”。
据我所知,似乎无法根据传递的标志更改'post-install-command'指定的列表,也无法设置可以传递给post-install-cmd中的命令的变量。
我有什么遗漏吗?似乎不可能使用composer只使用配置来执行开发和生产安装。我真的必须在生产环境中使用composer install --no-scripts,然后手动运行这四个命令吗?那似乎有些笨重。

3
Composer是一个“依赖管理器”,__不是__构建/部署工具。因此,你可能应该寻找像AnsibleAntCapistrano,[Phing](http://www.phing.info)等工具。 - Jasper N. Brouwer
4个回答

19

你可以使用PHP来进行环境检测,然后从同一个脚本中安装其他依赖项。这并不像在post-install-cmd中包含npm和bower那样好看和干净,但它可以让你得到你想要的结果。

"post-install-cmd": [
     "php artisan clear-compiled",
     "php artisan optimize",
     "php path/to/installer.php"
 ]

示例 installer.php:

// Logic to determine the environment. This could be determined many ways, and depends on how your
// application's environment is determined. If you're making use of Laravel's environment
// capabilities, you could do the following:
$env = trim(exec('php artisan env'));

// Clean up response to get the value we actually want
$env = substr($env, strrpos($env, ' ') + 1);

$envFlag = ($env === 'production')
    ? '--production'
    : '';

// Install npm
passthru("npm install {$envFlag}");
// Install bower
passthru("bower install {$envFlag}");

您可以让这个示例更加健壮,甚至可以为其创建一个Artisan命令。


2
你的安装/更新脚本可能会失败,因为你假设用户的机器上已经安装了npm,但实际情况可能并非如此。 - Shalom Sam
1
我认为假定已安装npm是合理的,因为原帖提供了这些命令。 - kfriend
抱歉,我的评论是针对楼主的,我并不打算贬低你的回答。只是提醒一下。这种方法可能对楼主有效,但如果正在开发的软件包面向整个社区,除非在安装文档中明确指定,否则它将失败。 - Shalom Sam
放心 :). 从 OP 的问题中,我相信他不是想要为公共包设置这个,而是为了他或他团队的开发工作流程。听起来他希望为每个开发人员安装与开发相关的软件包,然后部署他的网站/应用程序,并在生产服务器上安装时使用 --production 标志。 - kfriend

5
这将会起作用;
"post-update-cmd": [
        "php artisan clear-compiled",
        "php artisan optimize",
        "npm install",
        "bower install"
    ],
"post-install-cmd": [
    "php artisan clear-compiled",
    "php artisan optimize",
    "npm install --production",
    "bower install --production"
]

即,您应该在开发环境下运行“update”,而仅在生产环境下运行“install”。

2
如果我是一个人的团队,那么这将很好地运作,但是如果我希望其他团队成员从.lock文件中拾取composer中所有软件包的当前版本,他们将无法这样做。他们将被迫更新所有软件包或跳过开发依赖项。 - Dan B
2
那么我假设你应该先运行 'composer install',然后再运行 'composer update'。对于开发人员来说不应该是问题。 - Stepashka

3

虽然有点取巧,但你可以在bash中使用$PPID获取父命令的PID。从那里,你就能够获取命令行参数。

"post-install-cmd": [
    "ps -ocommand= -p $PPID | grep no-dev > /dev/null && echo called with no-dev || echo called without no-dev",
],

如果你想这样做,我会把它放在一个bash脚本中,并像这样运行:run-if-env-is-production.sh "bower install --production" 不过,我建议使用@kwoodfriend的解决方案,因为它更具可移植性,而且需要bash、ps和grep。

1

因为我使用npm、bower和gulp来构建我的资源文件,所以在生产环境中不需要它们的存在,这是我使用的composer.json:

    "post-install-cmd": [
        "php artisan clear-compiled",
        "php artisan optimize",
        "(ps -ocommand= -p $PPID | grep -q no-dev && true) || npm --loglevel silent install",
        "(ps -ocommand= -p $PPID | grep -q no-dev && true) || npm --loglevel silent install --global bower",
        "(ps -ocommand= -p $PPID | grep -q no-dev && true) || bower --silent install"
    ],
    "post-update-cmd": [
        "php artisan clear-compiled",
        "php artisan optimize",
        "(ps -ocommand= -p $PPID | grep -q no-dev && true) || npm --loglevel silent update",
        "(ps -ocommand= -p $PPID | grep -q no-dev && true) || bower --silent update"
    ]

...但是对我来说,在检测开发环境时使用如此棘手的命令似乎看起来很奇怪,或者不需要使用...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接