简体   繁体   中英

Symfony 4 - Webpack-encore use FosJsRouting : Routing is not defined

I try to use FosJsRouting with Webpack-encore in my Symfony 4 project.

I did :

1.

composer require friendsofsymfony/jsrouting-bundle

2.

php bin/console assets:install --symlink public

3.

php bin/console fos:js-routing:dump --format=json --target=public/js/fos_js_routes.json

And in my app.js :

// FosJsRouting

const routes = require('../../public/js/fos_js_routes.json');
import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js';
Routing.setRoutingData(routes);

Now, if in the app.js I do a console.log(Routing); I get the object in the console.

On the other hand, impossible to use it in my templates.

I have the following error:

Uncaught ReferenceError: Routing is not defined

I do not understand because my other packages work very well, but not the Routing

You may have found the solution but here are some information for the others:

  • The files are isolated that's why a variable which is defined from import/require in a file is undefined in another or in your templates even if you include the file in your template.

1. Import and configure everywhere

So, inside your app.js , where you import Routing , it can only be used in this specific file and you must import it wherever you want it. But, you need to set the routes everytime:

app.js

const routes = require('../../public/js/fos_js_routes.json');
import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js';
Routing.setRoutingData(routes);

console.log(Routing.generate("exposed_route_name")); // will prints in console /path/to/exposed_route

other.js

const routes = require('../../public/js/fos_js_routes.json');
import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js';
Routing.setRoutingData(routes);

console.log(Routing.generate("another_exposed_route_name")); // will prints in console /path/to/another_exposed_route

It is not a proper solution because it too redundant and nobody wants to duplicate the same code everytime.


2. Globalize Routing variable

Another solution is setting Routing as global and access it in files included after:

app.js

const routes = require('../../public/js/fos_js_routes.json');
import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js';
Routing.setRoutingData(routes);

// Setting Routing as global there
global.Routing = Routing;

console.log(Routing.generate("exposed_route_name")); // will prints in console /path/to/exposed_route

other.js

console.log(Routing.generate("another_exposed_route_name")); // will prints in console /path/to/another_exposed_route

template.html.twig

{{ encore_entry_script_tags('app') }}
{{ encore_entry_script_tags('other') }}

<script>
console.log(Routing.generate("a_third_exposed_route_name")); // will prints in console /path/to/third_exposed_route
</script>

The problem is that Routing will be available everywhere when the file which globalize it is included. It will be available in your web console too and I don't think it is a good thing because everyone will be able to see all your fos_js_routing configuration.


3. Export Routing in your own module

And there is the solution for which you create a "fake" Routing module. In this file, you will set your Routing object configuration and export it:

routing.js

const routes = require("../../public/js/fos_js_routes");
const Routing = require("../../public/bundles/fosjsrouting/js/router"); // do not forget to dump your assets `symfony console assets:install --symlink public`

Routing.setRoutingData(routes);

module.exports = Routing;

And then import it in whatever file to use it:

other.js

const Routing = import("./routing");
console.log(Routing.generate("another_exposed_route_name")); // will prints in console /path/to/another_exposed_route

You don't need to setting routing.js as a webpack entry nor including it in your templates. However, I don't know how to do it if you write your javascript directly in your twig templates.

Hope you will find your solution. You can also check this tutorial on SymfonyCasts.

Globalise Routing variable is solution to use in javascript with webpack installation

In app.js

const routes = require('../../public/js/fos_js_routes.json');
import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js';
Routing.setRoutingData(routes);

// Setting Routing as global there
global.Routing = Routing;

console.log(Routing.generate("exposed_route_name"));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM