Closed creocoder closed 10 years ago
@SDKiller that's all fine if all these bundles are yours but if these are all from different vendors you can't really force them to use same keys for same libraries.
Why not if we can override any bundle configuration in config? We don't force vendors - we force bundle config.
https://github.com/yiisoft/yii2/blob/master/docs/guide/structure-assets.md#overriding-asset-bundles
Well, that's manual editing that we're trying to avoid as much as possible.
one suggestion.
you can compare hash for that asset file to check duplicate. In that case you might need to process extra code for it which can be time taking too.
@samdark I'm not clear how you claim the issue about asset distribution is solved. If both widget A and widget B depend on the same 3rd party lib C. How do you propose to solve the problem?
There's certain overhead of declaring asset bundles.
I don't think this is an issue. It's more like the effort you have to take.
There's no central place one can review/edit all asset bundles.
This can be solved with an asset command.
@qiangxue
@samdark How to override asset bundle for doT
for example? Realize we have 3 different asset bundles for it. Which one override?
that's manual editing that we're trying to avoid as much as possible
@samdark
Anyway you cannot awoid it 100%.
Even with composer-bower packages the problem of double inclusion will not be solved if one extension wants js on POS_READY
and another - on POS_LOAD
@creocoder you don't really need to override it if it's downloaded as bower package. You can adjust package config an it will get different version for all three bundles.
@samdark Sorry, but we have feature, by using which we can override any asset bundles. For example i can override JqueryAsset
and get jquery
from CDN. And i'll try ask again ;) Realize we have 2+ asset bundles of same library from different extensions and i want to use regular overriding feature to get it from CDN for example.
You have to override both then.
@samdark Ok, both. Now realize JqueryAsset
not part of backend framework. Yii 2 in our case. 90% of libraries requre jquery
. For example you use 10 extensions. To override JqueryAsset
you will need override 10 bundles. Do not you think that something wrong here?
Another example. What if one vendor will use lib.js
in his asset bundle and other lib.min.js
. We will be faced with double include, etc. We need reliable solution. Or are you willing to hope maybe? How users can trust Yii knowing that it use not reliable solutions? Please, think of it in first.
@creocoder jquery bundle is part of Yii and there's no other library that is that popular.
The issue with minified script is indeed valid.
I don't think the same 3rd party lib should have different asset bundle classes in different widgets.
Perhaps we can introduce some special dependency declaration. For example,
class MyAssetBundle extends AssetBundle
{
public $depends = [
// depends on a bower package where package1 is the unique package name
'bower:package1',
// depends on my own asset bundle
'path\to\MyOwnBundle',
];
}
Because the name bower:package1
is globally unique, it can be used in different widgets by different vendors.
This is just some wild thinking. There are still technical details to be worked out.
@qiangxue But bower package itself does not contain any asset bundles. How it help? Also there is no possibility to autodetect which files should be included in case of bower package. For example if you'll look into selectize.js
, you will see that there is js/selectize.js
which requre sifter
and microplugin
and js/standalone/selectize.js
. After installing this package via bower you'll have both. Also this is new case similar to minified VS not minified files. How you can garantee that vendor A will use standalone selectize.js
verison in his SelectizeAsset
and vendor B will not use selectize.js
with sifter
and microplugin
. When i open this issue mine investigations show that there is no reliable solutions. This is why i suggest simple, non-automated solution. And only this can be 100% reliable.
Some further ideas. Unlike regular asset bundles which use their class names as global IDs, the bundle bower:package1
uses the bower package name as the global ID. Like regular asset bundles, you can specify js
, css
for such bundles. You can also configure it via AssetManager::bundles
. For example,
class MyAssetBundle extends AssetBundle
{
public $depends = [
// depends on a bower package where package1 is the unique package name
'bower:package1' => [
'js' => [...],
'css' => [...],
],
// depends on my own asset bundle
'path\to\MyOwnBundle',
];
}
So you can pick up the needed js/css files as you want for your widget. If two widgets are using the same bundle, Yii can automatically merge them or you can configure it via AssetManager::bundles
(this is similar to what you would do without using asset bundles).
@creocoder I had exactly the same problem as you described. In fact we may think about distinguishing between standard, minified and bower as a AssetBundle "state", but let's focus on standard vs. bower first.
@qiangxue
What do you think about the following approach, it's only two more properties for the AssetBundle class.
IMHO the only thing we need to know is, is where is the bower.json
for this AssetBundle and which files are NOT available from bower.
So $js
are the script files which are generated from the bower packages specified in $bowerJson
- they are exchangeable! Files from $jsCustom
are customizations for the current package.
Now I can stil use the standard way of including assets with Yii 2.
But it'll be also possible to collect the bower information from all required AssetBundles (including dependencies) and then install these with bower
, bowerphp
and throw them into grunt or whatever you like.
Specifying just the path to bower.json
would make sure you have only one place where you have to edit your client-script dependencies.
class SirTrevorAsset extends AssetBundle
{
public $language;
public $sourcePath = '@vendor/drmabuse/yii2-sir-trevor-js/assets';
// files generated by the developer
public $css = [
"grunt/sir-trevor-js.css",
];
// files generated by the developer
public $js = [
"grunt/sir-trevor.js",
"grunt/underscore.js",
"grunt/eventable.js",
"grunt/locales/de.js",
"grunt/locales/es.js",
];
// specify path to bower.json, so we can grab the above files from there
public $bowerJson = "bower.json";
// always to be included, not available via bower
public $jsCustom = [
"blocks/CodeBlock.js",
"blocks/ColumnsBlock.js",
"blocks/Gallery.js",
"blocks/ImageCaption.js"
];
// these assets should also define their bower.json location
public $depends = [
'yii\web\JqueryAsset',
'yii\web\YiiAsset'
];
}
This discussion may last forever.
2 major points to keep in mind:
1) 100% automation is impossible 2) where it is possible - automation is useful
Summary: 1) nevertheless of modern techniques there should be enough 'manual' tools to adjust everything. IMO current assets bundles implementation is lacking flexibility; 2) in simple cases current assets bundles implementation is enough.
Some options could be passed to assets in runtime - currently it is not available.
If we register assets 'per-view' - why we can configure them only application-wide in config file?
Why not to pass some options - for example to load only particular files in this view - anyway the whole folder with js files have been published already.
Etc...
Just found this project: https://github.com/francoispluchino/composer-asset-plugin
From the website:
The Composer Asset Plugin allows you to manage project assets (css, js, etc.) in your composer.json without installing NPM or Bower.
This plugin works by transposing package information from NPM or Bower to a compatible version for Composer. This allows you to manage asset dependencies in a PHP based project very easily.
@schmunk42 thanks, we are already aware of it :) I am currently waiting for composer to merge a pull request it depends on.
Must have overlooked it :)
btw: Did you talk to @Seldaek about this?
The PR from https://github.com/composer/composer/pull/3082 looks neat ... and ... maybe he just doesn't know that here are so many people waiting for this and would revere him for merging it. :bow: :pray:
@schmunk42 yes, see this comment: https://github.com/composer/composer/pull/3082#issuecomment-49978235
Closed to move discussion to #4454 and #4855.
For example we have
foo\yii2-gallery-widget
. It require js libs:We have 2 Asset Bundles:
foo\gallery\JqueryGalleryAsset
andfoo\gallery\DotAsset
.Second extension we have
bar\yii2-file-uploader-widget
. It requre js libs:We have 2 Asset Bundles:
bar\uploader\JqueryFileUploaderAsset
andbar\uploader\DotAsset
.Using this widgets in one page will lead to critical js error, because
doT
will be linked 2 times. Trying to use asset converter will lead to critical js error, because it will usedoT
2 times. Trying to overridedoT
bundle absolutte FAIL, because we can override 1 bundle, while there we have 2.Because all of it troubles current Yii 2 situation is: NOT use Yii 2 extensions at all, because it just DUNGEROUS. In middle/big application you will be faced with all described troubles.
Also as you see this is simple example where trouble come. In real world extensions which requre 2 - 3 js libraries possibility of such bundle collisions is 99%.
@qiangxue It is not yet too late (there is no release yet) to totally rethink asset bundles approach. Because if it will go to release prepare to situation when yii 2 extensions will not work together and no one will use them.