使用webpack5搭建react开发环境

2,624 阅读4分钟

序言

平时在开发项目的时候,都是直接使用脚手架来创建项目的,为了了解其中环境的配置,同时也是想实践一下webpack的应用,所以这次想要用webpack来搭建一个简单的react开发环境。

开始

webpack简单实践

我们先来简单的实践一下webpack的打包过程,首先初始化项目,并下载webpack和webpack-cli。

npm init -y
yarn add webpack webpack-cli -D

依照下图所示,创建项目的目录结构

image.png

webpack在打包的时候有自己默认的配置,若项目根目录存在webpack.config.js文件,则会根据文件中的配置来进行打包,当然我们也可以指定配置文件的路径。我们先在该文件中写一些基础的配置。

webpack.config.js

const path = require('path')
module.exports = {
  // 有development模式和production模式两种
  mode'development',
  // 打包的入口文件地址
  entry: path.resolve(__dirname, './src/index.js'),
  output: {
    // 打包输出文件名称
    filename'bundle.js',
    // 打包输出地址
    path: path.resolve(__dirname, './dist'),
    // 清除之前的打包文件
    cleantrue
  }

}

src/index.js

console.log('webpack')

public/index.html

<!DOCTYPE html>
<html>
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
    </head>
    <body>

      <script src="../dist/bundle.js"></script>
    </body>
</html>

打开package.json文件,在scripts中添加一条脚本命令

image.png

这时候就可以执行yarn build命令进行打包了。下图就是打包后的目录结构,webpack依照配置把打包结果输出到了dist目录下的bundle.js文件中。

image.png

之前在scr/index.js中写了一行测试代码,并在public/index.html中引入了打包后的文件,我们现在打开浏览器看一下控制台的输出。

image.png

可以看到测试代码成功的执行了,到现在为止已经完成了webpack最简单的实践。下面就开始接着搭建react的开发环境。

react的打包

下载react和react-dom,然后在src/index.js中编写react代码。

yarn add react react-dom

src/index.js

import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
  render() {
    return (
      <div>
        react
      </div>
    )
  }
}
ReactDOM.render(
  <App />,
  document.getElementById('root')
)

public/index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <!-- 添加react的容器 -->
  <div id="root"></div>
  
  <script src="../dist/bundle.js"></script>
</body>
</html>

因为react中使用了jsx语法,所以需要用babel-loader把jsx解析成webpack可以识别的内容。下载babel-loader以及babel相关的包,

yarn add @babel/core @babel/preset-env babel-loader @babel/preset-react -D

webpack.config.js

const path = require('path')
module.exports = {
  // 有development模式和production模式两种
  mode'development',
  // 打包的入口文件地址
  entry: path.resolve(__dirname, './src/index.js'),
  output: {
    // 打包输出文件名称
    filename'bundle.js',
    // 打包输出地址
    path: path.resolve(__dirname, './dist'),
    // 清除之前的打包文件
    cleantrue
  },
  module: {
    rules: [
      {
        // 对项目中.js结尾的文件,使用babel-loader进行转义处理
        test/\.js$/,
        loader'babel-loader',
        // 排除node_modules
        exclude/node_modules/
      }
    ]
  }
}

在根目录新建.babelrc文件

.babelrc

{
  "presets": ["@babel/preset-env""@babel/preset-react"]
}

重新打包项目查看一下结果

image.png

可以看到我们编写的react组件已经成功渲染到页面上了,接下来给组件添加样式。

css和scss的打包

这里使用scss来写样式,同时为了避免类名的冲突,使用css模块化的方式引入样式。

yarn add sass -D

在src下新建index.scss文件

src/index.scss

body {
  .content {
    color: red;
  }
}

index.js中引入该样式文件

src/inedx.js

import React from 'react'
import ReactDOM from 'react-dom'
import styles from './index.scss'
class App extends React.Component {
  render() {
    return (
      <div className={styles.content}>
        react 
      </div>
    )
  }
}
ReactDOM.render(
  <App />,
  document.getElementById('root')
)

webpack打包css或scss需要用到对应的loader

yarn add style-loader css-loader sass-loader -D

webpack.config.js

...
{
  test/\.(css|scss)$/,
  use: [
    "style-loader",
    {
      loader"css-loader",
      options: {
        // 开启css模块化
        modulestrue
      }
    },
    "sass-loader"
  ]
}

再重新打包,如下图所示可以看到样式已经成功添加。

image.png

打包过程优化

html-webpack-plugin

现在bundle.js文件是我们手动引入的,我们可以借助html-webpack-pllugin插件来优化这个过程,该插件会自己生成一个html文件并把打包好的文件自动引入。

yarn add html-webpack-plugin -D

webpack.config.js

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  ...
  plugins: [
    new HtmlWebpackPlugin({
      // 以public/index.html文件为模板
      template: path.resolve(__dirname, './public/index.html'),
      // 生成文件的名称
      filename'index.html'
    })
  ]
}

public/index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>

如下图所示,重新打包之后在dist目录自动生成了一个html文件,且文件中自动引入了打包后的文件。

image.png

webpack-dev-server

现在每次修改代码之后都需要重新打包,并且要手动刷新浏览器才能看到修改后的结果。我们可以使用webpack-dev-server在本地开启一个服务器,修改代码保存之后,会自动重新打包并刷新浏览器。

yarn add webpack-dev-server -D

在package.json中新增一个脚本命令

image.png

如下图所示,执行yarn dev命令在本地开启了8237端口,在浏览器中访问该地址就可以看到页面了。

image.png

当然也可以自己配置来决定开启哪个端口、是否开启热更新等等。我们试着将端口改为3000,注意修改配置文件之后需要重新执行一下yarn dev

webpack.config.js

module.exports = {
  ...
  devServer: {
    port3000,
    hottrue
  }
}

图片资源

webpack5中asset module可以处理图片、文字等资源,不需要依赖loader进行打包。

webpack.config.js

...
{
  test/\.(png|svg|jpg|jpeg|gif)$/i,
  type"asset",
  parser: {
    dataUrlCondition: {
      // 模块小于 maxSize,会被作为Base64编码的字符串注入到包中, 
      // 否则模块文件会被生成到输出的目标目录中
      maxSize1 * 1024
    }
  },
  generator: {
    filename'assets/img/[name].[hash:6][ext]'
  }
}

在src目录下放一张图片,我们试着在组件中引用这张图片。

src/index.js

import React from 'react'
import ReactDOM from 'react-dom'
import styles from './index.scss'
import cat from './cat.jpeg'
class App extends React.Component {
  render() {
    return (
      <div className={styles.content}>
        <img src={cat}></img>
      </div>
    )
  }
}
ReactDOM.render(
  <App />,
  document.getElementById('root')
)

打开浏览器可以看到图片可以成功的显示了。

image.png