webpack으로 매번 npx webpack
(또는 npm run dev
)로
변경사항이 있을 때 마다 빌드해줘야하는것이 번거롭다고 생각했다.
cra(create-react-app)에 내장된 hot-reload 기능을 구현할 수 있다고 해서
강좌대로 따라해보았다.
react-refresh
와 @pmmmwh/react-refresh-webpack-plugin
설치$ npm i react-refresh @pmmmwh/react-refresh-webpack-plugin -D
dev-server
설치$ npm i -D webpack-dev-server
"scripts": {
"dev": "webpack serve --env development"
},
const RefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
plugin을 require로 불러온 후, 변수로 저장함.
plugins: [new ReactRefreshWebpackPlugin()]
저장한 변수를 new 변수명으로 plugin에 설정함.
output: {
path: path.join(__dirname, "dist"),
filename: "[name].js",
publicPath: "/dist",
},
📌 [name].js 의 의미는?
filename: "[name].js" 과 같이 해놓으면,
output 되는 파일 이름이 entry 프로퍼티에서 설정한 각각의 key 값의 이름으로 등록이 된다.
4-2. babel-loader 설정 변경
module: {
rules: [
{
test: /\.jsx?$/,
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
targets: { browsers: ["last 2 chrome versions"] },
debug: true,
},
],
"@babel/preset-react",
],
plugins: ["react-refresh/babel"], // 👈 이부분 추가 - babelloader의 플러그인
},
exclude: path.join(__dirname, "node_modules"), // 👈 이부분 추가 - node_modules 폴더는 제외하라는 뜻
},
],
},
📌 loader VS plugin
Loaders (rules) Plugin 번들이 생성되는 동안이나 생성되기 전에 개별 파일 수준에서 작업 번들이 생성 된 후에 작동함
📌 .과 __dirname의 차이
__dirname . 현재 실행중인 스크립트가 있는 폴더 작업 디렉토리(=root)
📂 수정 전
const path = require("path");
const RefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
module.exports = {
name: "wordrelay-setting",
mode: "development", // 실서비스에선 'production'으로
devtool: "eval", // 빠르게
resolve: {
extensions: [".js", ".jsx"],
},
entry: {
app: ["./client"],
},
module: {
rules: [
{
test: /\.jsx?/,
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
plugins: ["react-refresh/babel"],
},
},
],
},
plugins: [new RefreshWebpackPlugin()],
output: {
path: path.join(__dirname, "dist"), //__dirname은 현재폴더경로
filename: "app.js",
publicPath: '/dist/',
},
devServer: {
static: {
directory: path.join(__dirname, "dist"),
},
hot: true,
},
};
📂 수정 후
const path = require("path");
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
module.exports = {
name: "word-relay-dev",
mode: "development",
devtool: "inline-source-map",
resolve: {
extensions: [".js", ".jsx"],
},
entry: {
app: "./client",
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
targets: { browsers: ["last 2 chrome versions"] },
debug: true,
},
],
"@babel/preset-react",
],
plugins: ["react-refresh/babel"],
},
exclude: path.join(__dirname, "node_modules"),
},
],
},
plugins: [new ReactRefreshWebpackPlugin()],
output: {
path: path.join(__dirname, "dist"),
filename: "[name].js",
publicPath: "/dist",
},
devServer: {
devMiddleware: { publicPath: "/dist" },
static: { directory: path.resolve(__dirname) },
hot: true,
},
};