create-react-appを使わずにReactの環境構築
まっさらの状態からReactを使ってブラウザで「Hello World」を表示する
※npmではなくyarn
なのでyarn init
でlockファイルを作成
Webpack
yarn add -D webpack webpack-cli webpack-dev-server html-webpack-plugin dotenv-webpack
babel
yarn add -D @babel/core @babel/runtime @babel/plugin-transform-runtime @babel/preset-env babel-loader
React
yarn add react react-dom
yarn add -D @babel/preset-react
Typescript
yarn add -D typescript @babel/preset-typescript @types/react @types/react-dom
CSS系
yarn add style-loader css-loader
tsconfig.jsonの作成
yarn run tsc --init
{
"compilerOptions": {
"typeRoots": ["types", "node_modules/@types"],//pngの型がないとエラーが起きるので後付け
"jsx": "react",
"target": "ES2021",
"lib": [
"ES2021",
"dom"
] ,
/* Modules */
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true ,
/* Emit */
"outDir": "./dist",
"noEmit": true,
"downlevelIteration": true,
/* Interop Constraints */
"isolatedModules": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true ,
/* Type Checking */
"strict": true,
"noImplicitAny": true ,
"strictNullChecks": true ,
"strictFunctionTypes": true ,
"strictBindCallApply": true ,
"strictPropertyInitialization": true ,
"noImplicitThis": true ,
"useUnknownInCatchVariables": true ,
"alwaysStrict": true ,
"noUnusedLocals": true ,
"noUnusedParameters": true ,
"exactOptionalPropertyTypes": true ,
"noImplicitReturns": true ,
"noFallthroughCasesInSwitch": true ,
"noUncheckedIndexedAccess": true ,
"noImplicitOverride": true ,
"noPropertyAccessFromIndexSignature": true ,
"allowUnusedLabels": true ,
"allowUnreachableCode": true
},
"exclude": ["node_modules"],
"include": ["src/**/*"]
}
png型エラーしないように自作
src > typesフォルダ > index.d.ts
declare module "*.png"
declare module "*.jpeg"
webpack.config.jsの作成
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const Dotenv = require("dotenv-webpack");
module.exports = {
mode: "development",
entry: path.resolve(__dirname, "./src/index.tsx"), // 始まるところ
output: {
path: path.resolve(__dirname, "dist"), // distを本番環境
filename: "index.js", // jsに変換
},
resolve: {
modules: [path.resolve(__dirname, "node_modules")],
extensions: [".ts", ".tsx", ".js", ".css"],
},
module: {
rules: [
{
test: [/\.ts$/, /\.tsx$/],
use: [
{
loader: "babel-loader",
options: {
presets: [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript",
],
plugins: ["@babel/plugin-transform-runtime"], // fetchを使いたかったができなかったため後から追加した
},
},
],
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
exclude: /src/,
},
{
test: /\.png/,
type: "asset/resource",
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "./src/index.html"),
}),
new Dotenv(),
],
devServer: {
port: 8111, // サーバー側とPORTが被らないように指定
static: {
directory: path.join(__dirname, "dist"),
},
historyApiFallback: true,
host: "0.0.0.0",
allowedHosts: "all",
},
};
index.htmlの作成
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>タイトル</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
※src > index.html
index.tsxの作成
import React from "react"
import ReactDOM from "react-dom"
import App from "./app"
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root"),
)
※src > index.tsx
app.tsx
import React from "react"
const App = () => <h1>Hello World</h1>
export default App
※src > app.tsx
最後に
- package.jsonのscriptsに
"start": "npx webpack serve --config webpack.config.js"
を書き込む yarn start
- ブラウザで
http://localhost:8111
にアクセスする
Hello Worldが表示される!
参考記事