gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
Let's get back to talking about the real power of Webpack: the ability to import or require JavaScript files. Pretend that building this string is actually a lot of work. Or maybe it's something we need to re-use from somewhere else in our code:
... lines 1 - 13 | |
console.log('Hello Webpack Encore! Edit me in assets/js/app.js!!!'); |
So, we want to isolate it into its own file. If this were PHP, we would create a new file to hold this logic. In JavaScript, we're going to do the same thing.
In assets/js/
, create a new file called get_nice_message.js
. Unlike PHP, in JavaScript, each file that you want to use somewhere else needs to export something, like a function, object, or even a string. Do that by saying module.exports =
and then the thing you want to export. Let's create a function()
with one argument exclamationCount
:
module.exports = function(exclamationCount) { | |
... line 2 | |
}; |
Inside, let's go steal our string... then return that string and, to increase our fanciness, add '!'.repeat(exclamationCount)
:
module.exports = function(exclamationCount) { | |
return 'Hello Webpack Encore! Edit me in assets/js/app.js'+'!'.repeat(exclamationCount); | |
}; |
Yes. Because strings are objects in JavaScript, this works - it's kinda cool. By the way, when a JavaScript file exports a value like this, it's known as a "module". That's not a big deal, but you'll hear this term a lot: JavaScript modules. OooOOOoo. It just refers to what we're doing here.
Now go back to app.js
. At the top, well... it doesn't need to be on top, but usually we organize the imports there, add const getNiceMessage = require('./get_nice_message');
:
/* | |
* Welcome to your app's main JavaScript file! | |
* | |
* We recommend including the built version of this JavaScript file | |
* (and its CSS file) in your base layout (base.html.twig). | |
*/ | |
// any CSS you require will output into a single css file (app.css in this case) | |
require('../css/app.css'); | |
// Need jQuery? Install it with "yarn add jquery", then uncomment to require it. | |
// const $ = require('jquery'); | |
const getNiceMessage = require('./get_nice_message'); | |
... lines 15 - 17 |
Notice the .js
extension is optional, you can add it or skip it - Webpack knows what you mean. And because, key strokes are expensive... and programmers are lazy, you usually don't see it.
Also, that ./
at the beginning is important. When you're pointing to a file relative to the current one, you need to start with ./
or ../
. If you don't, Webpack will think you're trying to import a third-party package. We'll see that soon.
And now that we have our getNiceMessage()
function, let's call it! Pass it 5 for just the right number of excited exclamation points:
... lines 1 - 13 | |
const getNiceMessage = require('./get_nice_message'); | |
console.log(getNiceMessage(5)); |
And because we're running the watch
command in the background, when we refresh, it just works!
But! When we originally looked at the Webpack docs, they weren't using require()
and module.exports
! Nope, they were using import
and export
. It turns out, there are two valid ways to export and import values from other files... and they're basically identical.
To use the other way, remove module.exports
and say export default
:
export default function(exclamationCount) { | |
... line 2 | |
}; |
That does the same thing. The default
is important. With this syntax, a module, so, a file, can export more than one thing. We're not going to talk about that here, but most of the time, you'll want to export just one thing, and this default
keyword is how you do that.
Next, back in app.js
, the require
changes to import getNiceMessage from './get_nice_message'
:
... lines 1 - 13 | |
import getNiceMessage from './get_nice_message'; | |
... lines 15 - 17 |
That's it! That is 100% the same as what we had before. So, which should you use? Use this syntax. The require()
function comes from Node. But the import
and export
syntax are the official way to do module loading in ECMAScript, which is the actual name for the JavaScript language specification.
You can - and should - also use this for CSS. Just import
, then the path:
... lines 1 - 7 | |
// any CSS you require will output into a single css file (app.css in this case) | |
import '../css/app.css'; | |
... lines 10 - 17 |
There's no from
in this case because we don't need it to return a value to us.
Make sure all this coolness works: refresh! Yes!
Woh! Hey! Shut the front door! Did we just organize our JavaScript without global variables? Yes! We totally did! And that is no small thing. Heck, we could stop the tutorial right now, and you would still have this amazing superpower.
But... we won't! There is still so much cool stuff to talk about. Like, how we can now super easily install third-party libraries via Yarn and import them in our code. Let's do it!
the .js and .css files are getting built in the build directory but console.log is not working it seems. No output on console after successfull build
Hey CloudCreators
Can you double-check that the CSS and JS files are being requested in your browser? You can check by opening the web debug toolbar and inspect the requests. A second thing to do is to do a hard refresh on your Browser (Usually Ctrl + F5)
Cheers!
Hey Shubham,
It's minor, and you can completely ignore this error for now while develop a project for learning purposes, but it's bad for production of course. If you want to fix it - make sure you have that favicon.ico file in your public/ directory. If not - create an .ico file and put it there, and try again. Or, if you have that ico file in a different dir - point the link in your base.html.twig to it. But I'd not recommend you to place it in a different place or handle this file via Webpack Encore - this is something that should be called favicon.ico and be stored in the public/ dir, think of this as a defacto standard :)
Cheers!
MY APP.JS FILE
import '../styles/app.css';
import getNiceMessage from './get_nice_message';
console.log(getNiceMessage(5));
// start the Stimulus application
import '../bootstrap';
MY GETNICEMESSAGE.JS FILE
export default function(exclamationCount){
// console.log('Hello Webpack Encore! Edit me in assets/js/app.js'+'!'.repeat(exclamationCount));
return 'Hello Webpack Encore! Edit me in assets/js/app.js'+'!'.repeat(exclamationCount);
};
THE background color changes as specified in .css but no console log printed.
The css is working the background colour changes but no output on console which I put in my .js file. I tried the hard refresh too.
Hey Niki,
Yes, it should just work out of the box as soon as it works with Webpack. I see in their docs that to use the "@material/textfield" component you just need to import it as:
import {MDCTextField} from '@material/textfield/index';
So, just try to follow their installation steps in docs: https://github.com/material-components/material-components-web#using-npm
I hope this helps! If you have any problems with Encore during those steps - just let us know and we would try to help!
Cheers!
Okay thank you. Is there a way to use Angular Material only instead of Material Components in non-Angular App?
Hey Niki,
Well, I'm not familiar with Angular Material unfortunately, so don't know, probably better to just google this :)
Cheers!
Hello, first thanks a lot for this amazing course !!! I discover so much cool things ! But I have a problem, I can't import external jquery library.
I tried with jquery nicescroll and jquery circle progress but I have always an error $(...).niceScroll is not a function or $(...).circleProgress is not a function...
No problem for using jquery and no problem for using bootstrap functions like dropdown for example but other external libraries don't work :(
I installed it with yarn and imported it like that :
'use strict';
import $ from 'jquery';
import 'bootstrap';
import 'jquery.nicescroll';
import 'jquery-circle-progress';
// and next my code
// this code is ok
$(".side-navbar li a").click(function(event) {
$(".collapse").collapse('hide');
});
// this code makes an error nicescroll not a function
$(".sidebar-scroll").niceScroll({
// some options
});
Thanks a lot for your help
Hey danslacabanedelilie
That's a problem coming from bad written Jquery plugins. I recommend you to watch this episode where Ryan talks about it and shows a solution: https://symfonycasts.com/sc...
Cheers!
Thanks MolloKhan for your response. I've watched this episode and the autoProvidejQuery() is in my webpack.config.js but not better. And it's not a "jQuery is not defined" error that I have but it's $(...).niceScroll is not a function or $(...).circleProgress is not a function.
I don't understand why it's not working. Here is my config file :
var Encore = require('@symfony/webpack-encore');
Encore
.setOutputPath('public/build/')
.setPublicPath('/build')
.addEntry('register', './assets/js/register.js')
.addEntry('default', './assets/js/default.js')
.addEntry('ecole', './assets/js/ecole.js')
.addEntry('projet', './assets/js/projet.js')
.splitEntryChunks()
.enableSingleRuntimeChunk()
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
.enableVersioning(Encore.isProduction())
.configureBabel(() => {}, {
useBuiltIns: 'usage',
corejs: 3
})
.enableLessLoader()
.autoProvidejQuery()
.copyFiles({
from: './assets/img',
to: 'img/[path][name].[hash:8].[ext]'
})
;
module.exports = Encore.getWebpackConfig();
Hey Danslacabanedelilie,
I see you have ".autoProvidejQuery()" in your webpack config - that's good! So, the question is how you import things in your JS files? IN you file where, e.g. you want to circleProgress plugin you need to import jQuery first, and then import the plugin, i.e. something like this:import $ from 'jquery';<br />import 'jquery-circle-progress';
So, only import the jQuery is NOT enough, you have to also import the plugins you are going to use, and do it AFTER jQuery is imported. Also, it depends on plugins, you may need different workarounds for different plugins, I'd recommend you to look into official plugin repositories - search in docs or search for issues where people describe how to import the plugin with Webpack and do the same.
I hope this helps!
Cheers!
Hello victor thanks for your response.
As I said in my first comment I installed it with yarn and imported it like that in my js file :
`
'use strict';
import $ from 'jquery';
import 'bootstrap';
import 'jquery.nicescroll';
import 'jquery-circle-progress';
import 'chart.js';
// and next my code
// this code is ok
$(".side-navbar li a").click(function(event) {
$(".collapse").collapse('hide');
});
// this code makes an error nicescroll not a function
$(".sidebar-scroll").niceScroll({
// some options
});
// this code makes an error circleprogress not a function
$('.circle').circleProgress({
value: 0.87,
size: 150,
startAngle: -Math.PI / 2,
thickness: 14,
lineCap: 'round',
emptyFill: '#f0eff4',
fill: {
gradient: ['#f9a58d', '#e76c90']
}
}).on('circle-animation-progress', function (event, progress) {
$(this).find('.percent').html(Math.round(87 * progress) + '<i>%</i>');
});
`
I also use chart.js and I have no problem with it but it's written in vanilla...
It seems it's only with jquery plugins, I've tried with some others and it's the same.
I looked into official repo for circle progress for example and it needs no specific configuration so I really don't understand...
I will open an issue in plugins repo maybe someone will know what's happen
Interesting... try adding this to your webpack.config.js file
...
const config = Encore.getWebpackConfig();
// see https://github.com/symfony/webpack-encore/issues/244
config.resolve.alias.jquery = path.join(__dirname, 'node_modules/jquery/dist/jquery');
module.exports = config;
// end of file
MolloKhan OMG you saved my life !!! I was on vacation, I just tried and magic it works now ! I will look at the issue to understand the trick, thanks thanks thanks !!!
#assets/app.js
import $ from 'jquery';
import 'carousel';
import 'bootstrap'; //adds functions to jquery
$(document).ready(function () {
var owl = $('#owl-slide');
owl.on('changed.owl.carousel', function (event) {
var element = event.target;
$('div[id="slide-shortcuts_"]').hide();
});
owl.owlCarousel({
items: 1,
nav: true,
autoplay: true,
autoplayHoverPause: true,
autoplayTimeout: 4000,
navText: [
"prev",
"next"
],
dotsContainer: '.owl-pagination'
});
});
It says to me owlcarousel is not a function also with pushmenu he tells me to install it with npm, I've done that and he says the same thing over over. I'm not sure if use encore or going back to the imports without it, it's so boring
Hey Giacomo,
Did you follow their quick start: https://github.com/OwlCarou... ? I see they say to import it as 'owl.carousel'.
Cheers!
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"aws/aws-sdk-php": "^3.87", // 3.91.4
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"knplabs/knp-markdown-bundle": "^1.7", // 1.7.1
"knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
"knplabs/knp-time-bundle": "^1.8", // 1.9.0
"league/flysystem-aws-s3-v3": "^1.0", // 1.0.22
"league/flysystem-cached-adapter": "^1.0", // 1.0.9
"liip/imagine-bundle": "^2.1", // 2.1.0
"nexylan/slack-bundle": "^2.0,<2.2.0", // v2.1.0
"oneup/flysystem-bundle": "^3.0", // 3.0.3
"php-http/guzzle6-adapter": "^1.1", // v1.1.1
"sensio/framework-extra-bundle": "^5.1", // v5.3.1
"stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
"symfony/asset": "^4.0", // v4.2.5
"symfony/console": "^4.0", // v4.2.5
"symfony/flex": "^1.9", // v1.17.6
"symfony/form": "^4.0", // v4.2.5
"symfony/framework-bundle": "^4.0", // v4.2.5
"symfony/orm-pack": "^1.0", // v1.0.6
"symfony/security-bundle": "^4.0", // v4.2.5
"symfony/serializer-pack": "^1.0", // v1.0.2
"symfony/twig-bundle": "^4.0", // v4.2.5
"symfony/validator": "^4.0", // v4.2.5
"symfony/web-server-bundle": "^4.0", // v4.2.5
"symfony/webpack-encore-bundle": "^1.4", // v1.5.0
"symfony/yaml": "^4.0", // v4.2.5
"twig/extensions": "^1.5" // v1.5.4
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0", // 3.1.0
"easycorp/easy-log-handler": "^1.0.2", // v1.0.7
"fzaninotto/faker": "^1.7", // v1.8.0
"symfony/debug-bundle": "^3.3|^4.0", // v4.2.5
"symfony/dotenv": "^4.0", // v4.2.5
"symfony/maker-bundle": "^1.0", // v1.11.5
"symfony/monolog-bundle": "^3.0", // v3.3.1
"symfony/phpunit-bridge": "^3.3|^4.0", // v4.2.5
"symfony/profiler-pack": "^1.0", // v1.0.4
"symfony/var-dumper": "^3.3|^4.0" // v4.2.5
}
}
// package.json
{
"devDependencies": {
"@symfony/webpack-encore": "^0.27.0", // 0.27.0
"autocomplete.js": "^0.36.0",
"autoprefixer": "^9.5.1", // 9.5.1
"bootstrap": "^4.3.1", // 4.3.1
"core-js": "^3.0.0", // 3.0.1
"dropzone": "^5.5.1", // 5.5.1
"font-awesome": "^4.7.0", // 4.7.0
"jquery": "^3.4.0", // 3.4.0
"popper.js": "^1.15.0",
"postcss-loader": "^3.0.0", // 3.0.0
"sass": "^1.29.0", // 1.29.0
"sass-loader": "^7.0.1", // 7.3.1
"sortablejs": "^1.8.4", // 1.8.4
"webpack-notifier": "^1.6.0" // 1.7.0
}
}
You are a hero! Nice video's my man!