Okay, time to actually put something together. It doesn't have to be much, but it has to be decent and help me learn more about TWCSS
As of right now, all the jsx I've done is in the main index.tsx
file. I'm going to move that out to its own file. Because I'm building my homepage and I expect to build other pages, I'll follow some of the Next.js project structure and create a /src/pages
folder.
Inside of that, I'll create my home.tsx
file and copy in what I'm currently rendering in <App />
:
import Headshot from '../assets/headshot.jpg';
export const HomePage = () => {
return (
<div className="bg-gray-900">
<h1 className="text-slate-100">MatDupont.dev</h1>
<h2 className="bg-blue-800 text-slate-400">Waddup, Mataverse?</h2>
<div className="mx-auto max-w-sm space-y-2 rounded-xl bg-white py-8 px-8 shadow-lg sm:flex sm:items-center sm:space-y-0 sm:space-x-6 sm:py-4">
<img
className="mx-auto block h-24 rounded-full sm:mx-0 sm:shrink-0"
src={Headshot}
alt="Mat's headshot"
/>
<div className="space-y-2 text-center sm:text-left">
<div className="space-y-0.5">
<p className="text-lg font-semibold text-black">Mat Dupont</p>
<p className="font-medium text-slate-500">Senior Engineer</p>
</div>
<button
type="button"
className="rounded-full border border-purple-200 px-4 py-1 text-sm font-semibold text-purple-600 hover:border-transparent hover:bg-purple-600 hover:text-white focus:outline-none focus:ring-2 focus:ring-purple-600 focus:ring-offset-2"
>
Message
</button>
</div>
</div>
</div>
);
};
Then, I update the index.tsx
:
...
import { HomePage } from './pages/home';
function App() {
return <HomePage />;
}
...
Looks like some tweaks are in order! This looks like a mix of eslint rules, a sprinkle of typescript config and a dash of webpack.
The first thing I'll tackle is the "'React' must be in scope when using JSX" issue. Mostly because it takes the most space and I want to feel productive tonight.
First, I'll silence this rule.
.estlintrc.js
...
rules: [
...
'react/react-in-jsx-scope': 'off',
]
Looking better...ish.
The linter isn't complaining, but this still aren't working.
I know I can squash this error by simply importing React. But it's 2022 and I know this isn't a hard necessity. I just need to configure typescript to do this for me.
*I will likely import React myself throughout this codebase to use the React.FC
type or some hooks, but that's not the point!
This one took a few minutes to figure out. It seems this new 'sans-React-import' functionality came with React 17 along with some new jsx
factories for TypeScript. Read more
The tsconfig.json
compilerOptions.jsx:
value needed a small adjustment:
Before:
"jsx": "react"
After:
"jsx": "react-jsx"
Getting there!
Now, I don't like default exports. Maybe it's a personal thing. But, I've dealt with too many codebases where the default export gets renamed wrong and things end up all confusing 3 months later.
Export with a name, import by name. That's my preference. Renaming as I destructure from the import is one thing, but I want to be deliberate if I do it.
TLDR; I'm getting rid of the import/prefer-default-export
rule.
.estlintrc.js
...
rules: [
...
'import/prefer-default-export': ['off'],
]
The remaining issues have to do with an inability to resolve the path to my new component from the index.tsx
As it turns out, the eslint-config-airbnb
rule set has a TypeScript counterpart.
yarn add -D eslint-config-airbnb-typescript
.eslintrc.js
...
extends: ['plugin:react/recommended', 'airbnb', 'airbnb-typescript', 'prettier'],
...
No more editor warnings!
But the browser, now... 🤬
At least I'm getting some instructions, right?!
I already have parserOptions defined in my .eslintrc.js
file though. It's what parses all my js. I'll need an override specific to ts/tsx
files:
...
overrides: [
...
{
files: ['**/*.ts', '**/*.tsx'],
parser: '@typescript-eslint/parser',
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json',
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
warnOnUnsupportedTypeScriptVersion: true,
},
},
],
...
Here, I'm telling eslint to use the @typescript-eslint/parser
for my .tsx?
files using the tsconfig.json
file for the project, a module
sourceType and jsx
support. I also want it to throw a warning for unsupported TypeScript versions.
Reload and... uuuhhh.
Check the browser console.
Still with the React import issue!?
Here's where that dash of Webpack comes in!
The ProvidePlugin is what we want.
webpack.common.config.js
const { HotModuleReplacementPlugin, ProvidePlugin } = require('webpack');
...
plugin: [
...
new ProvidePlugin({
React: 'react',
}),
]
...
Reload again and I'm back in business!