从零搭建简易版React脚手架

220 阅读1分钟

起步

  1. mkdir demo创建目录
  2. npm init -y创建package.json
  3. main:"index.js"替换为private:true

webpack配置

  1. yarn add webpack webpack-cli --dev安装webpack依赖
  2. mkdir config创建目录,新建文件webpack.config.js

react配置

  1. yarn add react react-dom安装react依赖
  2. 创建src/index.jsx文件
import React from "react";
import ReactDom from "react-dom";

ReactDom.render(
    <h1>hello world</h1>,
    document.getElementById("root")
);
  1. 创建public/index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="root"></div>
  <script src="../dist/bundle.js"></script>
</body>
</html>
  1. yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react安装babel依赖
  2. 新建.babelrc文件
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}
  1. webpack.config.js内容
const path = require('path');

module.exports = {
  entry: "./src",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, '../dist'),
  },
  mode: "development",
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: "babel-loader", // 转为es5
      },
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx'], // 模块引入后缀
  }
};
  1. package.json添加build
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config config/webpack.config.js"
  },
  1. 完成基本功能,yarn build打包构建,将生成dist/bundle.js。打开public/index.html,这里我使用live-server会出现Uncaught SyntaxError: Unexpected token '<'错误;正常打开则不会。

typescript配置

  1. yarn add typescript @types/react @types/react-dom @babel/preset-typescript
  2. .babelrc配置
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react",
+    "@babel/preset-typescript"
  ]
}
  1. webpack配置
resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'], // 模块引入后缀
},
  1. 根目录下添加tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react"
  },
  "include": [
    "src"
  ]
}

less配置

  1. yarn add style-loader css-loader less-loader less --dev安装所需依赖
  2. webpack配置添加以下内容
{
    test: /\.css$/,
    use: ["style-loader", "css-loader"]
},
{
    test: /\.less$/,
    use: ["style-loader", "css-loader", "less-loader"]
}

其他配置

  1. yarn add html-webpack-plugin --dev用于在打包时自动生成html,webpack配置如下:
const HotModuleReplacementPlugin = require('webpack').HotModuleReplacementPlugin;

plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '../public', 'index.html') // 使用模版
    }),
],
  1. yarn add webpack-dev-server --dev用于热更新
// webpack.config.js
const HotModuleReplacementPlugin = require('webpack').HotModuleReplacementPlugin;

plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '../public', 'index.html') // 使用模版
    }),
+    new HotModuleReplacementPlugin()
],

devServer: {
    contentBase: path.resolve(__dirname, '../dist'),
    hot: true,
    port: 3000,
    open: true,
    historyApiFallback: true, // 解决BrowserRouter 404
}

// package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config config/webpack.config.js",
+    "start": "webpack-dev-server --config config/webpack.config.js"
},
  1. yarn add file-loader用于解析字体和图片
{
    test: /\.(eot|svg|ttf|woff|woff2)$/,
    loader: 'file-loader'
},
{
    test: /\.(png|jpe?g|gif)$/i,
    loader: "file-loader"
},