I'm using Symfony 4 with Symfony Encore to handle assets, and some useful features, such as HMR.
Currently, I can handle Sass files, CSS files, JS, etc, and it works fine with HMR.
Now I would like to be able to make Weback dev server watch *.twig files for changes and trigger a live reload (as hot reload wouldn't be an option for server-side rendered templates).
I've seen things about --watchContentBase
and contentBase
options, but it doesn't do anything in my case:
WDS CLI :
./node_modules/.bin/encore dev-server --hot --disable-host-check --watchContentBase --contentBase ./templates/ --reload
webpack.config.js :
const Encore = require('@symfony/webpack-encore');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
Encore
.setOutputPath('public/build/')
.setPublicPath('/build')
.cleanupOutputBeforeBuild()
.autoProvidejQuery()
.addPlugin(new MiniCssExtractPlugin('[name].css'))
.enableSourceMaps(!Encore.isProduction())
.addLoader({
test: /\.(sc|sa|c)ss$/,
use: ['css-hot-loader'].concat(
MiniCssExtractPlugin.loader,
{
loader: 'css-loader'
},
{
loader: 'postcss-loader'
},
// {
// loader: 'postcss-loader'
// },
{
loader: 'sass-loader'
}
),
},)
.addLoader({
test: /\.twig$/,
loader: 'raw-loader'
},)
.enableVersioning(Encore.isProduction())
.addEntry('autocall-main', './assets/js/index.js')
// .addStyleEntry('autocall-main', ['./assets/scss/index.scss'])
.splitEntryChunks()
.enableSingleRuntimeChunk()
;
const config = Encore.getWebpackConfig();
module.exports = config;
My project files / folders follows the classic Symfony 4 structure: https://github.com/symfony/demo
What do I miss there?
Today, the year 2020, i have two solutions:
As you had said: I've seen things about --watchContentBase and contentBase options...
, this has nothing to do with encore. Its a default webpack configurations and you can learn more from webpack doc here
According to Advanced Webpack Config docs here you can extend webpack configs by calling var config = Encore.getWebpackConfig();
I have implemented as shown in the code below. For my case its working fine.
// webpack.config.js
var Encore = require('@symfony/webpack-encore');
var path = require('path');
// Manually configure the runtime environment if not already configured yet by the "encore" command.
// It's useful when you use tools that rely on webpack.config.js file.
if (!Encore.isRuntimeEnvironmentConfigured()) {
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}
Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
.setPublicPath('/build')
.addEntry('global', './assets/app.js')
// ... Your other encore code
// EXTEND/OVERRIDE THE WEBPACK CONFIG
const fullConfig = Encore.getWebpackConfig();
fullConfig.name = 'full';
// watch options poll is used to reload the site after specific set time
// polling is useful when running Encore inside a Virtual Machine
// more: https://webpack.js.org/configuration/watch/
fullConfig.watchOptions = {
poll: true,
ignored: /node_modules/
};
fullConfig.devServer = {
public: 'http://localhost:3000',
allowedHosts: ['0.0.0.0'],
// extend folder to watch in a symfony project
// use of content base
// customize the paths below as per your needs, for this simple
//example i will leave them as they are for now.
contentBase: [
path.join(__dirname, 'templates/'), // watch twig templates folder
path.join(__dirname, 'src/') // watch the src php folder
],
// enable watching them
watchContentBase: true,
compress: true,
open: true,
disableHostCheck: true,
progress: true,
watchOptions: {
watch: true,
poll: true
}
};
// export it
module.exports = fullConfig;
If you need a simple implementation you can use: webpack-watch-files-plugin. I prefer this, by the time you are reading this answer it might be abandoned but there many others with same functionality. In Symfony docs here you can implement Custom Loaders & Plugins as below. Using the above mentioned plugin we can implent it as follow:
// webpack.config.js
const WatchExternalFilesPlugin = require('webpack-watch-files-plugin').default;
Encore
// ...your code
.addPlugin(new WatchExternalFilesPlugin({
files: [
'/templates', // watch files in templates folder
'/src', // watch files in src folder
'!../var', // don't watch files in var folder (exclude)
],
verbose: true
}))
//...your code
;
Cheers. Happy coding!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With