symfony静态文件解决方案(未完待续)
目前,在symfony中与静态资源有关的目录有三个:/app /src /web
app
-- Resources
-- assets
-- css
-- js
--scss
src
-- AppBundle
-- CodeExplorerBundle
-- Resources
-- config
-- views
-- js
-- css
web
-- css
-- fonts
-- js
其中/web是document_root,所有对外访问的直接资源必须存放于此目录。
/src是存放各类Bundle(束),各个束下面有controller、service、data、Events、Test…,相当于一个独立的app,当然,根据symfony松耦合理念,束下面也有静态资源目录/Resources,存放js/css/images…,由于外部无法直接访问各个Bundle下面的静态资源,因此,symfony的解决方案是通过:
app/console assets:install web –symlink
命令建立由各bundle静态资源到web目录的软连接(unix),在windows下是通过copy一份到/web,执行命令以后,/web变成:
web
-- bundles
-- css
-- fonts
-- js
其中,bundles是存放/src及/vendor下各个bundle下的Resource/public资源的静态文件。
-- bundles
-- framework
-- css
-- images
-- sensiodistribution
-- webconfigurator
-- css
-- images
最有争议的是/app目录,根据最佳实践,一些可以通过合并、优化的静态资源,比如css/js/images建议存放在/app/Resources/assets下面。有关这个讨论可以查看这里。其中焦点在于,/app的资源不能通过assets:install建立软链接或拷贝存放于/web,那么为什么还建议公共资源存放于此?官方回答是这样:
Keep in mind that web/ is a public directory and that anything stored here will be publicly
accessible. For that reason, you should put your compiled web assets here, but not their
source files (e.g. SASS files).
http://symfony.com/doc/current/best_practices/web-assets.html
这里的资源不同于其它两个目录(/src /web),可以直接使用。这里存放的是源资源,即还没有编译的文件,如js/css/images/less/sass等,它们可以通过一定的工具调整尺寸、体积、合并的操作转换到/web/下面。
比如symfony提供了assetic进行asset管理,可以压缩、合并、打包静态资源,demo有一段:
{# uncomment the following lines to combine and minimize JavaScript assets with Assetic
{% javascripts filter="?jsqueeze" output="js/app.js"
"%kernel.root_dir%/Resources/assets/js/jquery-2.1.4.js"
"%kernel.root_dir%/Resources/assets/js/moment.min.js"
"%kernel.root_dir%/Resources/assets/js/bootstrap-3.3.4.js"
"%kernel.root_dir%/Resources/assets/js/highlight.pack.js"
"%kernel.root_dir%/Resources/assets/js/bootstrap-datetimepicker.min.js"
"%kernel.root_dir%/Resources/assets/js/main.js" %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}#}
它是对/app/Resources/assets下面的几个公共js进行合并打包,并输出一个文件:app.js。
如果不使用symfony提供的工具,也可以使用常见的node.js工具,比如gulp/webpack,它一样可以提供常见的静态资源处理。
以gulp为例,我们将待加工资源存放于/app/Resources下面:
-- Resources
-- assets
-- css
-- js
--scss
-- node_modules
-- .bin
-- acorn
-- ...
其中node_modules是node.js的包管理工具npm安装的各类js包,现在我们把assets、node_modules指定的资源转移到/web下面,建立gulpfile.js指令文件(需要一些简单的node.js知识):
var buildFolder = './',
destFolder = './../../web/js/',
gulp = require('gulp'),
fs = require('fs'),
rename = require('gulp-rename'),
concat = require("gulp-concat"),
header = require("gulp-header"),
minifyCss = require("gulp-minify-css"),
uglify = require("gulp-uglify");gulp.task('public', function () {
gulp.src([buildFolder + 'assets/js/*.min.js',
buildFolder + 'node_modules/cookie/index.js',
buildFolder + 'node_modules/seajs/dist/sea.js'])
.pipe(rename(function(path){
if (path.basename.indexOf('index') === 0)
path.basename = 'cookie';
}))
.pipe(gulp.dest(destFolder + 'public/'));
});
建立完毕执行:
gulp public
执行完毕,这些指定的公共js文件即转移到了/web下面:
web
-- bundles
-- framework
-- css
-- images
-- sensiodistribution
-- webconfigurator
-- css
-- images
-- css
-- fonts
-- js
-- public
-- bootstrap-3.3.4.min.js
-- cookie.js
-- …
那么,我们就可以在/web下面引用这些资源。当然gulp还可以进行些操作,比如压缩、合并等,处理速度比php 命令稍快。