Laravel中NPM、Composer和Bower的区别是什么?

7
在Laravel中,有ComposerNPMBower三种依赖管理器。其中,Composer主要用于PHP依赖管理,通过composer.json文件来确定需要安装的包。你可以通过修改该文件或者运行php composer install <package>来安装所需的包。而NPM则主要用于JavaScript依赖管理,并且拥有大量的包。通过运行npm install命令来安装依赖,其安装的包由package.json文件决定。至于Bower,据我所知它主要用于前端包管理。
在Laravel中,你可以任意使用这三个工具。但是,在某些情况下,比如一个库既可以通过npm也可以通过composer来获取,你应该选择哪一个呢?
举个例子,在Laravel的安装中,有两个文件:app.js(应用程序的主JS文件)和bootstrap.js(在app.js中引入一些依赖项的文件)。
下面是resources/js目录下我的bootstrap.js文件的内容:
window._ = require('lodash');
window.Popper = require('popper.js').default;

/**
 * We'll load jQuery and the Bootstrap jQuery plugin which provides support
 * for JavaScript based Bootstrap features such as modals and tabs. This
 * code may be modified to fit the specific needs of your application.
 */

try {
    window.$ = window.jQuery = require('jquery');

    require('bootstrap');
    require('slick-carousel');
    require('isotope-layout/dist/isotope.pkgd.min.js');
    require('tablesorter/dist/js/jquery.tablesorter.combined.min.js');
} 

catch (e) {}

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

/**
 * Next we will register the CSRF Token as a common header with Axios so that
 * all outgoing HTTP requests automatically have it attached. This is just
 * a simple convenience so we don't have to attach every token manually.
 */

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

/**
 * Echo exposes an expressive API for subscribing to channels and listening
 * for events that are broadcast by Laravel. Echo and event broadcasting
 * allows your team to easily build robust real-time web applications.
 */

// import Echo from 'laravel-echo'

// window.Pusher = require('pusher-js');

// window.Echo = new Echo({
//     broadcaster: 'pusher',
//     key: process.env.MIX_PUSHER_APP_KEY,
//     cluster: process.env.MIX_PUSHER_APP_CLUSTER,
//     encrypted: true
// });

app.css文件中,我有以下内容:
/* 
 * This file takes all of the styling we need and compiles it into one nice CSS file.
 * You'll notice you can pull in anything from the node_modules folder use a Tiddle (~)
*/

@import '~bootstrap/dist/css/bootstrap.min.css'; // Bootstrap 3.3.7 CSS
@import '~slick-carousel/slick/slick.css';       // Slick Carousel base CSS

@import "variables";                             // Sass Variables

@import "partials/typography";                   // All from this point are from the partials folder
@import "partials/mixins";
@import "partials/helpers";
@import "partials/navigation";
@import "partials/breadcrumb-bar";
@import "partials/welcome-box";
@import "partials/form-box";
@import "partials/content-box";
@import "partials/carousels";
@import "partials/tables";
@import "partials/interactions-row";
@import "partials/downloads-area";
@import "partials/articles-events";
@import "partials/biography-pages";
@import "partials/grid";
@import "partials/footer";
@import "partials/steve-custom.scss";

我真正困扰的是:为什么 app.js 知道我正在引用 node_modules 文件夹中的文件,而 app.css 只需使用 ~ 就知道我正在引用 Bootstrap?为什么我不需要指定绝对路径?
一般来说,JavaScript 相关的项目通常来自于 npm,而 PHP 依赖项则来自于 composer。但是,我对 Laravel Full Calendar 包感到困惑,因为它的样式和 JS 代码似乎是通过 npm 获取的,但其 PHP 依赖部分却是通过 Composer 获取的。这种情况正常吗?
我知道有很多问题,但我觉得 Laracasts 没有很好地解释这些包管理器的实际用法。
1个回答

7
首先简要说明一下三个依赖管理器。

Composer

Composer 是一个用于管理PHP依赖项的工具。它使用Packagist获取有关依赖项的信息并为您正确安装它们。

NPM

NPM 是 Node 生态系统的一部分,最初是为了管理 Node.js 应用程序的依赖项而构建的。然而,随着 Node 的普及,人们开始将 NPM 用于不仅仅是 Node.js 模块的管理。现在,它已经成为管理 JavaScript 依赖项的准标准。

Bower

类似于 NPM,Bower 管理 JavaScript 依赖项。但是,Bower 的创建是为了将前端开发的包(如 Bootstrap、jQuery 等)与整个 Node 模块生态系统分离,并为 CSS 提供包管理器。它提供/提供了一些 NPM 不提供或没有的功能。

总结一下:Composer 用于 PHP 包,NPM 和 Bower 用于 JavaScript 包。我非常确定没有可同时在 Composer 和 NPM 上使用的包,因为它们专注于两种非常不同的编程语言。然而,Bower 可以被 NPM 替换,反之亦然。从我的角度来看,Bower 已经有点过时了,因为有一些其他更先进的工具,大多数项目只使用 NPM 进行依赖管理。


我们继续回答你的问题。

app.js 如何知道我正在引用 node_modules 文件夹中的文件,app.css 如何知道我只是通过使用 ~ 引用 Bootstrap?

不是文件本身知道波浪号(~)是 node_modules 目录的同义词。编译器[1] 知道应该在提到波浪号的任何地方查找包。
请注意,波浪号 > node_modules 同义词是 CSS 开发的概念,而不是 JavaScript。

为什么我不需要指定绝对路径?

你可以。你也可以使用相对路径。或者波浪号。事实上,这没有任何区别。它只取决于你使用的编译器。

是否有一个经验法则,即 JavaScript 相关项目通常来自 NPM,而 PHP 依赖项来自 Composer?

这不是一个经验法则,而是必须的。你不会在 NPM 中找到 PHP 模块,反之亦然。

我的困惑是因为我正在查看一个名为 Laravel Full Calendar 的包,它的样式和 JavaScript 代码似乎是通过 NPM 拉取的,但其 PHP 依赖部分是从 Composer 拉取的?

绝对合理。如果您有一个 Laravel 包,该包可向您的应用程序添加 Fullcalendar 支持,则我建议创建一个独立于 NPM 包的 PHP 包。PHP 包构建 HTML,而 NPM 包只提供 CSS 和 JavaScript。
我不会称这为正常行为,但是正如我所说的,这完全合理。
我希望我的回答让您理解了这个问题。我也同意,依赖管理的整个概念及其差异并不容易理解。如果您有任何其他问题,请留言。

[1] Compiler > 可以是将 app.scss 转换为 app.css 的任何模块。例如 node-sass。


所以基本上,它们都做自己的事情,彼此独立? - Jesse Orange
一些Composer包(例如tcg/voyager)也会附带.js.css文件。 - Adam

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