《Webpack5 核心原理与应用实践》学习笔记-> React全栈环境

简介: 《Webpack5 核心原理与应用实践》学习笔记-> React全栈环境


搭建react开发环境为全新环境,这里只讲搭建react环境,不再包含lesscss等,只要不使用这些东西一样可以构建出来,因为这些之前都有讲过,再写就有点凑字数和废话,好学的可以看历史章节。


搭建react环境



这次搭建为从零开始,不包含开发环境,而且直接跳过.jsx,直接使用.tsx


  • 新建一个项目(就是目录),随便取个名字。
  • npm init -y生成一个package.json
  • 初始化webpack,命令行npm i -D webpack webpack-cli
  • 根目录下创建webpack.config.js,内容如下


const path = require("path");
module.exports = {
    mode: "production",
    entry: './src/index.tsx',
    output: {
        filename: "[name].js",
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /.tsx$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                '@babel/preset-env',
                                [
                                    '@babel/preset-react',
                                    { pragma: 'createElement' },
                                ],
                            ],
                        },
                    },
                    { loader: 'ts-loader' },
                ],
            },
        ]
    },
    resolve: {
        extensions: ['.tsx'], // 这个可以让webpack默认入口的文件类型(.js/.json/.wasm)新增额外类型
    }
}

从上面的配置可以看到我们要安装解析.tsx的配置,需要安装很多依赖,babel-loader@babel/preset-env@babel/preset-reactts-loader等。


  • 安装babelnpm i -D babel-loader @babel/core @babel/preset-env
  • 安装ts: npm i -D typescript ts-loader
  • 安装babelreact的支持:npm i -D @babel/preset-react @babel/plugin-transform-react-jsx
  • 安装react: npm i react(这里没有加-D,因为react是要放在生产环境中的,但是课程中都是有-D的,而且确实加不加都能构建出来,都能运行)


上面的依赖就是目前recat环境所需要的全部依赖了,如果你还需要使用css,实际项目中是一定需要的,就需要安装解析css的相关依赖了,还需要加上对应的配置,这个之前章节讲过了,就没有相关的代码和演示。


  • 新建tsconfig.json配置,内容如下


{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true,
    "jsx": "react"
  },
  "exclude": [
    "node_modules"
  ]
}

  • 新建src目录
  • src下面新建index.tsx,内容如下


import React from 'react';
const Component = () => {
  return <div className="hello">hello world</div>
}

  • 运行npx webpack构建项目,可以看到会生成dist目录


可以增加一个html-webpack-plugin生成.html文件,用来查看构建出来的内容是否正确,也可以增加一个webpack-dev-server试试开发环境和热更新效果。


以上就完成了对react环境的搭建


react服务端渲染


Vue服务端渲染时已经介绍过服务端渲染的概念,所以这里略过。 recat服务端渲染和Vue类似,所以目录结构都是一样的,还是还是用一个新的工程来记录。


  • 创建react-ssr目录
  • npm init -y生成package.json
  • 根目录下新建src目录
  • src下面新建entry-client.tsx,内容如下
import { createRoot } from 'react-dom/client';
import App from './App';
const container = document.getElementById('app');
const root = createRoot(container);
root.render(<App />);

  • src下面新建entry-server.tsx,内容如下


import React from 'react'
import App from './App'
import { renderToString } from 'react-dom/server';
export default () => {
    return renderToString(<App/>);
}

  • src下面新建App.tsx,内容如下


import React, { useState } from 'react';
import './App.css';
const App = () => {
    const [isActivity, setIsActivity] = useState(false);
    const handleClick = () => {
        setIsActivity(!isActivity);
    };
    return (
        <div>
            <h3 className={`main ${isActivity ? 'activate' : 'deactivate'}`}>Hello World</h3>
            <button onClick={handleClick}>Toggle</button>
        </div>
    );
};
export default App;

  • src下面新建App.css,内容如下


h3 {
    color: #42b983;
}
.main {
    padding: 20px 12px;
    transition: background 0.3s linear;
}
.activate {
    background: #000;
}
.deactivate {
    background: #fff;
}

上面已经完成了对react的页面构建,这一块和Vue的服务端渲染很相似,接下来就是对webpack的配置

  • 根目录下新建webpack.base.js,内容如下


module.exports = {
    mode: "production",
    module: {
        rules: [
            {
                test: /.tsx$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                '@babel/preset-env',
                                [
                                    '@babel/preset-react',
                                    { pragma: 'createElement' },
                                ],
                            ],
                        },
                    },
                    { loader: 'ts-loader' },
                ],
            },
        ]
    },
    resolve: {
        extensions: ['.js', '.jsx', '.tsx'],
    }
}

上面的配置就是上面讲react环境的配置,没想到这么快就用上了,而且还是作为基础配置来使用的。


  • 根目录下新建webpack.client.js(客户端文件生成的webpack配置),内容如下


const Merge = require("webpack-merge");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
const base = require("./webpack.base");
// 继承自 `webpack.base.js`
module.exports = Merge.merge(base, {
    entry: {
        // 入口指向 `entry-client.js` 文件
        client: path.join(__dirname, "./src/entry-client.tsx"),
    },
    output: {
        filename: 'index.js',
        publicPath: "/",
    },
    module: {
        rules: [{ test: /.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"] }],
    },
    plugins: [
        // 这里使用 webpack-manifest-plugin 记录产物分布情况
        // 方面后续在 `server.js` 中使用
        new WebpackManifestPlugin({ fileName: "manifest-client.json" }),
        // 生成CSS文件
        new MiniCssExtractPlugin({
            filename: 'index.[contenthash].css'
        }),
        // 自动生成 HTML 文件内容
        new HtmlWebpackPlugin({
            templateContent: `
    <!DOCTYPE html>
    <html>
    <head>
  <meta charset="utf-8">
  <title>Webpack App</title>
    </head>
    <body>
  <div id="app" />
    </body>
    </html>
  `,
        }),
    ],
});

  • 根目录下新建webpack.server.js(服务端文件生成的webpack配置),内容如下


const Merge = require("webpack-merge");
const path = require("path");
const base = require("./webpack.base");
module.exports = Merge.merge(base, {
    entry: {
        server: path.join(__dirname, "./src/entry-server.tsx"),
    },
    target: "node",
    output: {
        // 打包后的结果会在 node 环境使用
        // 因此此处将模块化语句转译为 commonjs 形式
        libraryTarget: "commonjs2",
        filename: 'server.js'
    },
    module: {
        rules: [{
            test: /.css$/,
            loader: './loader/removeCssLoader'
        }]
    },
});

这里有一个细节,就是.cssloader是自己的写的,因为服务端只需要生成页面,不需要管css的生成,这里会写一个空的css-loader

  • 根目录下新建目录loader
  • loader目录下新建文件removeCssLoader.js,内容如下


module.exports = () => {
    return 'module.exports = () => null';
};

  • 根目录下新建tsconfig.json,内容如下


{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true,
    "jsx": "react-jsx"
  },
  "exclude": [
    "node_modules"
  ]
}

课程里面讲的js版本的,我这里实践是ts版本的,所以会多一点东西。


接下来就是构建项目了,可以使用npx webpack --config webpack.client.jsnpx webpack --config webpack.server.js分别构建出客户端资源和服务端资源,我这里还是将这两个命令放到了package.json文件中,如下


"scripts": {
  "build:client": "npx webpack --config ./webpack.client.js",
  "build:server": "npx webpack --config ./webpack.server.js",
},

接下来就可以使用npm run build:clientnpm run build:server来构建客户端和服务端资源了。


搭建node服务验证效果


这里还是和vue服务端渲染一样,使用express来作为服务端。


  • 在根目录下新建server.js,内容如下


const express = require('express');
// 通过 manifest 文件,找到正确的产物路径
const clientManifest = require("./dist/manifest-client.json");
const server = express();
server.get("/", (req, res) => {
    const html = require('./dist/server.js').default;
    const clientCss = clientManifest["client.css"];
    const clientBundle = clientManifest["client.js"];
    res.send(`
<!DOCTYPE html>
<html>
    <head>
      <title>React SSR Example</title>
      <link rel="stylesheet" href="${clientCss}"></link>
    </head>
    <body>
      <!-- 注入组件运行结果 -->
      <div id="app">${html()}</div>
      <!-- 注入客户端代码产物路径 -->
      <!-- 实现 Hydrate 效果 -->
      <script src="${clientBundle}"></script>
    </body>
</html>
    `);
});
server.use(express.static("./dist"));
server.listen(3000, () => {
    console.log("服务启动成功:http://localhost:3000");
});

接下来就可以运行node server.js来启动服务啦,但是为了方便我这里将所有的命令一站式封装到package.json中了,这里还是因为依赖太多,所以服务端渲染这一块没有讲依赖安装的环节,这里还是直接上package.json


{
  "name": "react-ssr",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build:client": "npx webpack --config ./webpack.client.js",
    "build:server": "npx webpack --config ./webpack.server.js",
    "server": "node ./dist/server.js",
    "run": "npm run build:client && npm run build:server && node server.js",
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.18.10",
    "@babel/plugin-transform-react-jsx": "^7.18.10",
    "@babel/preset-env": "^7.18.10",
    "@babel/preset-react": "^7.18.6",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "express": "^4.18.1",
    "html-webpack-plugin": "^5.5.0",
    "mini-css-extract-plugin": "^2.6.1",
    "ts-loader": "^9.3.1",
    "typescript": "^4.7.4",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0",
    "webpack-manifest-plugin": "^5.0.0",
    "webpack-merge": "^5.8.0"
  }
}

现在可以使用npm run run来一站式构建客户端、服务端资源和启动服务啦,瑞思拜。


总结


没什么好总结的,今天不上课程里面的总结了,Vue的服务端渲染是直接对着课程来的,很顺利。

react的服务端渲染对着课程来报错了,不是因为我使用ts版的问题,是构建出来的资源无法运行,后来将架构改成和Vue版一致的就好了。


使用ts版的也是个人的拓展练习,准备webpack学完就深入ts了。


课程中建议这些东西不要自己折腾,可以直接使用比较成熟的Create React App,当然使用归使用,练习和学习还是自己来,这样就可以知其然且知其所以然。


示例代码:react-ssr


目录
相关文章
|
1月前
|
JSON 缓存 前端开发
【React】React原理面试题集锦
本文集合一些React的原理面试题,方便读者以后面试查漏补缺。作者给出自认为可以让面试官满意的简易答案,如果想要了解更深刻,可以点击链接查看对应的详细博文。在此对链接中的博文作者非常感谢🙏。
35 0
|
3月前
|
存储 资源调度 前端开发
React原理 即 React路由基础
React原理 即 React路由基础
51 1
|
2月前
|
Web App开发 JSON 前端开发
Webpack【搭建Webpack环境、Webpack增加配置文件、Webpack中使用Loader、Webpack分离CSS文件 】(一)-全面详解(学习总结---从入门到深化)
Webpack【搭建Webpack环境、Webpack增加配置文件、Webpack中使用Loader、Webpack分离CSS文件 】(一)-全面详解(学习总结---从入门到深化)
53 0
|
17天前
|
前端开发 JavaScript 算法
React原理
【4月更文挑战第4天】本文介绍了React的核心概念,包括jsx、React.createElement和fiber。jsx是React的语法糖,被转换为React.createElement生成虚拟DOM (vDOM)以优化性能。vDOM是轻量的数据结构,用于描述DOM状态。React通过fiber结构改进渲染性能,将同步任务拆分成小任务,利用requestIdleCallback在浏览器空闲时执行,确保流畅的用户体验。fiber是增强的vDOM,包含额外的引用指针。文章还提及了diff算法和hooks在React中的作用。
9 0
|
1月前
|
运维 JavaScript 前端开发
发现了一款宝藏学习项目,包含了Web全栈的知识体系,JS、Vue、React知识就靠它了!
发现了一款宝藏学习项目,包含了Web全栈的知识体系,JS、Vue、React知识就靠它了!
|
1月前
|
前端开发 JavaScript 容器
前端vw自适应解决方案,适用pc端以及移动端,适用webpack以及vite,适用vue以及react
前端vw自适应解决方案,适用pc端以及移动端,适用webpack以及vite,适用vue以及react
71 0
|
1月前
|
前端开发
React学习笔记(一)
React学习笔记(一)
|
1月前
|
前端开发
React学习笔记
React学习笔记
|
2月前
|
前端开发 JavaScript
前端框架React原理
前端框架React原理
30 0
|
2月前
|
前端开发 JavaScript API
介绍一下React Router的工作原理。
介绍一下React Router的工作原理。
31 5