Chapters
43 Chapters
|
5:00:38
|
This course is archived!
While the concepts of this course are still largely applicable, it's built using an older version of Symfony (4) and React (16).
Login to bookmark this video
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.2.0
Subscribe to download the code!Compatible PHP versions: ^7.2.0
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
08.
Build the Static App First
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
While the concepts of this course are still largely applicable, it's built using an older version of Symfony (4) and React (16).
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.2.0",
"ext-iconv": "*",
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // v1.8.0
"doctrine/doctrine-bundle": "^1.6", // 1.9.1
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.3
"doctrine/doctrine-fixtures-bundle": "~3.0", // 3.0.2
"doctrine/doctrine-migrations-bundle": "^1.2", // v1.3.1
"doctrine/orm": "^2.5", // v2.7.2
"friendsofsymfony/jsrouting-bundle": "^2.2", // 2.2.0
"friendsofsymfony/user-bundle": "dev-master#4125505ba6eba82ddf944378a3d636081c06da0c", // dev-master
"phpdocumentor/reflection-docblock": "^3.0|^4.0", // 4.3.0
"sensio/framework-extra-bundle": "^5.1", // v5.2.0
"symfony/asset": "^4.0", // v4.1.4
"symfony/cache": "^3.3|^4.0", // v4.1.4
"symfony/console": "^4.0", // v4.1.4
"symfony/flex": "^1.0", // v1.21.6
"symfony/form": "^4.0", // v4.1.4
"symfony/framework-bundle": "^4.0", // v4.1.4
"symfony/lts": "^4@dev", // dev-master
"symfony/monolog-bundle": "^3.1", // v3.3.0
"symfony/polyfill-apcu": "^1.0", // v1.9.0
"symfony/property-access": "^3.3|^4.0", // v4.1.4
"symfony/property-info": "^3.3|^4.0", // v4.1.4
"symfony/serializer": "^3.3|^4.0", // v4.1.4
"symfony/swiftmailer-bundle": "^3.1", // v3.2.3
"symfony/twig-bundle": "^4.0", // v4.1.4
"symfony/validator": "^4.0", // v4.1.4
"symfony/yaml": "^4.0", // v4.1.4
"twig/twig": "2.10.*" // v2.10.0
},
"require-dev": {
"easycorp/easy-log-handler": "^1.0.7", // v1.0.7
"symfony/debug-bundle": "^3.3|^4.0", // v4.1.4
"symfony/dotenv": "^4.0", // v4.1.4
"symfony/maker-bundle": "^1.5", // v1.5.0
"symfony/phpunit-bridge": "^4.0", // v4.1.4
"symfony/stopwatch": "^3.3|^4.0", // v4.1.4
"symfony/var-dumper": "^3.3|^4.0", // v4.1.4
"symfony/web-profiler-bundle": "^3.3|^4.0", // v4.1.4
"symfony/web-server-bundle": "^4.0" // v4.1.4
}
}
What JavaScript libraries does this tutorial use?
// package.json
{
"dependencies": {
"@babel/plugin-proposal-object-rest-spread": "^7.12.1" // 7.12.1
},
"devDependencies": {
"@babel/preset-react": "^7.0.0", // 7.12.5
"@symfony/webpack-encore": "^0.26.0", // 0.26.0
"babel-plugin-transform-object-rest-spread": "^6.26.0", // 6.26.0
"babel-plugin-transform-react-remove-prop-types": "^0.4.13", // 0.4.13
"bootstrap": "3", // 3.3.7
"copy-webpack-plugin": "^4.4.1", // 4.5.1
"core-js": "2", // 1.2.7
"eslint": "^4.19.1", // 4.19.1
"eslint-plugin-react": "^7.8.2", // 7.8.2
"font-awesome": "4", // 4.7.0
"jquery": "^3.3.1", // 3.3.1
"promise-polyfill": "^8.0.0", // 8.0.0
"prop-types": "^15.6.1", // 15.6.1
"react": "^16.3.2", // 16.4.0
"react-dom": "^16.3.2", // 16.4.0
"sass": "^1.29.0", // 1.29.0
"sass-loader": "^7.0.0", // 7.3.1
"sweetalert2": "^7.11.0", // 7.22.0
"uuid": "^3.2.1", // 3.4.0
"webpack-notifier": "^1.5.1", // 1.6.0
"whatwg-fetch": "^2.0.4" // 2.0.4
}
}
8 Comments
I think In th end of the tutorial we gonna delete all the twig files ? can we use a template engine with react?
Hey ahmedbhs!
Great question! The answer is a bit more interesting than a yes/no :).
First, yes, by the end of the tutorial, we will delete all of the *markup* from our Twig template that is now being rendered by React. But we will not completely delete your Twig templates.
Second, you can of course create a pure single-page-app with React. In this case, you wouldn't need any Twig templates. Well, maybe you would just render one Twig template that has some basic markup... but that would be it (React would render everything else). Or, you can create a more traditional multi-page app (SymfonyCasts is a good example of this) where *some* parts of your app use React. In that case, you would render a Twig template that, for example, rendered most of the markup for your page. But, in *one* spot on the page, you would just have an empty div. Then, React would build everything inside this div.
This is actually what we'll do in this tutorial. By the end, we will still have a traditional (no React) login page. And, on the "main" page, the header/layout will still be done by Twig, as well as the leaderboard on the right. Only the table/form part will be done by React. So basically, you can do everything in Twig or everything in React or any mixture in between :).
Cheers!
Hey guys!
The dev-server really speeds up the workflow, but I have a problem with it. My webpack.json has this entry:
Dev-server seems to erase the build directory, including build/static, so I have no static assets on my page. Am I missing something in my webpack.json?
Hey Dan_M!
Yea, thw dev-server is great, once you figure out how it works (it was a little "weird" for me at first not to see my compiled assets - eventually I realized that they're generated automatically).
Anyways, I can't remember the exact behavior with dev-server and CopyWebpackPlugin. But, I think I know the issue. I believe that plugin, like all of Webpack itself, does not physically copy the files when you're in dev-server. Instead, if you make a request to the dev-server - e.g. http://localhost:8080/build/static/myfile.png - and it dynamically returns that to you. I'm not 100% sure about this, but I believe that the plugin works this way (it should).
The problem then, is that, in your templates, you're final HTML probably just looks like
&t;img src="/build/static/myfile.png">, which means your requesting that file from your local, PHP server - not from the dev-server URL. In theory, if you're using theasset()function, that corrects things: it looks in manifest.json and sees that the URL needs the dev-server hostname in front of it. However, due to bad behavior with CopyWebpackPlugin, static assets are not included in manifest.json... and then we're all sad :(.So, let me tell you 2 things:
1) If you remove the
cleanupOutputBeforeBuild()call (which is not as important with dev-server anyways), you can probably work around this by running a normal build first, then doing dev-server. Kinda lame, but there you go.2) In the upcoming/next release of Encore (0.21.0), we will have a new
copyFile()method that works like the CopyWebpackPlugin, but correctly puts things into the manifest.json file. This should be the real solution.Let me know if that makes sense! Or if I'm totally wrong! :)
Cheers!
weaverryan,
I used your "kinda lame" workaround and, of course, that worked for assets rendered with twig. Without the cleanupOutputBeforeBuild() call, all of my static assets were still there and were called as I would expect.
However, when I rendered an asset in React, it did not work using something like this:
But if I change the img tag to
it works just fine.
Of course, that's not a solution. So, I'm still stuck.
Beyond that, your solution #2 sounds good, but I don't see how that works in React. Is there a jsx equivalent to asset() I should be using?
Hey Dan_M!
Oh, oh oh! You're doing something WAY more awesome than what I was thinking! You're referencing an asset from JavaScript! Brilliant! Just do this:
That's it! You don't even need the copy plugin. Webpack natively (well, when you tell it what to do, which Encore does) knows how to require image files. By requiring the image file, it will move it into the build directory and will return back the final path. This is actually the proper way to render image paths :).
Let me know if this make sense!
Cheers!
weaverryan,
That works!
In my case, the render function was in a form class, so it looked like:
Perhaps simpler is to just do:
In either case, it took me a minute to realize the path in the require statement is relative to the javascript source file, not the build directory.
Thanks!
Dan
Hey Dan_M
Yep, you are correct, the require function points to where the file lives. I'm glad to hear that your code is working again. Cheers!
"Houston: no signs of life"
Start the conversation!