9

Question:

How do I set up Typescript with Symfony with the minimum amount of configurations changes to Symphony’s configuration files?

Here are the points that this solution should solve:

  1. Typescript MVC Pattern in a private typescript directory:

    src > XBundle > Resources > private > typescript

  2. Javascript bundles compiled in :

    src > XBundle > Resources > public > js

  3. the private directory should consist of multiple apps for different pages. (If an app requires it's own tsconfig.json file, that's fine)

  4. an app is simply (for example) home.app.ts that imports (for example) a search.component.ts and a chat.component.ts

  5. Compiled "apps" should be located in the public > js repository mentioned in point (2) and should be named (example taken from point (4)) home.bundle.js

  6. In the public > js folder, there should only be x.bundle.js files

  7. Adding the bundles to my twig files, and calling my view should immediately run the bundle. I should not have to add an extra script to call the "module" (this is the reason why I want to avoid AMD / System )

What I'm not looking for:

I'm not looking for a solution with react and angular but a general solution using the /web directory (or even the Resources directory in a bundle) at the root of a symfony project.

Most articles regarding this talk about symfony2 and try integrating react and angular.

I'm not looking for an installation tutorial for npm and tsc.

I don't need an automatic compile. I use Phpstorm so it does it automatically anyway.

kemicofa ghost
  • 14,587
  • 5
  • 63
  • 112
  • Not sure if it is too much but you could use gulp/grunt (or any other tool than you like) to have a proper frontend architecture. It rely on separating backend and frontend architecture but I don't see any other solutions – goto Apr 05 '17 at 15:17
  • I'm using webpack with symfony applications (and it's smooth), not sure why you're trying to avoid it. "I just want to dev, and spend less time configuring something." --- if you cannot configure it, how do you know it would take less than configuring webpack? – zerkms Apr 16 '17 at 08:25
  • I do not change symfony at all: bundles built by webpack are loaded via ` – zerkms Apr 18 '17 at 07:22
  • I seriously cannot understand what you want to see: the webpack config is entirely separate to symfony. You just setup it as if it was a non-php single static page application with only JS. Then you put it on the page with ` – zerkms Apr 18 '17 at 07:31
  • 1
    @zerkms for some reason, what you said made things logical and I found a simple solution with webpack. Thank you. Seems to be working great. – kemicofa ghost Apr 19 '17 at 07:11

1 Answers1

3

I ended up using webpack for this to work. Props to @zerkms. This is a work in progress, and could be better optimized.

Installation:

  1. Install webpack, I personally installed it globally. (Unsure how to configure Phpstorm to use webpack, there doesn't seem to be a direct built in system for it)
  2. Go to src > XBundle > Resources > private > typescript

  3. npm init -y

  4. Install the dev dependencies: npm install --save-dev awesome-typescript-loader and npm install --save-dev typescript

Side note:

@Morgan Touverey Quilling, recommends installing webpack locally, your choice:

npm install --save-dev webpack

Configuration:

Here is my folder structure:

├── XBundle/
│   ├── Controller
│   ├── Resources
│   │   ├── config
│   │   ├── private
│   │   │   ├── typescript
│   │   │   │   ├── components
│   │   │   │   │   ├── auth
│   │   │   │   │   │   ├── auth.component.ts
│   │   │   │   │   ├── search
│   │   │   │   │   │   ├── search.component.ts
│   │   │   │   ├── services
│   │   │   │   │   ├── http.service.ts
│   │   │   │   ├── node_modules
│   │   │   │   ├── package.json
│   │   │   │   ├── webpack.config.js
│   │   │   │   ├── tsconfig.json
│   │   ├── public
│   │   │   ├── js
│   │   │   │   ├── build
│   │   │   │   │   ├── auth.bundle.js

webpack.config.js This config could probably be simplified much further.

For every bundle, a new config should be created pointing to the main file. Remember to rename the output bundle.

There shouldn't be more than one bundle per page. If you need (for example) the auth.bundle.js and the search.bundle.js on the home page, you should probably create a home.component.ts that uses auth.component.ts and search.component.ts and create a config in webpack.config.js to create the home.bundle.js

const path = require('path');

//Common configurations
let config = {
    module: {
        loaders: [
            { test: /\.ts$/, loader: 'awesome-typescript-loader' }
        ]
    },
    resolve: {
        extensions: ['.ts']
    }
};

//Copy and paste this for as many different bundles
//as required
let authConfig = Object.assign({}, config, {
    entry: path.join(__dirname, 'components/auth','auth.component.ts'),
    output: {
        path: path.join(__dirname, '../../public/js/build'),
        filename: 'auth.bundle.js',
        library: 'XApp'
    }
});

//Add each config here.
module.exports = [
    authConfig
];

tsconfig.json

{
  "compileOnSave": true,
  "compilerOptions": {
    "sourceMap": true,
    "moduleResolution": "node",
    "lib": ["dom", "es2015", "es2016"]
  },
  "exclude": [
    "node_modules"
  ]
}

Run

Type webpack in the directory where webpack.config.js resides.

Adding JS to your Twig file

Somewhere in one of your templates.

{% block javascripts %}
    {# More stuff here #}
    {% javascripts
    '@XBundle/Resources/public/js/build/auth.bundle.js'
    %}
    {# More stuff here #}
    {% endjavascripts %}
{% endblock %}

And run the following commands for any new bundles.js created for the first time in the root directory of your symfony project:

php bin/console assets:install
php bin/console assetic:dump
kemicofa ghost
  • 14,587
  • 5
  • 63
  • 112
  • 1
    A few notes : - You could use Webpack 2, Webpack 1 is used here. - You can avoid code repetition in the different config chunks (wasn't that the goal of Object.assign?) - You can replace Object.assign with the _object spread operator_ (http://redux.js.org/docs/recipes/UsingObjectSpreadOperator.html) - You may prefer to use `const` instead of `let`. - It's better to have a tsconfig.json, Webpack overrides TS behaviour concerning where the files get compiled, etc, but some other configuration keys may be useful. Right now you are just using the default configuration provided with TS. – Morgan Touverey Quilling Apr 19 '17 at 15:13
  • 1
    Also, you could generate that documentation automatically, by scanning the folders, looking for components, since their configuration always have the same structure. – Morgan Touverey Quilling Apr 19 '17 at 15:14
  • 1
    A last note : Installing Webpack globally is bad :( Prefer to have it into your dev deps, then use an npm script called, for example, "build", so you can run `yarn build` or `npm run`, so your team and future coworkers all have the same Webpack version and the same way to invoke it. – Morgan Touverey Quilling Apr 19 '17 at 15:16
  • 1
    Apart that, that's a neat solution to use TS/Webpack inside of a classic Symfony full-stack project =) – Morgan Touverey Quilling Apr 19 '17 at 15:17
  • 1
    This is very similar to what I have (up to using `Resources/private`), but I have a project, not bundle-specific webpack config. So my single webpack config builds assets for all symfony bundles. – zerkms Apr 20 '17 at 08:40
  • @zerkms what are the benefits to your method compared to mine? Is your package.json / tsconfig.json / webpack.config.js at the root of your directory? Since finding my solution, the question has been bugging me. I'm very curious. – kemicofa ghost May 03 '17 at 13:13
  • @rugdealer I don't think it's more beneficial, it's just different :-) I just like that it's a single configuration per project. – zerkms May 04 '17 at 01:42