2017-07-29
版本:v1.3.1
源码:fxpio/composer-asset-plugin
翻译:JAY
【翻译序】
composer-asset-plugin是一个用来安装前端资源包的Composer插件。Yii2就是通过这个插件来安装的,所以安装Yii2之前需要全局安装这个插件,否则会出现bower文件夹缺失等疑难杂症。而安装了这个插件之后,又会绕过Composer的中国镜像直接从github上下载资源,导致安装过程变慢。
许多PHP开发者对前端了解不多,这插件中文介绍极少,Yii2的安装教程也只一句话带过,因此常有萌新被坑得一脸懵逼。在此翻译本插件的文档,以供查阅。
(后记:Yii2.0.13之后不再推荐这个插件,可以改用asset-packagist)
以下为译文:
Composer 的 NPM/Bower 依赖管理器
composer-asset-plugin能让您通过composer.json管理项目中的前端资源文件(css、js 等),而不用安装NPM或Bower。通过把NPM或Bower的版本号转为Composer的版本号,可以直接用PHP管理依赖的前端资源。
功能包括:
使用本地资源库
使用公开发布的前端资源库
对前端资源文件进行延迟加载以提高性能
筛选导入的根包和依赖包文件以提高性能
从以下库中自动获取资源文件:
自动获取每个包中依赖项的资源文件(包括开发版本)
根据以下映射转化为Composer的依赖:
NPM Package - package.json
Bower Package - bower.json
将语义化版本号转换为Composer版本号(Semver version)
将语义化版本号范围转换为Composer版本号范围(Semver range version)
通过创建的VCS库将url依赖转换为Composer依赖(dependencies with URL)
将同一依赖项的多个版本转换为不同的Composer依赖
在项目中手动添加同一依赖项的多个版本
根据Composer配置直接重写VCS库配置
支持以下源:
本地缓存系统:
版本号
依赖包
前端资源重定向
通过根目录下的composer.json自定义安装配置
在Bower中,标记了“忽略”的所有文件将不会被安装
替换和删除Bower中禁用或删除忽略的文件
允许手动删除NPM的忽略文件
使用Composer忽略文件的脚本
在全局或环境变量中配置每个项目的插件
与所有命令兼容, 包括:
depends
diagnose
licenses
remove
require
search (bower only)
show
status
为什么需要这个插件?
在 php 项目中, 有几种以下几种管理资源的方法:
安装Node.js,每次运行完Composer命令后再运行使用NPM或Bower命令;
写一个自动化脚本来执行上面的命令;
把前端资源直接放到项目中(不推荐);
创建一个依赖所有资源包的扩展,并使用Composer来安装
把前端资源的下载链接写到composer.json中
建立一个管理前端资源的服务器
其他?
前端开发者都知道,javascript、css等库都有自己的开发和管理工具,NPM和Bower都被广泛使用。然而,在一个完整的PHP项目中,开发人员希望Composer支持PHP以外扩展,这样就不用为了安装插件同时安装好几个工具 (Node.js、NPM、Bower、Grunt等) 。这个插件正是为了解决这些问题而创建的。
文档
基本用法
安装
(译者注:请先安装Composer。)
参阅Release信息,了解所需的Composer版本。
全局安装
composer global require "fxp/composer-asset-plugin:~1.3.1"
项目内安装
不支持项目内安装(原因:issus)。
使用
使用前端资源库
把前端资源添加到composer.json的require属性中,使该资源成为项目中的一个依赖。
必须以 {asset-type}-asset/. 为前缀。
比如这样添加bootstrap库(NPM):
{ "require": { "npm-asset/bootstrap": "dev-master" } }
或(Bower):
{ "require": { "bower-asset/bootstrap": "dev-master" } }
使用私有的Bower
用Hacklone Private Bower来使用私有的Bower:
将私有Bower服务器的URL添加到composer.json的section中。插件会自动通过这个URL来查找你私有的Bower包。
例如:
{ "config": { "fxp-asset": { "private-bower-registries": { "<YourPrivateBowerRegistryServerName>": "https://<YourPrivateBowerRegistryServerURL>/packages" } } } }
使用VCS储存库
如果您的前端资源未发布到NPM或Bower库中,或者这是一个私有的包,你可以为它创建一个VCS资源库。这个储存库需要有一个版本打包文件,如NPM的package.json或Bower的bower.json。打包文件必须遵循Bower或NPM的规范,版本号的标签需要遵循Semver 2.0规范。如果您的库不包含数字版本号,需要加入@dev标签,或直接使用开发分支dev-master。
例如:
{ "config": { "fxp-asset": { "repositories": [ { "type": "bower-vcs", "url": "https://github.com/vendor/exemple-asset-name.git" } ] } } }
可用的源
Drivers | NPM | Bower |
auto | npm-vcs | bower-vcs |
Git | npm-git | bower-git |
GitHub | npm-github | bower-github |
Git Bitbucket | npm-git-bitbucket | bower-git-bitbucket |
Mercurial | npm-hg | bower-hg |
Mercurial Bitbucket | npm-hg-bitbucket | bower-hg-bitbucket |
SVN | npm-svn | bower-svn |
Perforce | npm-perforce | bower-perforce |
重写VCS库配置
如果您必须使用一个不在NPM或Bower上注册的库,则必须在VCS库的配置中指定一个前缀。
例如:
{ "config": { "fxp-asset": { "repositories": [ { "type": "bower-vcs", "url": "https://github.com/vendor/exemple-asset-name.git", "name": "bower-asset/exemple-asset-name" } ] } } }
也可以使用Composer的标准格式来命名您的VCS库:
{ "config": { "fxp-asset": { "repositories": { "bower-asset/exemple-asset-name": { "type": "bower-vcs", "url": "https://github.com/vendor/exemple-asset-name.git" } } } } }
使用同一个依赖的多个版本
如果需要使用同一前端资源的多个版本,只需在包名称后添加一个版本号,并以"-"隔开即可。
例如:
{ "require": { "bower-asset/jquery": "1.11.*", "bower-asset/jquery-2.0.x": "2.0.x", "bower-asset/jquery-2.1.0": "2.1.0" } }
这些依赖项将存到以下目录中:
vendor/bower-asset/jquery for 1.11.*
vendor/bower-asset/jquery-2.0.x for 2.0.x
vendor/bower-asset/jquery-2.1.0 for 2.1.0
Composer包依赖的所有资源,在引入前都会根据版本号和分支进行自动过滤。不符合匹配条件的版本将会被忽略,也不会被下载。过滤条件包括精确版本号、范围号、通配符、比较运算符。
例如:
{ "minimum-stability": "dev", "require": { "npm-asset/example-asset1": ">=1.0@stable", "npm-asset/example-asset2": ">=2.3@RC", "npm-asset/example-asset3": ">=1.3@beta", "npm-asset/example-asset4": "~0.9@alpha", "npm-asset/example-asset4": "2.1.*", } }
如果其中一个资源依赖于另一个资源,并且考虑到上述优化不能与子依赖项一起执行,则可以将这个依赖直接写到composer的根配置中。
安装时禁用过滤器
默认情况下,插件会筛选并导入依赖的包,除非定义的包已经安装过了。然而如果该依赖使用的版本低于安装的版本,Composer有可能抛出一个“can not find a compatible version”的异常(译者注:未找到兼容的版本)。这时您可能需要在配置中掉过滤器:
{ "config": { "fxp-asset": { "optimize-with-installed-packages": false } } }
修改/禁用 跳过版本号模式
默认情况下,插件会跳过中间的修复版本,但这个模式可以修改或禁用。
修改:
{ "config": { "fxp-asset": { "pattern-skip-version": "(-build)" } } }
禁用:
{ "config": { "fxp-asset": { "pattern-skip-version": false } } }
禁用过滤器连接选项
{ "config": { "fxp-asset": { "optimize-with-conjunctive": false } } }
注意:仅当启用了已安装包的优化时才使用此选项。
自定义前端资源安装目录
全部插件默认会安装到vendors/{asset-type}-asset目录下,每个包会用自己的名字来作为文件夹的名称。但是你可以在composer.json里修改资源文件的路径:
{ "config": { "fxp-asset": { "installer-paths": { "npm-asset-library": "web/assets/vendor", "bower-asset-library": "web/assets/vendor" } } } }
修改或禁用Bower忽略的文件
在Bower中标记了“忽略” 的所有文件将不会被安装,并且将在每个软件包安装后被删除。当然,这可以禁用或替换。
禁用:
{ "config": { "fxp-asset": { "ignore-files": { "bower-asset/example-asset1": false } } } }
替换:
{ "config": { "fxp-asset": { "ignore-files": { "bower-asset/example-asset1": [ ".*", "*.md", "test" ] } } } }
手动删除NPM的忽略文件
{ "config": { "fxp-asset": { "ignore-files": { "npm-asset/example-asset1": [ ".*", "*.md", "test" ] } } } }
使用NPM scopes
NPM可以使用scopes路径(@ <vendor>/<dependency-name>)来管理包,但
Composer已经有vendors的命名空间了,并且这个插件会在命名空间下创建包的虚拟路径。而且包名的“@”字段也不是由Composer来设置的。因此把NPM的@ <vendor>/ 转换为 <vendor>-。
通过Composer脚本来管理忽略的文件
如果需要清理一个不是NPM/Bower的前端资源包,可以这么用:
{ "scripts": { "post-package-install": [ "Fxp\\Composer\\AssetPlugin\\Composer\\ScriptHandler::deleteIgnoredFiles" ], "post-package-update": [ "Fxp\\Composer\\AssetPlugin\\Composer\\ScriptHandler::deleteIgnoredFiles" ] }, "config": { "fxp-asset": { "ignore-files": { "acme/other-asset": [ ".*", "*.md", "test" ] } } } }
覆盖Bower的main文件
bower.json允许包在运行或构建后定义入口文件。一些Bower插件像main-bower-files,wiredep和asset-builder可以通过配置文件覆盖包的main文件。
{ "config": { "fxp-asset": { "main-files": { "acme/other-asset": [ "other-asset.js" ] } } } }
禁用资源库搜索
{ "config": { "fxp-asset": { "registry-options": { "npm-searchable": false, "bower-searchable": false } } } }
配置VCS Github
使用本机Git来替代Github,默认为false:
{ "config": { "fxp-asset": { "vcs-driver-options": { "github-no-api": true }, "pattern-skip-version": "(-build|-patch)" } } }
也可以设置为true,但个别库用正则表达式进行排除:
{ "config": { "fxp-asset": { "vcs-driver-options": { "github-no-api": { "default": true, "packages": { "bower-asset/example-asset1": false } } } } } }
解决资源的依赖冲突
Bower 自带了两个版本间的冲突处理方案,而NPM配置同个依赖的若干版本时,只有其中一个版本生效。(升级依赖包时请留意新版本的兼容性。)
例如:
{ "name": "foo/bar", "require": { "bower-asset/jquery": "^2.2.0" } "name": "bar/baz", "require": { "bower-asset/jquery": "2.0.*" } "name": "root/package", "require": { "foo/bar": "^1.0.0", "bar/baz": "^1.0.0" } "config": { "fxp-asset": { "resolutions": { "bower-asset/jquery": "^3.0.0" } } } }
按照上面这样配置,所有用到jquery的地方将会使用3.0.0版本。
为所有项目定义配置
你可以在每个项目的composer.json文件中定义配置,也可以把配置写到全局的Composer配置文件中来进行全局配置。注意:无法使用Composer的global命令,因为Composer不支持自定义选项。但是你可以把配置写到全局的composer.json和config.json文件中。
在环境变量中定义配置
可以直接把每个配置(config.fxp-asset.*)定义到PHP的环境变量中。所有变量都必须是大写的并且以 FXP_ASSET__ 开头,并且连词符 - 必须替换成下划线 _ 。允许的数据类型包括:
字符串
布尔型
整型
JSON数组或对象
例如可以被 FXP_ASSET__PATTERN_SKIP_VERSION="(-build)" 环境变量覆盖:
"config": { "fxp-asset": { "pattern-skip-version": "(-patch)" } } }
可由 FXP_ASSET__VCS_DRIVER_OPTIONS = "{" github-no-api ": true}" 的环境变量重写:
{ "config": { "fxp-asset": { "vcs-driver-options": { "github-no-api": true } } } }
配置的优先级
FXP_ASSET__开头的环境变量
项目的composer.json文件
全局的config.json文件
全局的composer.json文件
项目composer.json文件的 extra.asset-*配置。
禁用插件
如果有多个PHP项目,其中一些不需要使用这个插件,可以使用config.fxp-asset.enabled配置来启用或禁用。比如需要全局禁用插件(所有项目),而仅在其中一个项目启用,可以这么写:
全局composer.json文件:
{ "config": { "fxp-asset": { "enabled": false } } }
项目composer.json文件:
{ "config": { "fxp-asset": { "enabled": true } } }
注意: 如果全局禁用该插件,并在其中一个项目启用,则会抛出一个“the asset dependencies does not exist”的异常(译者注:找不到该插件)。
FAQs
(译者注:有些问题上述文档已经说明清楚了,这里不再重复翻译)
这个插件是如何工作的?
这个插件使用VCS储存库来添加每个前端资源。为了检索需要的库,这个插件会针对NPM和Bower创建一个和Packagist差不多的源,甚至允许手动添加VCS库。
一旦选择了VCS库,Composer会下载NPM或Bpwer包里主分支的信息并进行转换,以及其他分支的列表和tags(标签)。这样就能直接用composer.json里模拟出NPM的package.json和Bower的bower.json的功能。请注意,这些前端资源的都是在被Composer用到的时候才加载的。
当插件搜索包时, 为什么Composer会变慢?
Composer会检索本地包的所有分支和比标签。如果这些分支分成多,可能会使得过程变慢。但是这个插件有缓存系统,这样下次运行install/update命令时不用重新发出检索请求,会快很多。Composer自己也有提高获取远程文件性能的修改,参见composer/composer#3282。
为什么要从同个包的多个版本中检索安装信息?
安装时需要验证满足约束条配件的版本。版本约束越灵活,需要检索并验证的版本信息越多,版本约束越详细,检索越少。
Composer抛出一个“the version does not exist”的意外
如果该版本是存在却抛出“版本不存在”的意外,有可能是新的软件版本比安装的软件版本更低。有三种解决方案:
删除vendor下的目录,再重新运行composer update(推荐使用)
禁用导入筛选器(上述文档有提到如何配置)
在项目的根composer.json处增加依赖:添加该插件未被找到的那个版本号,把配置中config.fxp-asset.optimize-with-conjunctive修改为false,运行update;然后删除composer.json中的依赖项和config.fxp-asset.optimize-with-conjunctive配置,再运行composer update(译者注:很繁琐,效果同1,不推荐使用)
如何修改PHP内存限制?
请参阅Composer官方文档:Memory limits errors。
为什么需要用到Github的Token?
匿名访问时,Github对API进行限制(60次/小时)。你必须用token来提高限制(5000次/小时)。用Node.js和NPM也会遇到一样的问题。请参阅:Github Personal API Tokens
如何把GitHub token写到配置中?
参见Composer官方文档:API rate limit and OAuth tokens
关于
这个插件由François Pluchino发起。MIT许可。
本文未经许可禁止转载,如需转载请联系 JAY@oonne.com