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:
Typescript MVC Pattern in a private typescript directory:
src > XBundle > Resources > private > typescript
Javascript bundles compiled in :
src > XBundle > Resources > public > js
the private directory should consist of multiple apps for different pages. (If an app requires it's own tsconfig.json
file, that's fine)
an app is simply (for example) home.app.ts that imports (for example) a search.component.ts and a chat.component.ts
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
In the public > js
folder, there should only be x.bundle.js
files
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
)
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.
Good tools are only good if you use them, luckily the TypeScript APIs are open and are be used by many editors. In the case of PHP, many developers are used to using PHPStorm from JetBrains. Out of the box the IDE offers integration with TypeScript that also manages the compilation.
Webpack Encore is a simpler way to integrate Webpack into your application. It wraps Webpack, giving you a clean & powerful API for bundling JavaScript modules, pre-processing CSS & JS and compiling and minifying assets. Encore gives you professional asset system that's a delight to use.
ts-loader: convert typescript (es6) to javascript (es6) babel-loader: converts javascript (es6) to javascript (es5) and Typescript doesn't do polyfills , which babel does. If you write client-side code in es6 and want it to run on modern browsers, you'd probably need babel 's polyfills .
TypeScript is a syntactic superset of JavaScript which adds static typing. This basically means that TypeScript adds syntax on top of JavaScript, allowing developers to add types. TypeScript being a "Syntactic Superset" means that it shares the same base syntax as JavaScript, but adds something to it.
I ended up using webpack for this to work. Props to @zerkms. This is a work in progress, and could be better optimized.
Go to src > XBundle > Resources > private > typescript
npm init -y
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
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"
]
}
Type webpack
in the directory where webpack.config.js
resides.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With