I am attempting to get Webpack to process and copy all the image files in src folder and output them to the build folder using ‘image-webpack-loader`.
As far as I understand, Webpack will only do this with images referenced in CSS/SASS/LESS or an entry point.
I am working on a Symfony project and have many references in twig templates, which are obviously ignored.
Any idea how I could make this happen without the addition of a build tool or making a duplicate reference file for every image that I include in a project template?
Create a s subdirectory under web root:
Symfony 3:
web/s
Symfony 4 & 5:
public/s
Configure your new subdomain:
Symfony 3: (app/config/config.yml)
framework:
assets:
base_urls:
- '%protocol%://s.%host%'
Symfony 4 & 5: (config/packages/assets.yaml)
framework:
assets:
base_urls:
- '%protocol%://s.%host%'
Note:
%protocol% is either http or https accoring to you environment
%host% is your host, maybe example.com or something.
Configure Webpack (webpack.config.js)
Symfony 3:
var Encore = require('#symfony/webpack-encore');
Encore
// ...
.setOutputPath('./web/s/build/')
.setPublicPath('/build')
.setManifestKeyPrefix('build')
.cleanupOutputBeforeBuild()
// ...
;
module.exports = Encore.getWebpackConfig();
Symfony 4 & 5:
var Encore = require('#symfony/webpack-encore');
Encore
// ...
.setOutputPath('./public/s/build/')
.setPublicPath('/build')
.setManifestKeyPrefix('build')
.cleanupOutputBeforeBuild()
// ...
;
module.exports = Encore.getWebpackConfig();
Put all your images inside /web/s or /public/s according to your Symfony version.
Inside your Twig views, access them like below:
<img src="{{ asset('photo.jpg') }}" alt="Photo"/>
Accept and hit upvote on this cool answer!
In webpack.config.js, you could add .copyFiles() to the Encore object. This will take an object with "from", and "to" keys, with a couple of wildcards.
Here is an example:
.copyFiles({
from: 'src',
to: 'images/[path][name].[ext]'
})
Related
I've renamed my public directory into www so as the documentation says I've added some line in composer.json file:
"extra": {
"...": "...",
"public-dir": "www"
}
Then I ran composer update.
But it seems not to work.
I have this error :
An exception has been thrown during the rendering of a template ("Asset manifest file "*******/public/build/manifest.json" does not exist.").
So I've added in config/packages/dev/framework.yaml (I'm on dev):
framework:
assets:
json_manifest_path: '%kernel.project_dir%/www/build/manifest.json'
But another error has appeared:
An exception has been thrown during the rendering of a template ("Could not find the entrypoints file from Webpack: the file "*******/public/build/entrypoints.json" does not exist.").
Then I modify webpack.config.js file like this :
Encore
// directory where compiled assets will be stored
.setOutputPath('www/build/')
But the error is still there.
Is there a simple way to rename the public directory?
I've fixed my issue :
In config/packages/webpack_encore.yaml :
webpack_encore:
# The path where Encore is building the assets.
# This should match Encore.setOutputPath() in webpack.config.js.
output_path: '%kernel.project_dir%/www/build'
i am having problem with implementing jquery 3rd party plugins in symfony webpack encore.
so far i have several .js files with varous logic, and also some scripts inside twig files that execute some of js.
this is app.js :
var $ = require('jquery');
global.$ = global.jQuery = global.jquery = $;
require('jquery-validation');
webpack compiles, but when i execute program i get:
$(...).validate is not a function
webpack.config.js is straightforward:
var Encore = require('#symfony/webpack-encore');
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')
.setManifestKeyPrefix('build/')
.addEntry('base', './assets/js/base.js')
.splitEntryChunks()
.enableSingleRuntimeChunk()
;
module.exports = Encore.getWebpackConfig();
package.json:
"jquery": "^3.3.1",
"jquery-validation": "^1.18.0",
"jquery-datetimepicker": "^2.5.20",
update:
jquery-datetimepicker is working fine,
but jquery-validation is not!
solution:
update webpack.config.js with alias information, so that every jquery 3rd party plugin uses same jquery
var path = require('path');
Encore
.addAliases({
'jquery': path.join(__dirname, 'node_modules/jquery/src/jquery')
})
from: https://symfony.com/doc/current/frontend/encore/legacy-apps.html
jQuery Plugins and Legacy Applications
Inside Webpack, when you require a module, it does not (usually) set a global variable. Instead, it just returns a value:
// this loads jquery, but does *not* set a global $ or jQuery variable
const $ = require('jquery');
...
Fixing jQuery Plugins that Expect jQuery to be Global
jQuery plugins often expect that jQuery is already available via the $ or jQuery global variables. To fix this, call autoProvidejQuery() from your webpack.config.js file:
Encore
// ...
.autoProvidejQuery() // add this line into your webpack.config.js file
;
Accessing jQuery from outside of Webpack JavaScript Files
If your code needs access to $ or jQuery and you are inside of a file that's processed by Webpack/Encore, you should remove any "$ is not defined" errors by requiring jQuery: var $ = require('jquery').
But if you also need to provide access to $ and jQuery variables outside of JavaScript files processed by Webpack (e.g. JavaScript that still lives in your templates), you need to manually set these as global variables in some JavaScript file that is loaded before your legacy code.
For example, in your app.js file that's processed by Webpack and loaded on every page, add:
// require jQuery normally
const $ = require('jquery');
+ // create global $ and jQuery variables
+ global.$ = global.jQuery = $;
From a new Symfony 4 project, when I run this command :
./node_modules/.bin/encore dev-server --hot
And then I modify a scss file (change the the body tag background-color by example), the shell react
But my browser does not automatically refresh ! I always have to reload manually the page for see the latest css change. Where may I do a mystake ?
Thank you !
=> I tested with different browsers
=> If I modify a custom javascript file, the browser autorefresh ! in contrary when I change the scss file
=> My assets directory structure :
=> My webpack.config.js content :
var Encore = require('#symfony/webpack-encore');
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/')
/*
* ENTRY CONFIG
*
* Add 1 entry for each "page" of your app
* (including one that's included on every page - e.g. "app")
*
* Each entry will result in one JavaScript file (e.g. app.js)
* and one CSS file (e.g. app.css) if you JavaScript imports CSS.
*/
.addEntry('app', './assets/js/app.js')
.addEntry('article/main', './assets/js/article/main.js')
.addStyleEntry('article/style','./assets/css/article/style.scss')
//.addEntry('page2', './assets/js/page2.js')
/*
* FEATURE CONFIG
*
* Enable & configure other features below. For a full
* list of features, see:
* https://symfony.com/doc/current/frontend.html#adding-more-features
*/
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
// enables hashed filenames (e.g. app.abc123.css)
.enableVersioning(Encore.isProduction())
// enables Sass/SCSS support
.enableSassLoader()
// uncomment if you use TypeScript
//.enableTypeScriptLoader()
// uncomment if you're having problems with a jQuery plugin
//.autoProvidejQuery()
;
module.exports = Encore.getWebpackConfig();
=> And my automatically generated public/build/manifest.json file :
considering the documentation here the Hot Module Replacement (HMR) doesn't work for everything at the moment. It should work for Vue.js but that's all.
For more informations you can check the documentation for HMR.
TL:DR Your custom js & css assets are not supposed to be hot reloaded in the current state of HMR. You'll have to reload your browser manually. I don't know if you know about the --watch option, but it'll allow you to compile your code every time a file has changed.
Good luck
I'm having errors when I try to build my VueJS project with the style sheets.
My error when I run "yarn run dev --watch" produces these errors:
c:\wamp\www\DBViewer2>yarn run dev --watch
yarn run v1.6.0
warning package.json: No license field
$ encore dev --progress=true --watch
Running webpack ...
0% compiling
Webpack is watching the files…
95% emitting ERROR Failed to compile with 1 errors 16:00:56
This dependency was not found:
* !!vue-style-loader!css-loader?sourceMap!../node_modules/vue-loader/lib/style-compiler/index?{"optionsId":"0","vue":true,"scoped":false,"sourceMap":true}!scss-loader!../node_modules/vue-loader/lib/selector?type=styles&index=0!./App.vue in ./assets/App.vue
To install it, you can run: npm install --save !!vue-style-loader!css-loader?sourceMap!../node_modules/vue-loader/lib/style-compiler/index?{"optionsId":"0","vue":true,"scoped":false,"sourceMap":true}!scss-loader!../node_modules/vue-loader/lib/selector?type=styles&index=0!./A
I'm not sure what is causing this. It appears it is looking for the files in the wrong location?
Here is my App.vue file:
<template>
<router-view></router-view>
</template>
<script>
export default {
name: 'app'
}
</script>
<style lang="scss-loader">
/* Import Font Awesome Icons Set */
$fa-font-path: 'font-awesome/fonts/';
#import 'font-awesome/scss/font-awesome.scss';
/* Import Simple Line Icons Set */
$simple-line-font-path: 'simple-line-icons/fonts/';
#import 'simple-line-icons/scss/simple-line-icons.scss';
/* Import Bootstrap Vue Styles */
#import 'bootstrap-vue/dist/bootstrap-vue.css';
/*// Import Main styles for this application*/
#import './assets/scss/style';
</style>
Here is my webpack.config.js:
var Encore = require('#symfony/webpack-encore');
Encore
// the project directory where all compiled assets will be stored
.setOutputPath('public_html/build/')
// the public path used by the web server to access the previous directory
.setPublicPath('/build')
// will create public/build/app.js and public/build/app.css
.addEntry('main', './assets/main.js')
.addEntry('vendor', './assets/js/vendor.js')
// allow legacy applications to use $/jQuery as a global variable
.autoProvidejQuery()
// enable source maps during development
.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()
.enableVueLoader()
// allow sass/scss files to be processed
.enableSassLoader()
;
// export the final configuration
module.exports = Encore.getWebpackConfig();
Any suggestions is greatly appreciated. Have spent 2 days now trying different things and research on google. I'm just not familiar enough with symfony/encore and this is my first vuejs project.
In order to be able to use SCSS in a Vue template, you need to declare in the single file component the following style block:
<!-- Those styles are not scoped to that particular component -->
<style lang="scss">...</style>
<!-- Or those styles are scoped to that particular component -->
<style lang="scss" scoped>...</style>
You can even use both in the same file, if needed.
You'll also need to install the correct node dependencies by running:
npm install --dev node-sass sass-loader
This should then work out of the box when used in a project initialized with vue-cli.
However you could need to add this in your webpack 'test' configuration to make lang="scss" work in tests when using vue-loader's ?inject option:
resolveLoader: {
alias: {
'scss-loader': 'sass-loader',
},
},
I'm working on a Symfony 4 project with Webpack Encore for asset management.
I configured my local server with this : https://stackoverflow.com/a/15864222/5158153
I can access to localhost from my Android device but it doesn't get access to any asset.
I tried with another project (not Symfony) and it can get assets.
I think there's something I forgot with webpack config but I don't know what.
Webpack-config.js
const Encore = require('#symfony/webpack-encore');
Encore
.setOutputPath('public/build/')
.setPublicPath('http://localhost/tharmo/public/build')
.setManifestKeyPrefix('build/')
.cleanupOutputBeforeBuild()
.enableSourceMaps(!Encore.isProduction())
.autoProvidejQuery()
.createSharedEntry('vendor', [
'./assets/js/custom.js',
'materialize-css',
])
.addEntry('app', './assets/js/app.js')
.enableSassLoader()
;
module.exports = Encore.getWebpackConfig();
base.html.twig
<link type="text/css" rel="stylesheet" href="{{ asset('build/app.css') }}"
media="screen,projection" />
It works correctly in Windows where Wamp server is installed but not in Android.
On Android device, if I type the url, I can get the asset so something is wrong with the way I get asset in Twig.