简体   繁体   English

Symfony 4,包括来自供应商目录的资产

[英]Symfony 4, include assets from vendor directory

I would like to load vendor assets, downloaded with composer inside vendor directory, from my twig template.我想从我的树枝模板加载供应商资产,在供应商目录中使用 composer 下载。

Using a relative path is one solution (in this example I'm going to include bootstrap css, but the same problem is for any other libs required from composer, as jQuery, jQueryUI etc. )使用相对路径是一种解决方案(在本例中,我将包含引导 css,但对于 Composer 所需的任何其他库,如 jQuery、jQueryUI 等,同样的问题也是如此)

<link rel="stylesheet" href="{{ asset('../vendor/twbs/bootstrap/dist/css/bootstrap.min.css') }}" >

Symfony docs suggest to use asset:install in order to generate a symlink from vendor directory to public, but I was unable to understand how it works. Symfony 文档建议使用资产:安装来生成从供应商目录到公共的符号链接,但我无法理解它是如何工作的。 assets:install -h wasn't so clear to let me understand how to link a specific vendor path to the public directory. assets:install -h 不太清楚,让我了解如何将特定供应商路径链接到公共目录。

Creating a simlink with创建一个simlink

ln -s /path/of/vendor/lib /path/public/dir

works fine but, symlinks created will be deleted every time I look for an update with composer.工作正常,但是每次我寻找 Composer 的更新时,创建的符号链接都会被删除。

Any idea about "a best practice" to include assets from vendor directory?关于包含供应商目录中资产的“最佳实践”有什么想法吗?

Thank you谢谢

Before, Assets used to compile all your selected files into one with the current version in the file name, but it changes from Symfony 4 之前,Assets用于将所有选定的文件编译成文件名中包含当前版本的文件,但它从Symfony 4更改

According to those documentation 根据那些文件

https://symfony.com/doc/current/frontend.html https://symfony.com/doc/current/frontend.html

https://symfony.com/doc/current/frontend/encore/bootstrap.html https://symfony.com/doc/current/frontend/encore/bootstrap.html

You should use Webpack Encore and be able to use the new system of Asset 您应该使用Webpack Encore并能够使用新的Asset系统

In terms of 'Best Practice', I generally use npm with gulp or something to that effect, which generates distribution css and js files that are output to a designated file in public/ .在“最佳实践”方面,我通常将npmgulp或类似的东西一起使用,它生成分发 css 和 js 文件,这些文件输出到public/的指定文件。

Here's an example from a recent project package.json file这是最近项目package.json文件中的一个示例

{
  "devDependencies": {
    "bootstrap": "^4.1.3",
    "gulp": "^4.0.0",
    "gulp-concat": "^2.6.1",
    "gulp-sass": "^3.1.0"
  },
  "scripts": {
    "compile:styles": "gulp styles"
  }
}

Rather run npm install --save-dev bootstrap gulp gulp-concat gulp-sass to get the latest versions etc.而是运行npm install --save-dev bootstrap gulp gulp-concat gulp-sass以获取最新版本等。

And you'll need this gulpfile.js too你也需要这个gulpfile.js


var gulp = require('gulp');
var concat = require('gulp-concat');
var sass = require('gulp-sass');

gulp.task('styles', function(){
    return gulp
        .src([
            'app/Resources/sass/main.scss',
            ])
        .pipe(sass({outputStyle:'compressed', includePaths: ['node_modules']}).on('error', sass.logError))
        .pipe(concat('styles.min.css'))
        .pipe(gulp.dest('public/css'));
    });

Once setup, you can run npm run compile:styles from the console and the app/Resources/sass/main.scss SASS file will be pre-processed, minified and output to public/css/styles.min.css .设置完成后,您可以从控制台运行npm run compile:styles并且app/Resources/sass/main.scss SASS 文件将被预处理、缩小并输出到public/css/styles.min.css

Note that the gulp file includes the node_modules folder so you can import bootstrap inside the main.scss file, eg请注意,gulp 文件包含 node_modules 文件夹,因此您可以在main.scss文件中导入引导程序,例如

$primary: #55a367;

@import 'bootstrap/scss/bootstrap';

From a twig template:从树枝模板:

<link rel="stylesheet" type="text/css" href="{{ asset('css/styles.min.css') }}">

I generally commit both the main.scss and styles.min.css我通常同时提交main.scssstyles.min.css

The reason why you can't tell the assets:install to link and arbitrary vendor directory is that the command is designed to loop through the list of installed bundles and link a well-known directory ( Resources/public ) directory if it exists.您不能告诉assets:install链接和任意供应商目录的原因是该命令旨在遍历已安装包的列表并链接已知目录 ( Resources/public ) 目录(如果存在)。 It relies on both the short bundle name and the directory existing, so it can only work with symfony bundles, there's no support for other libraries like bootstrap or jquery.它依赖于短包名称和现有目录,因此它只能与 symfony 包一起使用,不支持其他库,如 bootstrap 或 jquery。 (Link to current command source ). (链接到当前命令源)。

The recommended way to handle frontend libraries nowadays is encore .现在处理前端库的推荐方法是encore

In a situation where that's not possible, you could use composer scripts .在不可能的情况下,您可以使用composer scripts I wouldn't call this "best practice", might end up being more trouble than it's worth but is an option you can consider.我不会称之为“最佳实践”,最终可能会比它的价值带来更多的麻烦,但这是您可以考虑的选择。

You would create a shell, php script or console command where you basically replicate the functionality of assets:install to link your library assets.您将创建一个 shell、php 脚本或控制台命令,在其中基本上复制assets:install的功能以链接您的库资产。 You will still need to manually update the script when you install a new library, but you can configure it to automatically run after installing or updating packages.安装新库时,您仍需要手动更新脚本,但您可以将其配置为在安装或更新软件包后自动运行。

Copy this simple sample bash script into you project directory, name it install_vendors.sh :将这个简单的示例 bash 脚本复制到您的项目目录中,将其命名为install_vendors.sh

#!/bin/bash

BASE_PATH=`pwd`
PUBLIC="public"

if [ "$1" != "" ]; then
    PUBLIC=$1
fi;

PUBLIC=${BASE_PATH}/${PUBLIC}/vendor
VENDOR=${BASE_PATH}/vendor

rm $PUBLIC -rf
mkdir $PUBLIC

function link_asset
{
    SOURCE_DIR=${VENDOR}/$1
    TARGET_DIR=${PUBLIC}/$2
    ln -s $SOURCE_DIR $TARGET_DIR
}

link_asset twbs/bootstrap/dist bootstrap

Add it to the scripts section of composer.json and the auto-scripts :将它添加到composer.jsonauto-scriptsscripts部分:

"scripts": {
    "vendors:install": "bash install_vendors.sh",
    "auto-scripts": {
        "cache:clear": "symfony-cmd",
        "assets:install %PUBLIC_DIR%": "symfony-cmd"
        "@vendors:install"
    },
    // ...
}

You can also execute it at any time with composer run vendors:install .您也可以随时使用composer run vendors:install执行它。

Then include them in your twig files: {{ asset('vendor/bootstrap/css/bootstrap.min.css') }} .然后将它们包含在你的树枝文件中: {{ asset('vendor/bootstrap/css/bootstrap.min.css') }}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM