-
-
Notifications
You must be signed in to change notification settings - Fork 201
How are static assets handled? #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Yes, you can't currently use |
@jrobeson actually you can. Symfony supports having several asset packages with different versioning strategies. so you could have 1 package using the manifest strategy, and another one using hashed-asset-bundle (or just use hashed-asset-bundle for all of them, by disabling the path-based versioning of encore) |
Oh packages! I had forgotten that they exist. I guess that's one way to go about it. |
I wonder if other folks are gonna use different versioning schemes for these static assets vs webpack or just me. If so, it might be good to see a recommendation somewhere. |
+1 for a mechanism to add static assets such as images into the manifest.json. Currently I have a gulp file generates a manifest that deals with hashing my css, js and images, if I were to use encore I'd like to use the same versioning strategy for all my static assets js and css. |
+1 for there being a way for processing these through webpack. Actually, it's pretty standard already - if you (for example) require a image or font from CSS (or even JS), it will be moved into the |
The main problem for me here is that templates (Twig or else) contain references to assets (images) that will never be handled by webpack unless we do it explicitely. Solutions tried were:
So far I havent found anything else. If somebody has ideas pls share :) |
@davidmpaz Is there now any working solution? I am using Encore now together with CopyWebpackPlugin and ImageMinPlugin and it works -> but with one problem. I am not able to put copied images to manifest.json. If it can be done now, I would really appreciate an example. Thanks! |
There's no working solution yet - but it's on my "todo" list. As a workaround, you should be able to add a require call in any # app.js
require('./images/foo.png'); This should cause Let me know if that works. I'd like a more official way to do this, but really, this is what that official solution will be doing behind the scenes. Cheers! |
It works, thanks! |
@skaryys your scenario is the same as mine. For me is not good also to require all images since it is too much and at that point that is a build/deploy task, I did not want it in application code. did you read about plugin execution order? This thread gave me the hints needed. Basically My working solution with PR applied, not using it yet though :)
Hints for the future: let me know if this helps. |
@davidmpaz Ok, i was able to generate Thanks anyway for the unshift solution and hints ;) |
I am glad it helped ;).... Copy plugin has some functionality for naming files with hashes and so on but you need to try. I had problem with that part, somehow the copy plugin was messing around when I passed some globs like: I tried: I did not dive into it since in my case those images copied will rarely change, so it can just be copied as is. I don't need hashing them. With having it in manifest to integrate with framework later on was good enough. |
@davidmpaz I was succesfully able to copy assets with hash but the manifest then looked like this:
So instead of dealing with the ManifestPlugin, I wrote little script which generates javascript file which looks like this:
For me and my project, it works. I am quite unskilled with NodeJS and creating packages, but if it will be useful for someone, I will be glad ;) |
For those of you who struggle with what is mentioned above. 1. Require your image in your js fileassets/js/app.js require('./images/foo.png'); Your image will be generated in your # We are in 'public/images'
$ tree
├── images
│ ├── foo.fe373bcc.png
├── main
│ └── app.js
└── manifest.json 2. Compile assets
Among other things, your manifest.json has been generated.
3. Don't forget to use
|
@weaverryan So I can not organize images on subfolders. Why first level folder |
@bravik By default all images are put into webpack-encore/lib/config-generator.js Lines 143 to 156 in 00e4051
If you want to keep your subfolders you'll have to change the naming strategy to include the Encore.configureFilenames({
images: '[path][name].[hash:8].[ext]'
}); |
All this is really confusing ... To enable the versioning and have the manifest file working I followed this : https://symfony.com/doc/current/frontend/encore/versioning.html The only difference is that I'm working with the dev environment so I needed to change
in the default webpack.config.js file. Also to make it work I needed to add this key under assets: in framework.yaml
it's really ugly but the asset fonction don't put the /public in the url |
Hi @kaizokou,
Which version of Symfony are you using? Starting from Symfony 4 the If you use an older version of Symfony you should use |
@Lyrkan I'm using SF4 latest version and I don't have web directory. It's a new project without much things in it. Maybe I'm missing something in the config. The asset twig fonction was working well before enabling the versioning. Maybe this is because I'm using Mamp and the web server root is on / and not on /public. I do have a .htaccess that redirect to /public. I don't know. |
@kaizokou Indeed, if your Symfony app is in a subdirectory (which is kind of the same thing) you'll have to do that kind of adjustment (you should be able to tweak MAMP to avoid it though, for instance by creating vhosts). Did you try using By the way (and not really related to Encore), if you generate URLs from the console you'll also need to set |
At the end I deactivated completely the versioning because I don't need it for the images. Originally I put them under That said, it bothers me to have my asset in two places : The Symfony Best Practices pdf is quite poor about the assets. The chapter 10 is only 1 page and doesn't say anything except that Encore is the recommended asset manager. At the end I'm really confused about how to handle my assets. I'll be so grateful if someone can clear this out. btw thanks @Lyrkan for your answer. |
Hi |
Hey @etshy, You could probably achieve that using For instance: const imagesCtx = require.context('./images', false, /\.(png|jpg|jpeg|gif|ico|svg|webp)$/);
imagesCtx.keys().forEach(imagesCtx); If you also want to include subfolders, change the second parameter of the A cleaner solution for that use case would probably be to use the |
thanks, seems it's working. Thanks anyways for that solution, I'm pretty new with webpack and npm (I just used it to get some library before) edit: hmm I have a little problem about output folder.
and the piece of codes you put earlier. |
@etshy That's because of how Before calling Now let's say you use Then, if you add If you want to remove the In case that helps, I did some tests a while ago that show how it behaves using different parameters: #103 (comment) |
hmm Like I said I'm very new to this so I'm a bit lost. //require all images
const imagesCtx = require.context('../img', true, /\.(png|jpg|jpeg|gif|ico|svg|webp)$/);
//dunno what this line is doing exactly
imagesCtx.keys().forEach(imagesCtx); Here is my webpack.config.js file if that could help you to guide me. // webpack.config.js
var Encore = require('@symfony/webpack-encore');
Encore
// the project directory where all compiled assets will be stored
.setOutputPath('public/build/')
// the public path used by the web server to access the previous directory
.setPublicPath('/build')
// will create public/build/main.js and public/build/main.css
.addEntry('main', './assets/js/main.js')
.addEntry('reader', './assets/js/reader.js')
// allow sass/scss files to be processed
.enableSassLoader()
// allow legacy applications to use $/jQuery as a global variable
.autoProvidejQuery()
.enableSourceMaps(!Encore.isProduction())
// empty the outputPath dir before each build
.cleanupOutputBeforeBuild()
// show OS notifications when builds finish/fail
.enableBuildNotifications()
// create hashed filenames (e.g. app.abc123.css)
.enableVersioning()
.configureFilenames({
images: '[path][name].[hash:8].[ext]'
})
;
// export the final configuration
module.exports = Encore.getWebpackConfig(); |
The And as how to do it... that's not something that you can do by only using Encore methods (that's what I meant by "you'll have to do more changes directly in the generated Webpack conf"). You'd have to:
Do you really want to do that though? You shouldn't have to worry about the directories your images are put into. Especially since only changing that loader's context to |
hm yeah that's too much just to have the folder hierarchy I want. I thought it was weird to have What's the recommended ways to handle images so ? Because, I guess imags used in html/twig or whatever (not detected during the encore exportation) have to be manually get by url in the images folder, right ? |
// main.js
// webpack.config.js
|
There is now a |
The documentation is update : https://symfony.com/doc/current/frontend/encore/copy-files.html |
A question by @jrobeson on Symfony Slack:
The text was updated successfully, but these errors were encountered: