πŸ“œ ⬆️ ⬇️

How to just make friends Symfony2 and RequireJS on the example of SPA

There was already a publication that demonstrated how to use Symfony2 and RequireJS using the HearsayRequireJSBundle bundle. The way is the place to be, I know from the first row, because I was directly involved in the development of the second version of this bundle. However, I do not use this bundle. The client part is often developed as a SPA and found a simpler way, and it will be discussed.

The main idea of ​​the method is to place the client-side sources in a public directory accessible from the Web. In symfony2, this is the web directory. As a result, without any problems, you can very easily configure the r.js optimizer, you only need to explain Symfony2 how to give the source code to the client side depending on the environment of the application and write a fairly simple config for r.js optimizer.

We will use Bower to install the necessary JavaScript dependencies and gulp.js ( Grunt is possible, but I like gulp.js more) to build the client part, so we will need the installed Node.js and NPM.

We assume that Bower and gulp.js are already installed, now we need to add configuration files for them, put them in the root of the project:
')
bower.json

{ "name": "symfony-standard-requirejs", "private": true, "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "almond": "0.3.0", "requirejs": "2.1.15", "rjs": "2.1.15" } } 

Above, we indicated that we need almond (lightweight AMD loader for prod environments, replacement for RequireJS), RequireJS and r.js optimizer.

package.json

 { "name": "symfony-standard-requirejs", "private": true, "dependencies": { "gulp": "3.8.8", "yargs": "1.3.2" } } 

Above, we indicated that we need gulp.js and yargs.

gulpfile.js

 var gulp = require('gulp'), exec = require('child_process').exec, argv = require('yargs').argv; gulp.task('copy', function () { // almond gulp.src('bower_components/almond/almond.js') .pipe(gulp.dest('web/app/vendor/almond')); // requirejs gulp.src('bower_components/requirejs/require.js') .pipe(gulp.dest('web/app/vendor/requirejs')); // rjs gulp.src('bower_components/rjs/dist/r.js') .pipe(gulp.dest('.')); }); gulp.task('rjs', function (cb) { var env = argv.env ? argv.env : 'dev', cmd = [ 'php app/console cache:clear --env=' + env, 'php app/console assets_version:increment --env=' + env, 'php app/console assetic:dump --env=' + env, 'node r.js -o web/app/app.build.js' ]; exec(cmd.join(' && '), function (err, stdout, stderr) { console.log(stdout); console.log(stderr); cb(err); }); }); gulp.task('build', ['copy', 'rjs']); gulp.task('default', ['build']); 

Above we have indicated the following tasks:


Now we need to install the necessary Node.js packages and JavaScript dependencies, run the following commands for this:

 npm install bower install 

The main preparatory work is over. It remains to explain Symfony2 how to give the source code to the client side depending on the application environment and write a fairly simple config for the optimizer r.js. We do this as follows:

src / AppBundle / Resources / views / Default / index.html.twig

 {% extends "AppBundle::layout.html.twig" %} {% block javascripts %} {% if app.environment == 'prod' %} <script src="{{ asset('app/dist/main.js') }}"></script> {% else %} <script>var require = {urlArgs: 'bust=' + (new Date()).getTime()};</script> <script data-main="app/main" src="{{ asset('app/vendor/requirejs/require.js') }}"></script> {% endif %} <script> requirejs.config({ config: { 'src/config': { user: { id: 1, username: 'John Doe' } } } }); </script> {% endblock %} 

It should be noted here that the client part has some structure in the file system and in order to have fewer questions, I will write about it briefly. The sources are located in the public web directory, namely in the web / app directory, which has the following structure:

 β”œβ”€β”€ app.build.js β”œβ”€β”€ dist β”‚  └── .gitkeep β”œβ”€β”€ main.js β”œβ”€β”€ specs β”‚  └── .gitkeep β”œβ”€β”€ src β”‚  β”œβ”€β”€ app.js β”‚  └── config.js └── vendor 

Add config for RequireJS

web / app / main.js

 requirejs.config({ baseUrl: 'app' }); require([ 'src/app', 'src/config' ], function (App, config) { App.start(config); }); 

Add config for optimizer r.js

web / app / app.build.js

 ({ baseUrl: '.', mainConfigFile: 'main.js', wrapShim: true, name: 'vendor/almond/almond', include: 'main', out: 'dist/main.js', findNestedDependencies: true, preserveLicenseComments: false }) 

In the file example.build.js you can read more about each parameter.
Let's write a simple Hello application:

web / app / src / app.js

 define([ ], function () { 'use strict'; var App = {}; App.start = function (config) { console.log('Hello, ' + config.user.username + '!'); }; window.App = App; return App; }); 

web / app / src / config.js

 define([ 'module' ], function (module) { 'use strict'; return module.config(); }); 

Symfony2 may require additional edits in the controller, in the example I am using Symfony Standard Edition.
Open the main application page in the browser, the message β€œHello, John Doe!” Should appear in the browser console.

To build the client for the prod environment, add the following command to the deployment:

 npm install bower install gulp build --env=prod 

Also, don't forget to add the following lines to .gitignore:

 /bower_components/ /node_modules/ /web/app/dist/ /web/app/vendor/ /r.js 

Done!

PS In the symfony-standard repository on GitHub you can find an example of this Hello application.

Source: https://habr.com/ru/post/245911/


All Articles