Why isn't Tailwind CSS connecting in my react app? - reactjs

I am attempting to install tailwind (Which I have done many times before with no issue). Please help me with what I am missing this time around.
tailwind.config.js
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Package.json
....
"devDependencies": {
.....
"autoprefixer": "^10.4.2",
"postcss": "^8.4.6",
"tailwindcss": "^3.0.23"
},
....
index.js
import './index.css'
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(<App />, document.getElementById('root'))
app.js
const App = () => {
return <div className='bg-blue-300'>
cool
</div>
}
And lastly (where I believe my problem is)
index.css
#tailwind base;
#tailwind components;
#tailwind utilities;
body{
background-color: red; /* I WORK FYI! */
}
(EDIT) A bit more info: This app is the 'example-app' generated after running using create-react-library. I just created a brand new react app, installed TW, and had no problems. I also installed another package into my example-app (react-icons) just to test that wasn't the issue but that works as expected.

Do you start the Tailwind CLI build process?
npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch

Related

Absolute path not working in Vite project React TS

I'm struggling to get absolute path to work in a Vite react-ts project.
Here's how I created the project
npm init #vitejs/app
npx: installed 6 in 1.883s
√ Project name: ... test-vite
√ Select a framework: » react
√ Select a variant: » react-ts
Then I added baseUrl to tsconfig.json
based on the TS official doc:
{
"compilerOptions": {
"baseUrl": "./src",
...
followed by adding a simple component (T:\test-vite\src\components\Test.tsx)
import React from "react";
const Test = () => <h1>This is a Test.</h1>;
export default Test;
Finally I import the Test component in App.tsx
but it won't let me use absolute path:
import Test from "components/Test";
I get this error
whereas if I use relative path, the app works in dev & build mode without any error:
import Test from "./components/Test";
How can I make absolute path work in the project?
There are two problems here:
Tell typescript how to resolve import path
Tell vite how to build import path
You only tell typescript how to resolve, but vite don't konw how to build. So refer to the official document resolve.alias, maybe this is what you want:
// vite.config.ts
{
resolve: {
alias: [
{ find: '#', replacement: path.resolve(__dirname, 'src') },
],
},
// ...
}
You can import path like this (or any module under ./src):
import Test from "#/components/Test";
import bar from "#/foo/bar"
Moreover, you can use vite plugin vite-tsconfig-paths directly, it makes you don't have to manually configure resolve.alias
Follow the instructions below:
Install vite-tsconfig-paths as dev dependency
Inject vite-tsconfig-paths using the vite.config.ts module
import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
plugins: [tsconfigPaths()],
})
I came here through search results, I was looking for something different, namely, how to do a simple absolute import like import { foo } from 'src/lib/foo.ts'
So if you have a /src directory that contains all code and want to use an absolute import path.
vite.config.ts
export default defineConfig({
...
resolve: {
alias: {
src: path.resolve('src/'),
},
}
})
tsconfig.json
{
"compilerOptions": {
...
"baseUrl": "./"
}
}
Note that this is a trick: src is an alias, so it appears like the path is absolute in Vite. If you have another directory in the root dir, adjacent to /src, you will need to add another alias for that directory.
#Yuns solutions works, but it shows error in vscode. And it was breaking auto-import in vs code.
To make it work in vscode and vite both, I added alias in both tsconfig and vite.config.
// tsconfig.json
{
"paths": {
"#/*": ["src/*"]
}
// ...
}
// vite.config.ts
{
resolve: {
alias: [{ find: '#', replacement: '/src' }],
},
// ...
}
Then, I could import like below (svelte app is in src directory)
import Header from '#/components/Header.svelte
Looking for import {...} from "src/foo/bar";?
I also came here through search results like user Maciej Krawczyk, but the # part also wasn't what I was interested in. That user's answer helped me, but I had trouble with the path.resolve part (ReferenceError because path wasn't defined), so I used a slightly different approach:
vite.config.ts
export default defineConfig({
...
resolve: {
alias: {
src: "/src",
},
},
...
})
Vite's resolver considers the absolute path /src to be from where the server is serving (see GH issue). So if you're running/building from the root of your project with src as a top level directory -- which is pretty common -- this alias points Vite in the right direction.
tsconfig.json
{
"compilerOptions": {
...
"baseUrl": "./",
"paths": {
"src/*": [
"./src/*"
]
}
}
}
This is basically blindly following this StackOverflow answer. TypeScript needs to know that we have special resolving going on as well, otherwise TS will be freaked out about your non-existent src package and not know where it should go looking. (Note: After I changed my TS config, VSCode didn't immediately pick up the change, so I was still getting warnings. I quit, re-opened, and had to wait ~15sec for the warnings to go away.)
1) You need to install these packages:
npm i path
yarn add path
npm i #types/node
yarn add #types/node
npm i vite-tsconfig-paths
yarn add vite-tsconfig-paths
2) Then in the vite.config file:
import { defineConfig } from 'vite';
import react from '#vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';
import path from 'path';
export default defineConfig({
base: './',
resolve: {
alias: {
Components: path.resolve(__dirname, './src/components'),
Assets: path.resolve(__dirname, './src/assets'),
},
},
plugins: [react(), tsconfigPaths()],
});
3) And now we have to tell TS those same paths that we defined in the alias:
{
"compilerOptions": {
...,
"baseUrl": "./",
"paths": {
"src/*": [ "./src/*" ],
// We define this path for all files/folders inside
// components folder:
"Components/*": [ "./src/components/*" ],
// We define this path for the index.ts file inside the
// components folder:
"Components": [ "./src/components" ],
"Assets/*": [ "./src/assets/*" ],
"Assets": [ "./src/assets" ]
}
},
...
}
4) reload vscode: As the comment above said, press Fn1 and type "reload with extensions disabled", re-enabling extensions from the popup.
Now try to import
import Test from "components/Test";
it should work.
For anyone looking specifically to add the nice import "#/something-in-src" syntax like Vue has with the latest (as of posting this answer) version of Vite + React + TypeScript, here's how I did it:
Make sure #types/node is installed as a dev dependency. This didn't come with the latest version of Vite for me, and it will make "path" and __dirname throw an undefined error.
vite.config.ts
import { defineConfig } from "vite";
import react from "#vitejs/plugin-react";
import path from "path";
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: [{ find: "#", replacement: path.resolve(__dirname, "src") }],
},
plugins: [react()],
});
tsconfig.json
Add:
{
"compilerOptions": {
"paths": {
"#/*": ["./src/*"]
}
}
}
For anyone who stucks after all required changes, you need to reload vscode.
My config files:
tsconfig.json
"baseUrl": "./",
"paths": {
"#/*": ["src/*"]
}
vite.config.ts
import { defineConfig } from 'vite';
import react from '#vitejs/plugin-react';
import path from 'path';
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: { '#': path.resolve(__dirname, './src') },
},
plugins: [react()],
});
In above code you need to have 2 libraries installed:
'path': npm i path
'#types/node': npm i #types/node
After configure your project files you need to reload vscode. To do that press ctrl + P and type ">reload with extensions disabled", after that you will get popUp to activate extensions again click it, and your absoulte path should work
If someone installed vite-tsconfig-paths library, you also need to reload the vscode, remember to import given library to vite.config.ts
export default defineConfig({ plugins: [react(), tsconfigPaths()] });
With package you get default 'components/File' import instead of '#components/File' import.

How to optimize React app bundle size using rollup.js

I am trying to use rollup.js to bundle my react app. And i realized the bundle .js file is bigger than compiled with create-react-app.
How can I solve this. I just discovered rollup.js last two weeks and love it. I need help to get this done.
I tried with options I found on the net by creating peerDev in package.json like below
"peerDependencies": {
"react": ">= 16.x.x",
"styled-jsx": ">= 3.x.x"
}
and then with this line "external: id => /^react|styled-jsx/.test(id)," in rollup.config.js. I realized this has to do with react components only but not bundling for react app even though it did reduce the file size drastically. The page doesn't run when compiled that way
This is the rollup config file without the peerDependencies reference
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import livereload from "rollup-plugin-livereload";
import { terser } from "rollup-plugin-terser";
import replace from "rollup-plugin-replace";
//import pkg from "./package.json";
const production = !process.env.ROLLUP_WATCH;
const NODE_ENV = process.env.NODE_ENV;
export default [
{
input: "src/index.js",
output: {
name: "bundle",
file: "dist/main.js",
format: "iife"
},
"process.env": {
NODE_ENV: JSON.stringify("production")
},
plugins: [
replace({
"process.env.NODE_ENV": JSON.stringify(NODE_ENV)
}),
babel({
exclude: "node_modules/**"
}),
resolve(),
commonjs(),
!production && livereload("dist"),
production && terser()
],
globals: {
react: "React"
},
watch: {
clearScreen: false
}
}
];
And this is just the simple react code.
import ReactDOM from 'react-dom';
ReactDOM.render(<h3>React with Rollup</h3>,document.getElementById('root'));
After compilation. This is the file size I get 961K. This should be smaller. Becuase, with much bigger applications, the file sizes are far smaller than this. Prompt help will be very much appreciated

React project using parcel bundler instead of Webpack

We can start with React project using command create-react-app. But when we use this command we don't get idea about how it's bundle and pack all types of files using Webpack.
So I tried to build react app without create-react-app command using Webpack 4 and Babel 7 and I succeed.
Now I want to do same app using parcel bundler. as I read on different blogs I got an idea that parcel is easy then web pack and it's truly zero configuration set up.
My project structure is
- src
|- components
|- styles
|- index.html
|- index.js
- package.json
This is simple project to start with parcel bundle so I've not add Redux or routing yet.
What I want to achieve is
1). As aspected React app should be run in browser using parcel bundler.
2). I want to use absolute paths when importing JS files.
3). I want to enable hot reloading.
After few minutes of research on net I find the solution and it's truly zero configuration with parcel bundler.
we just need to add 2 commands in package.json file 's script section.
project structure is
- src
|- components
|- styles
|- index.html
|- index.js
|- App.js
- package.json
- .babelrc // this file will use to setup absolute path when import files
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from './App';
import "./style/index.scss";
ReactDOM.render(<App />, root);
index.html is same file as create-react-app provide we just need div with id.
App.js
import React, { Component } from "react";
import Count from "#components/Count"; // here I used absolute path. check .bablerc file
export default class App extends Component {
render() {
return (
<>
<div>this is App component</div>
<Count />
</>
);
}
}
components/Count.js
import React, { Component } from "react";
export default class Test extends Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<>
count is: {this.state.count}
<br />
<button onClick={(prevState) => {this.setState({
count: prevState.count + 1
});
}}
>
Add count
</button>
</>
);
}
}
style/index.scss
body {
background-color: red;
color: #fff;
text-align: center;
font-size: 40px;
}
note that we don't need to manually install node-sass package to use
scss. parcel will handle for you.
package.json
{
"name": "react_parcel",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "parcel ./src/index.html",
"build": "parcel build ./src/index.html/"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"parcel-bundler": "^1.12.3",
},
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6"
}
}
.bablerc
{
"plugins": [
[
"module-resolver",
{
"root": ["./src"],
"alias": {
"#components": "./src/components"
}
}
],
["react-hot-loader/babel"]
]
}
here we add alias for components folder so when we need to import any file from components folder we don't need to write relative path.
npm run dev
your server will start on localhost:1234
I solved 2 issues but still need to figure out how to use hot reloading so if you guys have any idea related hot reloading please answer it.
for production build: npm run build

How to get postcss-nesting and #vue/cli pwa working?

How is it possible to get postcss-nesting and a #vue/cli v3 project built with the PWA plugin working?
So far I've tried
npm install postcss-nesting
I then created a src/main.css which contains
body {
h1 {
color: green;
}
}
Inside the main.js file I import the css import './main.css';
Then inside the postcss.config.js I've added it to the plugins (with others that work) e.g.
module.exports = {
plugins: {
'postcss-import': {},
'postcss-nesting': {},
}
}
When I then run npm run serve the CSS does not transform into body h1 as you can see
What would be the correct way to get this working?
Thanks
Nesting should be enabled inside package.json since vue-cli does not read the configuration from postcss.config.js or .postcssrc.js as mentioned here.
"postcss": {
"plugins": {
"autoprefixer": {},
"postcss-preset-env": {
"browsers": "last 2 versions",
"features": {
"nesting-rules": true,
"custom-media-queries": true,
"color-mod-function": true
}
}
}
},
Working example on this repository: https://github.com/dobladov/vue-cli-example-postcss
Also for the nesting is important to use the symbol &
<style>
body {
background-color: tomato;
& .foo {
color: purple;
}
}
</style>

Jest not preprocessing my JSX

I am following the Jest tutorial to test a react component and am running into preprocessing issues with my jsx. I assume the error is due to preprocessing, the error message is not very helpful. Googling shows similar errors with older versions of react/jest that were fixed by including the /** #jsx React.DOM */ docblock which as far as I can tell was fixed.
When I run my test:
Using Jest CLI v0.8.0, jasmine1
FAIL spec/MyComponent_spec.js
Runtime Error
SyntaxError: /Users/asdf/react/stuff-react/spec/MyComponent_spec.js: Unexpected token (13:6)
npm ERR! Test failed. See above for more details.
The line in question is the one that should be rendering my component:
jest.dontMock('../src/MyComponent');
let React = require('react');
let ReactDOM = require('react-dom');
let TestUtils = require('react-addons-test-utils');
const MyComponent = require('../src/MyComponent');
describe('MyComponent', function(){
it('render', function(){
var myComponent = TestUtils.renderIntoDocument(
// This is the line referenced in the test error
<MyComponent />
)
var myComponentNode = ReactDOM.findDOMNode(myComponent);
expect(myComponentNode.textContent).toEqual('hi');
});
});
I thought my package.json was responsible for telling jest to preprocess that file?
"scripts": {
"test": "jest"
},
"jest": {
"testDirectoryName": "spec",
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react",
"<rootDir>/node_modules/react-dom",
"<rootDir>/node_modules/react-addons-test-utils",
"<rootDir>/node_modules/fbjs"
]
},
My component:
import React from 'react';
class MyComponent extends React.Component({
render () {
return (
<div>
hi
</div>
)
}
});
export default MyComponent;
Using a .bablerc file in the project root directory fixed it for me.
I was not using a .babelrc file while developing because I defined my presets in the webpack configuration file. But it turns out that when you run the unit test with jest, then jest is not aware of this presets as it does not know about webpack. So simply adding a .babelrc file with the presets should solve the issue for you too.
Contents of .babelrc:
{
"presets": ["es2015", "react"]
}
I had a similar problem, and the solution was adding this to jest config file:
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.jsx$": "babel-jest" // This line was missing
}
The reason it was needed in our project, is because we overridden the default "transform" value in jest config file.
I think you may just need to add the testFileExtensions and testFileExtensions to the jest section of your package.json.
See the README.md of babel-jest:
https://github.com/babel/babel-jest
Changing my .babelrc config file to babel.config.js or babel.config.json worked for me because Jest ignores .babelrc.
Add ["#babel/preset-react", { runtime: "automatic" }] to the presets in babel.config.js.
Your babel.config.js file should look something like:
module.exports = {
presets: [
["#babel/preset-env", { targets: { node: "current" } }],
"#babel/preset-typescript",
["#babel/preset-react", { runtime: "automatic" }],
],
};
And you need to set your jest environment to jsdom by adding this to the top of your test (make sure you've installed the jest-environment-jsdom node package):
/**
* #jest-environment jsdom
*/

Resources