问题
I cannot get FOSJsRoutingBundle to work with Symfony Flex, Webpack and AngularJS.
I've been using this bundle in Symfony 3 with AngularJS for a long time and there's never been an issue but with the introduction of webpack in Symfony Flex, the setup has become more complex. Unfortunately the documentation for FOSJsRoutingBundle version 2.2 isn't clear.
You can find the current documentation for this bundle here.
I am using the FOSJsRoutingBundle so that my Angular HTTP requests can use the generated routes rather than absolute URLs.
The Problem
I have setup this bundle as documented through composer. The routes are then dumped to a json file located at code/assets/fos_js_routes.json
. The generated routes in this file are valid and what I expect to see.
As I am using Angular I want to do the initial required declaration of the Routing in a separate file so that all of my Angular controllers can use the Routing.
without having to do any further work in those files.
FOS setup file /code/assets/js/fos_js_router.js
(Following documentation)
const routes = require('../../assets/fos_js_routes.json');
import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js';
Routing.setRoutingData(routes);
Sample Angular file /code/assets/js/apps/default/controller/test.js
(function () {
'use strict';
angular.module('test')
.controller(
'TestCtrl',
['$scope', '$http',
function ($scope, $http) {
let url = Routing.generate('test_route_name');
}
])
});
Webpack Config
var Encore = require('@symfony/webpack-encore');
Encore
.setOutputPath('public/build/')
.setPublicPath('/build')
.addEntry('app', './assets/js/app.js')
.addEntry('app_fos_router', [
'./assets/js/fos_js_router.js'
])
.addEntry('app_angular', [
'./assets/js/apps/default/app.js', // angular app setup
'./assets/js/apps/default/routes.js', // angular routes setup
'./assets/js/apps/default/controller/test.js' // angular where Routing is needed
])
.enableSingleRuntimeChunk()
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
.enableVersioning(Encore.isProduction())
;
module.exports = Encore.getWebpackConfig();
Front-end twig template
{% extends 'base.html.twig' %}
{% block title %}Test{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{{ encore_entry_script_tags('app_fos_router') }}
{{ encore_entry_script_tags('app_angular') }}
{% endblock %}
{% block body %}
<div ng-app="test" ui-view="content"></div>
{% endblock %}
The Error
From the above setup I get test.js: ReferenceError: Routing is not defined at
in my AngularJS files.
What do I need to do differently so that I can make use of let url = Routing.generate('test_route_name');
in my AngularJS files?
回答1:
Create file router.js
in your assets/js
directory. Next, fill router.js
with following content:
const routes = require('./fos_js_routes.json');
const router = require('../../vendor/friendsofsymfony/jsroutingbundle/Resources/public/js/router.min.js');
router.setRoutingData(routes);
module.exports = router;
Provide new variable in your webpack.config.js
like this:
.autoProvideVariables({
"Routing": "router",
})
Add new loader to your webpack:
.addLoader({
test: /jsrouting-bundle\/Resources\/public\/js\/router.min.js$/,
loader: "exports-loader?router=window.Routing"
})
Finally extend webpack config with:
let config = Encore.getWebpackConfig();
config.resolve.alias = {
'router': __dirname + '/assets/js/router.js',
};
module.exports = config;
It should make Routing a global object so you can use it in other js files like this:
let url = Routing.generate('some_route_name', { param: value });
Hope it helps. Cheers.
回答2:
Simple fix to get this working:
const routes = require('../../assets/fos_js_routes.json');
import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js';
Routing.setRoutingData(routes);
window.Routing = Routing;
来源:https://stackoverflow.com/questions/54053137/webpack-fosjsroutingbundle-integration-with-symfony-flex-and-angular