You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
var Encore = require('@symfony/webpack-encore');
Encore
// directory where should all compiled assets will be stored
.setOutputPath('web/build/')
// what's the public path to this directory (relative to your project's document root dir)
.setPublicPath('/build')
// empty the outputPath dir before each build
.cleanupOutputBeforeBuild()
// will output as web/build/app.js
.addEntry('app', './assets/js/main.js')
// will output as web/build/global.css
.addStyleEntry('global', './assets/css/global.scss')
// allow sass/scss files to be processed
.enableSassLoader()
// allows legacy applications to use $/jQuery as a global variable
.autoProvidejQuery()
.enableSourceMaps(!Encore.isProduction())
// create hashed filenames (e.g. app.abc123.css)
// .enableVersioning()
;
var webpackConfig = Encore.getWebpackConfig();
webpackConfig.module.rules.push({
test: /\.vue$/,
loader: 'vue-loader'
});
webpackConfig.module.rules.push({
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
});
// export the final configuration
module.exports = webpackConfig;
main.js
import Vue from 'vue/dist/vue'
import App from './app.vue'
require('semantic-ui/dist/semantic.min.css')
Errors
GET http://localhost/build/fonts/icons.woff2
GET http://localhost/build/fonts/icons.woff
GET http://localhost/build/fonts/icons.ttf
@heitorvrb Ah, thanks for the extra info! If you're deployed under a subdirectory, that should be reflected in your setPublicPath:
// this is your *true* public path.setPublicPath('/mySymfonyApp/build')// this is now needed so that your manifest.json keys are still `build/foo.js`// i.e. you won't need to change anything in your Symfony appconfig.setManifestKeyPrefix('build')
You can see an example of this in the tests as well:
it('Deploying to a subdirectory is no problem',(done)=>{
Webpack must be aware of the true public path, because if you use "code splitting", then webpack itself will make AJAX requests for assets (so it needs to know the real path). That's why the config lives in webpack.config.js, instead of allowing your app (i.e. Symfony) to "fix" the subdirectory.
Let me know if that helps! I'll open an issue on the docs about this.
dayze, AchillesKal, EliuTimana, pjehan, sn0opr and 2 more
What if my web root changes depending to the environment I'm deploying to?
On my local development environment, the web root will be /my-nth-app/web/build
whereas on the production server, it will just be /build.
What would be the recommended way to make this dynamic, or at least, configurable?
I am just desperated that SF team opted for a JavaScript solution to handle the assets. Nothing works no more with this technology. And there is no way to maintain it without absorbing a whole lot knowledge about JavaScript. I just hate this "language". When it's not the sass-loader that falls down, you discover that it just can't handle multiple environments. I think I will end with totally uninstalling webpack and find a working PHP solution, that can be configured, fixed, and adapted if necessary to anyone's needs. Frustrated. Why don't you use a stable language, something defined, something that runs the same on any environment. Something that works like any other language. Or maybe it's time to stop working with SF, but it is so sad ...
@dmeziere you are still free to build your assets the way you want, and reference them with the asset() function in your Twig template. The Asset component has no requirement on webpack-encore.
Modern tooling regarding building frontend code is all written in JS. And we decided to recommend webpack (with this wrapper around its config to simplify it for the use cases we see). But it is not mandatory to use it with Symfony at all.
And regarding using a pure PHP solution, there is no PHP-based tooling implementing a module bundler for JS (JS developers build their tooling in the language they know: JS). And the Symfony core team has no interest into porting Webpack and its whole ecosystem to PHP (that would make no sense, and would require many full-time developers to catch up with the whole webpack community).
You can still do that yourselves if you want to use JS modules. And if you want to keep writing JS in the old way and only concatenate the files together in your final bundle, it is easy to implement that in any language (including a simple Bash command: cat assets/js/*.js > web/build/js/app.js)
So, I finally found the problem. It was an impact on fos_js_routing. But the frustration of loosing days on this point didn't help me to see things clearly. Finally the solution provided by @Lyrkan was the key as I also use aliases on my dev server, but not on my production server. But if you, falling on this ticket, are using fos_js_routing; be aware that the generated js/json file is not called anymore. It is integrated by webpack encore to the main JS file (what makes sense, after all). So you must make it "prod friendly" before calling yarn encore production. And you no longer need to dump the routes in your deployment script, this will be useless. Finally, I don't like the fact that I must compile and commit my production assets to my repo before a deployment, but it is way better than being forced to install node on the production server, downloading all the node_modules, etc.
I use sub directories for sites while in dev and it was a bit of a pain setting a publicPath. Especially when co-workers had different sub directory structures.
I wrote some code to automatically determine the public directory across all projects within the webpack config.
webpack.config.js
var Encore = require('@symfony/webpack-encore');
var publicPath = '/build';
if (!Encore.isProduction()) {
require('dotenv').config({
path: './.webpack.env',
});
if ('undefined' !== typeof process.env.ENCORE_PUBLIC_PATH) {
publicPath = process.env.ENCORE_PUBLIC_PATH;
} else {
const guessFromPaths = [
'/usr/local/var/www/htdocs',
'/usr/local/var/www',
process.env.HOME + '/Sites',
];
for (var i = 0; i < guessFromPaths.length; i++) {
var path = guessFromPaths[i];
if (0 === __dirname.indexOf(path)) {
path = __dirname.split(path);
publicPath = path[1] + '/public/build';
break;
}
}
}
}
Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
// public path used by the web server to access the output path
.setPublicPath(publicPath)
// only needed for CDN's or sub-directory deploy
.setManifestKeyPrefix('build/')
...
You will need to install dotenv from yarn for this to work.
In the above code we are just giving it an array of potential web root directories to look for. This is a list that a few different co-workers are using.
As soon as the loop find a value that matches the __dirname variable, it will take that value and append /public/build to the value.
e.g. if your build files are located in /usr/local/var/www/htdocs/clientXYZ/project123/public/build it will make the public path /clientXYZ/project123/public/build
We also have a .encore.env.dist where you can set a value for ENCORE_PUBLIC_PATH
@toklok Even without CI/CD I wouldn't recommend commiting them. Building them locally before a deployment, or even directly on the server (which is not really a good thing either) are probably better solutions.
.setPublicPath(Encore.isProduction() ? '.' : '/build/admin') - so css will contain font paths relative to css file
.setManifestKeyPrefix('build')
After module.exports = Encore.getWebpackConfig() add
if(Encore.isProduction()){module.exports.plugins[2].options.publicPath='bundles/w3desadmin/build/'// [2] is WebpackManifestPlugin position}
Now after yarn run build I have css with relative paths, and asset() function works fine. Unfortunately entrypoints.json have wrong paths, I cannot override it in similar way because AssetsWebpackPlugin calls webpackConfig.getRealPublicPath() directly.
Activity
weaverryan commentedon Jun 16, 2017
Hey @dayze!
Can you post your webpack.config.js file and also the code for any relevant other files (like main.js)?
dayze commentedon Jun 19, 2017
Hi,
webpack.config.js
main.js
Errors
heitorvrb commentedon Jun 19, 2017
Same issue here, with similar configuration. The situation seems to be that my app doesn't run on a ground-level domain, but on a alias on apache:
So webpack is trying to create the
src: url()
paths with/build/fonts/myFont.eot
, when it should be/mySymfonyApp/build/fonts/myFont.eot
.webpack.config.js:
global.scss:
Resulting global.css:
localhost/build/fonts/foundation-icons.ttf
obviously 404s, the correct path would belocalhost/mySymfonyApp/build/fonts/foundation-icons.ttf
weaverryan commentedon Jun 20, 2017
@heitorvrb Ah, thanks for the extra info! If you're deployed under a subdirectory, that should be reflected in your
setPublicPath
:You can see an example of this in the tests as well:
webpack-encore/test/functional.js
Line 180 in db980b4
Webpack must be aware of the true public path, because if you use "code splitting", then webpack itself will make AJAX requests for assets (so it needs to know the real path). That's why the config lives in
webpack.config.js
, instead of allowing your app (i.e. Symfony) to "fix" the subdirectory.Let me know if that helps! I'll open an issue on the docs about this.
heitorvrb commentedon Jun 20, 2017
It worked. Thanks for the help.
dayze commentedon Jun 21, 2017
It worked too, thanks !
vctls commentedon Oct 9, 2017
What if my web root changes depending to the environment I'm deploying to?
On my local development environment, the web root will be
/my-nth-app/web/build
whereas on the production server, it will just be
/build
.What would be the recommended way to make this dynamic, or at least, configurable?
Lyrkan commentedon Oct 9, 2017
@vctls Maybe you could use
Encore.isProduction()
to set the web root dynamically?vctls commentedon Oct 9, 2017
@Lyrkan I will do that, thank you :)
It feels a little hacky, though. I wonder if there's any way of detecting the web root.
scaytrase commentedon Nov 5, 2017
@Lyrkan what if I use artifact-based deploying and the builder do not really know where the artifact would be deployed to?
Is it possible just make path relative to manifest?
Lyrkan commentedon Nov 5, 2017
Hi @scaytrase,
I guess you would need to call
setPublicPath
with a relative path... which isn't allowed right now:webpack-encore/lib/WebpackConfig.js
Lines 122 to 127 in 7997206
@andyexeter had a similar issue here: #88 (comment)
We could probably add an
allowRelativePath
parameter to that method in order to disable that check... what do you think @weaverryan?scaytrase commentedon Nov 5, 2017
@Lyrkan commenting this error and passing relative path makes internal CSS files to import like
basedir/build/build/fonts/fontawesome.ttf
The
build
doubles since CSS file is placed inside thebuild
and it calls relativebuild/fonts/.../
So we really need the possibility to rewrite the paths
25 remaining items
dmeziere commentedon Jan 8, 2019
I am just desperated that SF team opted for a JavaScript solution to handle the assets. Nothing works no more with this technology. And there is no way to maintain it without absorbing a whole lot knowledge about JavaScript. I just hate this "language". When it's not the sass-loader that falls down, you discover that it just can't handle multiple environments. I think I will end with totally uninstalling webpack and find a working PHP solution, that can be configured, fixed, and adapted if necessary to anyone's needs. Frustrated. Why don't you use a stable language, something defined, something that runs the same on any environment. Something that works like any other language. Or maybe it's time to stop working with SF, but it is so sad ...
stof commentedon Jan 8, 2019
@dmeziere you are still free to build your assets the way you want, and reference them with the
asset()
function in your Twig template. The Asset component has no requirement on webpack-encore.Modern tooling regarding building frontend code is all written in JS. And we decided to recommend webpack (with this wrapper around its config to simplify it for the use cases we see). But it is not mandatory to use it with Symfony at all.
And regarding using a pure PHP solution, there is no PHP-based tooling implementing a module bundler for JS (JS developers build their tooling in the language they know: JS). And the Symfony core team has no interest into porting Webpack and its whole ecosystem to PHP (that would make no sense, and would require many full-time developers to catch up with the whole webpack community).
You can still do that yourselves if you want to use JS modules. And if you want to keep writing JS in the old way and only concatenate the files together in your final bundle, it is easy to implement that in any language (including a simple Bash command:
cat assets/js/*.js > web/build/js/app.js
)dmeziere commentedon Jan 10, 2019
So, I finally found the problem. It was an impact on fos_js_routing. But the frustration of loosing days on this point didn't help me to see things clearly. Finally the solution provided by @Lyrkan was the key as I also use aliases on my dev server, but not on my production server. But if you, falling on this ticket, are using fos_js_routing; be aware that the generated js/json file is not called anymore. It is integrated by webpack encore to the main JS file (what makes sense, after all). So you must make it "prod friendly" before calling yarn encore production. And you no longer need to dump the routes in your deployment script, this will be useless. Finally, I don't like the fact that I must compile and commit my production assets to my repo before a deployment, but it is way better than being forced to install node on the production server, downloading all the node_modules, etc.
Lyrkan commentedon Jan 10, 2019
@dmeziere Building the assets before a deployment is a good thing, but I'm not sure why you'd have to commit these files.
By the way, if you have more than two public paths to manage you can do something like this:
Then simply set the
ENCORE_PUBLIC_PATH
environment variable before calling Encore.trsteel88 commentedon Feb 25, 2019
I use sub directories for sites while in dev and it was a bit of a pain setting a publicPath. Especially when co-workers had different sub directory structures.
I wrote some code to automatically determine the public directory across all projects within the webpack config.
webpack.config.js
You will need to install dotenv from yarn for this to work.
In the above code we are just giving it an array of potential web root directories to look for. This is a list that a few different co-workers are using.
As soon as the loop find a value that matches the __dirname variable, it will take that value and append /public/build to the value.
e.g. if your build files are located in /usr/local/var/www/htdocs/clientXYZ/project123/public/build it will make the public path /clientXYZ/project123/public/build
We also have a .encore.env.dist where you can set a value for ENCORE_PUBLIC_PATH
toklok commentedon Nov 1, 2019
Some of us don't use CI/CD builds and must commit these files.
Lyrkan commentedon Nov 1, 2019
@toklok Even without CI/CD I wouldn't recommend commiting them. Building them locally before a deployment, or even directly on the server (which is not really a good thing either) are probably better solutions.
zulus commentedon Jun 16, 2021
My temporary solution:
.setPublicPath(Encore.isProduction() ? '.' : '/build/admin')
- so css will contain font paths relative to css filemodule.exports = Encore.getWebpackConfig()
addNow after yarn run build I have css with relative paths, and asset() function works fine. Unfortunately entrypoints.json have wrong paths, I cannot override it in similar way because AssetsWebpackPlugin calls webpackConfig.getRealPublicPath() directly.
carsonbot commentedon Dec 16, 2024
Thank you for this issue.
There has not been a lot of activity here for a while. Has this been resolved?
carsonbot commentedon Jun 17, 2025
Thank you for this issue.
There has not been a lot of activity here for a while. Has this been resolved?
carsonbot commentedon Jul 1, 2025
Just a quick reminder to make a comment on this. If I don't hear anything I'll close this.
carsonbot commentedon Jul 15, 2025
Hey,
I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!