Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to use the router.js with webpack? #264

Closed
videni opened this issue Nov 1, 2016 · 7 comments
Closed

how to use the router.js with webpack? #264

videni opened this issue Nov 1, 2016 · 7 comments

Comments

@videni
Copy link

videni commented Nov 1, 2016

import Routing from '../../../../../../../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router';
var  link= Routing.generate('pintushi_shop_account_car_brand');

this will throw an error

bundle.js:31419 Uncaught TypeError: _router2.default.generate is not a function

@Nightbr
Copy link

Nightbr commented Feb 15, 2017

+1 any idea for this ?

@stof
Copy link
Member

stof commented Feb 15, 2017

the router.js file currently does not support AMD and CommonJS, meaning importing it directly won't work. you would have to create a shim exposing the global variable through CommonJS instead

@Kolbasyatin
Copy link

Kolbasyatin commented Sep 19, 2017

My solution inspired by this comment

bin/console fos:js-routing:dump we have to generate routes.

Then I created file /assets/js/router.js

const {router}  = require('../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.js');
require('../../web/js/fos_js_routes');
module.exports = router;

Then webpack magic starts:
In webpack.config.js(actually I use Symfony Webpack Encore)
I declare alias for router, declare variable Router, then I add loaders. See below...

..... encore config file .....
    .autoProvideVariables({
        "Routing": "router" 
    })
    .addLoader({
        test: /jsrouting-bundle\/Resources\/public\/js\/router.js$/,
        loader: "exports-loader?router=window.Routing"
    })

let config = Encore.getWebpackConfig();
config.resolve.alias = {
    'router': __dirname + '/assets/js/router.js'
};

So, when you need Access to Router in any place, just type Routing.generate('your_route') :)

p.s. 21.09.2017 some updates was done. Removed unnesesary code from webpack config.

@davidesigner
Copy link

Hi @Kolbasyatin,

your solution looks clean but I have an error with it: TypeError: Cannot read property 'navigator' of undefined at a (router.js:8). Have you an idea to solve this problem?

Thanks.

@Kolbasyatin
Copy link

@davidesigner it seems like something wrong with your path to files. Check your relative path here (in my case ../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.js

const {router}  = require('../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.js');

and also check path in loader.

Anyway, if file router.js has loaded in right way, you can just type fos in browser console and You'll see Router in global scope... something like this

>fos

{Router: ƒ}Router: ƒ K(a, c)g: ƒ ()getInstance: ƒ ()j: K {a: {}, d: s}setData: ƒ (a)arguments: nullcaller: nulllength: 2name: "K"prototype: {h: ƒ, o: ƒ, k: ƒ, n: ƒ, l: ƒ, …}__proto__: ƒ ()[[FunctionLocation]]: router.js:8[[Scopes]]: Scopes[3]__proto__: Object
....

If no, type your code here and we found solution.
By the way, here is a repo, when my code works. Maybe this will help.

@vigintas
Copy link

vigintas commented Nov 2, 2017

I had an even trickier problem as I had to expose some routes and base path to webpack config itself before any of the loaders are run so stuff like expose-loader was not going to cut it. And of course because the module was binding to the window object I had to extract it this way:

// lib/RoutingCli.js
const fs = require('fs');
const path = require('path');
let window = {};

(function () {
    eval(fs.readFileSync(path.resolve(__dirname, '../../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.js'), 'utf8'));
    eval(fs.readFileSync(path.resolve(__dirname, '../../../web/js/fos_js_routes.js'), 'utf8'));
}).call(window);

module.exports = window.Routing;

And from there it's easy to use it in webpack config:

// webpack.config.js
const routing = require('./lib/RoutingCli');
module.exports = {
    ....
    output: {
        ...
        publicPath: routing.getBaseUrl() + '/client/'
    }
    ...
};

Note that for this to work you cannot have your webpack config files written in es6 or named *.babel.js, which automatically parses them with babel-loader and enables strict mode, which in turn changes the way eval this context works.

For completeness, a separate file for es6 browser code imports:

// lib/RoutingWeb.js
require('expose-loader?window!../../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router');
require('../../../web/js/fos_js_routes');

export default global.window.Routing;

// index.js
import Routing from './lib/RoutingWeb';
Routing.generate('route_name', null, true);

For this one I simply used expose-loader so you'll have to have that in your dev dependencies.

@stof
Copy link
Member

stof commented May 22, 2018

this is now much simpler since 2.2: symfony/webpack-encore#97 (comment)

@stof stof closed this as completed May 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants