Ruby on Rails, TailwindCSS and React very slow compile times - reactjs

I am trying out RoR for an upcoming project and have hit an interesting snag with the tools I am trying to use. The project was setup using rails new app --database postgresql --webpack react which worked great for quickly embedding react into the app.
Where I find issue is when I try and add TailwindCSS to the mix, it works, but it is EXTREMELY slow. 1 line changes in react code are triggering full webpack recompiles which are taking upwards of 40-50 seconds per refresh which just isn't viable.
I have looked around and even tried to implement TailwindCSS JIT which was a headache in itself but also did not fix my issue. I also could not find anything really specific around my exact configuration (react and tailwind) and how to fix this particular issue.
Here is my config:
// app/javascript/packs/application.js
import Rails from "#rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "#rails/activestorage"
import "channels"
import "stylesheets/application" // I have tried with and without this...
Rails.start()
Turbolinks.start()
ActiveStorage.start()
// app/javascript/stylesheets/application.css
#import "tailwindcss/base";
#import "tailwindcss/utilities";
#import "tailwindcss/components";
// app/views/layouts/application.html.erb
...
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= stylesheet_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'index' %>
</head>
...
Is there somewhere I can place the application.css import so it doesn't compile everytime I make a change in react?
Thanks in advance.

I use this gem on my project https://github.com/rails/tailwindcss-rails
the tailwind.css is included https://github.com/rails/tailwindcss-rails/blob/main/app/assets/stylesheets/tailwind.css
and will purge unused css on production env

Related

When I try to rename a favicon in a react project to "favicon.ico" the icon changes to react logo

before renaming
After renaming same file
without naming the file "favicon.ico" is there any other option to add favicon to a react project ?
This is a problem that can occur when in development. When building the project, it will load at the new favicon. If that doesn't work the case may be with browser cookies, try erasing your cookies and then the new favicon will show.
Check all the modules being loaded in your client app and see if any are importing the logo:
import logo from '../logo.svg';
Your default favicon might be being overridden by the React things

How on earth do I get react to actually work on a web server - just keep getting loads of errors - mainly from Babel

I've been playing with react for a while now and it seems quite good. I managed to get React working on my home computer easily enough using NPM to install it and then running npm start and it seems to work.
However if I upload the files it created with npm to my webhost (ecohosting) all I seem to get is some message about "require is not defined" in the console. I've tried searching for the answer and all I get is something about having to change the module settings.
I've also tried creating my own stand alone version of react just using a load of CDN links to both babel and react and am getting the same response.
This is my code I've tried :-
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js'></script>
<script>
{
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['#babel/preset-env']
}
}
}
]
}
}
</script>
</head>
<body>
<div class="app">
</div>
<script type="text/babel">
import React from 'react';
import ReactDOM from 'react-dom';
const test = (
<h1>
This test works
</h1>
);
ReactDOM.render(test, document.getElementById('app'));
</script>
</body>
</html>
I can't believe I started playing with React thinking it looked quite exciting and new - but I can't find any clear instructions on how to actually set the thing up to render. I normally use PHP and jQuery but thought I'd give React a go but so far it seems too overly complicated to get it working, more than jQuery or even PHP (jQuery you just add the jQuery CDN and you're done - with this React you need all this extra Babel included and the instructions for doing this on anything other than your home computer seems extremely vague). Am I just missing something really stupidly simple here or is React only designed for things like web apps and not for HTML use??
Do I need to do something with npm like build it before uploading or do I need to run start from something like the web hosts CLI (which my web host doesn't give me access to SSH).
I am also PHP developer who landed up with react so i understand the confusion. As you correctly guessed we need to first build the project and then upload that to the server. React is mainly used to create Single Page applications. If you want to play around with React you could use Create React App which includes all these configurations. Then use services like netlify and vercel for easy deployments.
To be perfectly honest i havent used the CDN approach so not sure about that part

How to make SVG build files from a React app available in a SilverStripe 4 page layout?

I have a React application called react-app nested in a page in my SilverStripe 4 project. Currently it appears in unusable form with none of the CSS styles working as expected and strange things happening to the SilverStripe layout for that particular page (e.g. an unscrollable banner filling entire page).
This question relates to a previous question I asked which received a great answer from Robbie Averill = (How to insert (inject?) an existing React app (just a UI without a backend) into a SilverStripe page layout?).
When I use the command npm run build to generate build files inside the react-app, there is a media build folder created containing files which are not JavaScript or CSS. How do I bring this build/static/media folder from inside react-app into my SilverStripe project? I can't use the Requirements class (of SilverStripe) as it only deals with JavaScript or CSS files.
The generated build folder paths and files are:
build/static/js:
- main.f8fcfe77.js
- main.f8fcfe77.js.map
build/static/css:
- main.417390ae.css
- main.417390ae.css.map
build/static/media:
- bottom_image_height_improved_enlarged.0242eccb.svg
- glyphicons-halflings-regular.448c34a5.woff2
- glyphicons-halflings-regular.89889688.svg
- glyphicons-halflings-regular.e18bbf61.ttf
- glyphicons-halflings-regular.f4769f9b.eot
- glyphicons-halflings-regular.fa277232.woff
- ic_cloud_download.0258cc94.svg
- ic_cloud_upload.6bf269d8.svg
- ic_help.bb8f97ab.svg
- ic_local_download.ddb824a7.svg
- ic_menu.7f39fb5c.svg
- ic_new.57667fef.svg
- ic_open.ddb824a7.svg
- ic_print.420fc2c5.svg
- ic_save.3fee4fd0.svg
- logo.d6c538c9.svg
- master_menu_cancel_btn.53591bb8.svg
Below shows the CircleAppPageController.php file using the init function and Requirements class to bring in the JavaScript and CSS files from the react-app build files. Note: react-app is nested inside the SilverStripe project app folder.
<?php
namespace SilverStripe\Lessons;
use SilverStripe\View\Requirements;
use PageController;
class ReactAppPageController extends PageController
{
protected function init()
{
parent::init();
// Requiring build files for react-app - Doesn't include media folder files!
Requirements::javascript('app/react-app/build/static/js/main.f8fcfe77.js');
Requirements::css('app/react-app/build/static/css/main.417390ae.css');
}
}
?>
Here is where I am wanting the react-app to appear in the layout of the ReactAppPage.ss (Note: ReactAppPage.php class extends Page.php class. The layout for Page.ss includes a simple navbar, header and footer which ReactAppPage.ss will inherit).
<% include Banner %>
<!-- BEGIN CONTENT -->
<div class="content">
<div class="container">
<div class="row">
<div class="main col-sm-8">
<div>
<div id="root">
I want the react-app with it's independent CSS stylings to appear here.
</div>
</div>
</div>
<div class="sidebar gray col-sm-4">
<% if $Menu(2) %>
<h3>In this section</h3>
<ul class="subnav">
<% loop $Menu(2) %>
<li><a class="$LinkingMode" href="$Link">$MenuTitle</a></li>
<% end_loop %>
</ul>
<% end_if %>
</div>
</div>
</div>
</div>
<!-- END CONTENT -->
Things I have tried:
1) If I only require the JavaScript build files the SilverStripe page layout doesn't break.
class ReactAppPageController extends PageController
{
protected function init()
{
parent::init();
Requirements::javascript('app/react-app/build/static/js/main.f8fcfe77.js');
}
}
On viewing the ReactAppPage I can see plain text for most of the react-app headings (not all). There are unstyled drop-down menus that I can interact with. This confirms that some React aspects are working, but the page is still unusable. Can SilverStripe themes CSS files override the CSS files coming from the react-app build files?
2) By copying the contents of the build/static/media folder inside the react-app and moving it to a static/media folder outside of my SilverStripe project, SilverStripe will find and run the files, but this does not change the onscreen result.
i.e. copying folder contents from:
www/my-silverstripe-project/app/react-app/build/static/media
to a newly created folder:
www/static/media
Expected Results:
On opening the SilverStripe page with the nested react-app, the page retains the correct SilverStripe styling and layout. The react-app would appear nested in the layout with correct styling (and working like it does when it runs independently of SilverStripe).
Thank you for your time reading my question. I am new to learning both React and SilverStripe and any responses will be greatly appreciated. My apologies if the question is confusing or badly worded. Thanks again :-).
I decided to delete the <% include Banner %> entirely from the page as this was behaving strangely. I couldn't just comment it out with HTML style comments because ReactAppPage.ss is a SilverStripe page and not true HTML.
I found out why SilverStripe runs commented out keywords. HTML style comments are still sent to the browser. I changed to SilverStripe comments <%-- --%>:
Research: SilverStripe3: Multiline comments in template
Now I can see the react-app as expected and working as expected.
Some other weird things happened to the SilverStripe CSS which meant the page was not scrolling like the others. The chrome dev tools in the browser allowed me to identify what the problems were happening on that page and then make adjustments to the code. I was able to reintroduce the banner with close to identical look to the other pages. Not the best solution as had to create a page specific banner with inline styles to override what was broken.
My continued problem is:
Finding the right place for the files in the media folder within the SilverStripe project (instead of outside the SilverStripe project at www/static/media).
Because I am following the SilverStripe lessons (which carve up a static website into a SilverStripe project) I am thinking some of these problems might be resolved by continuing the lessons. Any suggestions gratefully received.

How to debug typescript in angular-meteor

I followed the angular-meteor tutorial for the Socially app in Angular2. It basically works (after a few manual steps to fix package dependencies, etc), however, I am unable to debug the client side code in Chrome Dev Tools. When I navigate to the sources for my *.ts files, all I see are things like
module.export("default",exports.default=("<div> <ul> <li *ngFor=\"let party of parties\"> {{party.name}} <p>{{party.description}}</p> <p>{{party.location}}</p> </li> </ul> </div>"));
Other strange things in dev tools: my app.ts is blank. I see html files with !raw suffixes.... (e.g. app.html!raw). What is the !raw suffix and what causes that?
How can I debug my typescript?
I may be able to help with some parts of your question.
You don't mention which version of meteor you're using, but I assume version 1.4 or 1.4.0.1. I have seen that these versions of Meteor seem to have issues with sourcemaps for Typescript files (probably as they have to go through multiple transpilation steps).
I don't yet know where exactly the bug lies (Meteor or the Typescript compiler package).
Here's one github issue for this: https://github.com/barbatus/typescript/issues/23
UPDATE: This issue has now been fixed.
For now, my suggestion would be to try reverting to a 1.3.x.x version of Meteor. For something like the Socially tutorial, the easiest option is to specify the Meteor release at creation time:
$ meteor create --release 1.3.5.1 Socially
(list of releases is at: https://github.com/meteor/meteor/releases)
The 'app.html' and 'app.html!raw' files are generated by the meteor angular compilers as a way of working around issues with using templateUrl and the meteor build process. My understanding is that the preferred approach is to have inline templates or import the templates like this:
// This import loads the content of the html file into 'template'
import template from './app.html';
#Component({
selector: 'app',
// Instead of templateUrl, use:
template, // <--- 'template,' is syntactic sugar for: 'template: template,'
directives ... etc.
The import statement is a bit unusual, and this magic is achieved by the meteor angular pre-compiler that converts every html and css file into a couple of js files. That's what strange app.html and app.html!raw are.
The funny characters in the first app folder seem to be a bug. Meteor tries to generate put in a computer emoji, but sometimes this gets handled incorrectly. I'm not sure if this is a bug Chrome, ChromeDevTools or Meteor. (Personally, I wish they'd ditch the emoji).

ExtJS 4.2 - Ext.ux.Printer library/class does not work

Good day. Sorry but I've stumbled upon a problem that I can't seem to figure out for the past couple of hours. I downloaded this printing class to be able to print a Form that I have in my web application. I copied the Ext.ux.Printer folder in my scripts folder inside resources. The file path looks like: resources/scripts/Ext.ux.Printer and the resources folder is on the same level as the app folder.
My Loader looks like:
Ext.Loader.setConfig({
enabled: true,
paths: {
'Ext.ux.Printer': 'resources/scripts/Ext.ux.Printer/Printer'
}
});
And the Application looks like:
Ext.application({
requires: [
'Ext.Loader',
'Ext.layout.container.Absolute',
'resources.scripts.Notification',
'Ext.layout.container.Column',
'Ext.ux.Printer.Printer'
], //models, views, controllers, follow after
and I try to use it in my code as such:
Ext.ux.Printer.print(form);
However, I am given an Uncaught TypeError: Cannot read property 'Printer' of undefined whenever I try to execute the line of code above.
Can anyone help me? I'm a beginner in ExtJS4 and I'm just trying to follow examples I see around the internet - it is possible that I tried to appropriate my code incorrectly with something I saw online.
Any help is very much appreciated, thank you.
UPDATE 1
Upon discussion with Guilherme Lopes below we did the following steps:
Import the js files by adding it as a js resource in Sencha Architect. Make sure that the file path is correct.
Check the includeAfterAppJS checkbox. Due to a bug in Architect, sometimes the JS Files are added in before the ExtJS.
Open index.htmluse ext-all.js instead of ext-dev.js. Note that Sencha Architect overwrites/resets this file every time you save your project. A quick fix is to go to project settings and uncheck updating index.html.
Try Ext.ux.Print.print(form);
By the developer instructions, you should import the script files using your main html document, the same way you do with ExtJS classes (if you are not using the bootstrap).
These lines should be added after you import the ExtJS library:
<script type="text/javascript" src="Printer.js"></script>
<script type="text/javascript" src="renderers/Base.js"></script>
The library currently comes with renderers for Ext.grid.GridPanel, and Ext.tree.ColumnTree.
These can be included as required:
<script type="text/javascript" src="renderers/GridPanel.js"></script>
<script type="text/javascript" src="renderers/ColumnTree.js"></script>
And your calls to Ext.ux.Printer should start working.
If you are using Architect, add your external JS files clicking on: + => Resources => JS Resource
And then change the URL to the path you need (do this for every file you wish to add)
* I would just uncheck the x-compile and x-bootstrap

Resources