Salut à tous,

J'ai une question concernant le bundle symfony/webpack-encore (pour symfony 4 dans mon cas).

Comment accéder aux fonctions contenues dans mon code javascript qui a été empaqueté par Encore?


Voici un exemple avec plus de détail:


fichier javascript (jsTest.js):

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
function jsTest() {}
 
jsTest.prototype = {
    affichage: function affichage(message) {
        alert(message);
    }
};
console.log('fichier chargé');

code dans la vue:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
{% block javascripts %}
    {{ parent() }}
    <script type="text/javascript" src="/js/jsTest.js"></script>
    <script type="text/javascript">
        var jsT = new jsTest();
        jsT.affichage('mon message');
    </script>
{% endblock %}
Tout fonctionne correctement.


Mais avec le code généré par Encore:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
{% block javascripts %}
    {{ parent() }}
    <script type="text/javascript" src="{{ asset('build/jsTest.js') }}"></script>
    <script type="text/javascript">
        var jsT = new jsTest();
        jsT.affichage('mon message');
    </script>
{% endblock %}
Une erreur se produit: "Uncaught ReferenceError: jsTest is not defined".
Le console.log a bien affiché "fichier chargé".


C'est normal d'avoir une erreur car le code javascript a été encapsulé par webpack.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
webpackJsonp([4],{

/***/ "./assets/js/jsTest.js":
/*!*****************************!*\
  !*** ./assets/js/jsTest.js ***!
  \*****************************/
/*! dynamic exports provided */
/*! all exports used */
/***/ (function(module, exports) {

function jsTest() {}

jsTest.prototype = {
    affichage: function affichage(message) {
        alert(message);
    }
};
console.log('fichier chargé');

/***/ })

},["./assets/js/jsTest.js"]);

La question est de savoir comment accéder à cette fonction à partir de la vue.

J'ai trouvé une solution qui ne me plaît pas.
Le principe est de créer une variable "globale" en javascript et de l'utiliser dans le fichier javascript.

fichier javascript:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
function jsTest(){}
 
jsTest.prototype = {
    affichage: function(message){
        alert(message);
    }
};
jsT = new jsTest();
code dans la vue:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
{% block javascripts %}
    {{ parent() }}
    <script type="text/javascript">var jsT; </script>
    <script type="text/javascript" src="{{ asset('build/jsTest.js') }}"></script>
    <script type="text/javascript">
        jsT.affichage('mon message');
    </script>
{% endblock %}
Quelqu'un peut-il m'éclairer sur comment Encore doit être utilisé dans un tel cas?

Un tout grand merci.

Pour information:

webpack.config.js

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var Encore = require('@symfony/webpack-encore');
 
Encore
    .setOutputPath('public/build/')
    .setPublicPath('/build')
    .cleanupOutputBeforeBuild()
    .enableSourceMaps(!Encore.isProduction())
    .autoProvidejQuery()
    .enableVersioning()
 
    .addEntry('jsTest', './assets/js/jsTest.js')
;
 
module.exports = Encore.getWebpackConfig();

et la configuration du versioning dans framework.yml

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
framework:
	assets:
        json_manifest_path: '%kernel.project_dir%/public/build/manifest.json'