webpack-encore
webpack-encore copied to clipboard
versioned icons not found in the manifest.json in PWA configuration using .configureManifestPlugin
Hi I have active the .enableVersioning() option in my webpack.config.js file and I also configured the seed key/values for my PWA using .configureManifestPlugin like this:
var Encore = require('@symfony/webpack-encore');
var ManifestPlugin = require('webpack-manifest-plugin');
var OfflinePlugin = require('offline-plugin');
const CopyPlugin = require('copy-webpack-plugin');
if (!Encore.isRuntimeEnvironmentConfigured()) {
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}
Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
// only needed for CDN's or sub-directory deploy
//.setManifestKeyPrefix('build/')
.addEntry('app', './assets/js/app.js')
.addEntry('sw', './assets/js/serviceWorker.js')
.splitEntryChunks()
.disableSingleRuntimeChunk()
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
//ENABLING VERSIONING HERE
.enableVersioning(Encore.isProduction())
.configureBabelPresetEnv((config) => {
config.useBuiltIns = 'usage';
config.corejs = 3;
})
.configureBabel(function(babelConfig){
babelConfig.plugins.push("@babel/plugin-proposal-class-properties");
})
.enableSassLoader()
.autoProvidejQuery()
.enableReactPreset()
//COPYING THE HASHED ICONS TO THE PUBLIC FOLDER I REALLY DON'T KNOW IF THERE IS ANOTHER WAY TO DO THIS
.copyFiles(
{
from: './assets/img/icons',
to: 'images/icons/[path][name].[hash:8].[ext]',
pattern: /\.(png|jpg|jpeg)$/
}
)
//ADDING PWD KEYS TO MANIFEST.JSON
.configureManifestPlugin( (options) =>{
options.seed = {
"name": "bla bla bla",
"short_name": "bla",
"display": "standalone",
"start_url": ".",
"background_color": "#fff",
"theme_color": "#1c97b0",
"orientation": "portrait-primary",
"icons": [
{
"src": "/build/images/icons/icon-512x512.png", //IS THIS THE CORRECT URL???????
"type": "image/png",
"sizes": "512x512"
},
{
"src": "/build/images/icons/icon-192x192.png", //IS THIS THE CORRECT URL???????
"type": "image/png",
"sizes": "192x192"
}
]
}
})
var config = Encore.getWebpackConfig();
config.plugins.push(new OfflinePlugin({
"strategy": "changed",
"responseStrategy": "cache-first",
"publicPath": "/build/",
"caches": {
"main": [
'*.json',
'*.css',
'*.js',
'img/*'
]
},
"ServiceWorker": {
"events": !Encore.isProduction(),
"entry": "./assets/js/serviceWorker.js",
"cacheName": "Reysis",
"navigateFallbackURL": '/',
"minify": !Encore.isProduction(),
"output": "./../sw.js",
"scope": "/"
},
"AppCache": null
}));
;
module.exports = Encore.getWebpackConfig();
my final manifest.json is this
{
"name": "bla bla bla",
"short_name": "bla",
"display": "standalone",
"start_url": ".",
"background_color": "#fff",
"theme_color": "#1c97b0",
"orientation": "portrait-primary",
"icons": [
{
"src": "/build/images/icons/icon-512x512.png",
"type": "image/png",
"sizes": "512x512"
},
{
"src": "/build/images/icons/icon-192x192.png",
"type": "image/png",
"sizes": "192x192"
}
],
"build/app.css": "/build/app.css",
"build/app.js": "/build/app.js",
"build/sw.js": "/build/sw.js",
"build/vendors~app.css": "/build/vendors~app.css",
"build/vendors~app.js": "/build/vendors~app.js",
"build/vendors~app~sw.js": "/build/vendors~app~sw.js",
"build/images/icons/icon-192x192.png": "/build/images/icons/icon-192x192.3d157c59.png",
"build/images/icons/icon-512x512.png": "/build/images/icons/icon-512x512.b6511709.png"
}
but I got a not found icon in the browser when trying to load icons from the manifest,... My question is: Is this the correct way to add my PWA settings to the manifest.json? or ... Is it necessary to add the hash to the icons inside the .configManifestPlugin in the seed option? I am a little new using Encore, maybe I am doing something wrong, sorry for the inconvenience and thanks in advance...
I'm using Reactjs for the Frontend
Hi,
You are confusing the manifest.json
from Webpack Manifest Plugin and the manifest.json
for PWA.
They don't have the same goals and can not be "merged" in a single manifest.json
file.
As a workaround, you can configure the manifest.json
filename used by Webpack:
Encore.
.configureManifestPlugin(options => {
options.fileName = 'webpack-manifest.json';
})
If you are using Symfony with the Symfony Webpack Encore Bundle, you will have to configure framework.assets.json_manifest_path
to target the new webpack-manifest.json
file.
The URL you use in your manifest.json
file is not correct, you should not use build/images/icons/icon-192x192.png
but /build/images/icons/icon-192x192.3d157c59.png
.
But the hash 3d157c59
is not predictable, so you can't use a raw value here.
You can disable the hash for images by using Encore.configureFilenames()
:
Encore
.configureFilenames({
images: 'images/[name].[ext]'
})
I'm not a big fan, a better solution would be to generate your PWA's manifest.json
after Webpack has built entries (or resolved entries names). This way you will be able to use something like this:
Encore.addPlugin(MyPlugin([
{
name: 'manifest.json',
content(webpackEntries) {
const json = {
// ...
'icons': [
{
'src': webpackEntries['build/images/icons/icon-512x512.png'], // should resolve to /build/images/icons/icon-512x512.b6511709.png
'type': 'image/png',
'sizes': '512x512',
},
{
'src': webpackEntries['build/images/icons/icon-192x192.png'], // should resolve to /build/images/icons/icon-192x192.3d157c59.png
'type': 'image/png',
'sizes': '192x192',
},
],
};
return JSON.stringify(json, null, 2);
},
},
]);
I don't think such a plugin exists, but you can create your own I guess.
@Kocal Thanks for the answer it help me a lot to understand the differences between the both manifest and I solve the first part of the problem.... the second part well... is there some place where I can read more about how to solve it?? also I was inspecting using the dev tools and I saw that in the Sources tab, the images folder is not there... but if I check the public path it is beeing copied to that location due the .copyFile() function in the webpack.config.js file... is this normal?? could this be part of the problem?? Cheers!!
Ah! Sorry, I didn't see you used .copyFiles
!
Then you can use instead:
Encore
.copyFiles(
{
from: './assets/img/icons',
to: 'images/icons/[path][name].[ext]',
pattern: /\.(png|jpg|jpeg)$/
}
)
Project made with TypeScript, react.Js, React-native. Recycling day design
https://github.com/Rodrigo001-de/Projeto-Ecoleta-advanced
Other solution to copy manifest.json
PWA into build folder :
Encore
.addPlugin(new CopyWebpackPlugin({
patterns: [
{ from: './assets/icon_pwa', to: 'icon_pwa' },
{ from: './assets/manifest.json', to: path.resolve(__dirname, 'public/build', 'manifest.json') }
],
}))