之前我总结过使用react-scripts如何通过env进行环境配置(原文),但是我们在打包的时候常用的是webpack。所以我针对webpack总结了一下如何使用env进行环境配置。

安装

首先我们需要安装相应的插件,我将我的package.json放在下面了,大家按需安装吧。

{
  "name": "react-remplate",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@babel/polyfill": "^7.12.1",
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "axios": "^0.21.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-scripts": "4.0.3",
    "web-vitals": "^1.0.1"
  },
  "scripts": {
    "start": "dotenv -e .env.development webpack-dev-server",
    "backserver": "dotenv -e .env.backserver webpack-dev-server",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@babel/cli": "^7.14.8",
    "@babel/core": "^7.15.0",
    "@babel/plugin-proposal-class-properties": "^7.14.5",
    "@babel/plugin-transform-runtime": "^7.15.0",
    "@babel/preset-env": "^7.15.0",
    "@babel/preset-react": "^7.14.5",
    "babel-loader": "^8.2.2",
    "clean-webpack-plugin": "^4.0.0-alpha.0",
    "css-loader": "^6.2.0",
    "dotenv-cli": "^4.0.0",
    "dotenv-webpack": "^7.0.3",
    "eslint": "^7.32.0",
    "eslint-plugin-prettier": "^3.4.1",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.3.2",
    "mockjs": "^1.1.0",
    "prettier": "^2.3.2",
    "sass": "^1.38.2",
    "sass-loader": "^12.1.0",
    "style-loader": "^3.2.1",
    "url-loader": "^4.1.1",
    "webpack": "^5.51.1",
    "webpack-cli": "^4.8.0",
    "webpack-command": "^0.5.1",
    "webpack-dev-server": "^4.0.0"
  }
}

这里的dotenv-clidotenv-webpack是实现环境配置的重点。

dotenv-cli是为了让webpack获取env的数据。
dotenv-webpack是为了让前端环境获取env的数据。

配置

在项目根目录创建环境文件.env.development.env.backserver,配置如下:

# .env.development
REACT_APP_ENV='development'
REACT_APP_MAIN_PATH='/mock'

REACT_APP_PORT='8088'

# .env.backserver
REACT_APP_ENV='backserver'
REACT_APP_PORT='8089'

在项目的根目录新建文件webpack.config.js,配置如下:

const path = require('path')
const webpack = require('webpack')
const HtmlPlugin = require('html-webpack-plugin')
// 重点在这里!
const Dotenv = require('dotenv-webpack')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const { env } = process

const config = {
  mode: env.REACT_APP_ENV,
  devtool: 'inline-source-map',
  entry: {
    index: './src/index.js'
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'build')
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [{ loader: 'style-loader' }, { loader: 'css-loader' }]
      },
      {
        test: /\.scss$/,
        use: [
          { loader: 'style-loader' },
          // sass可以使用module的方式引入了
          {
            loader: 'css-loader',
            options: { modules: true, importLoaders: 1 }
          },
          { loader: 'sass-loader' }
        ]
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: 'img/[name].[hash:7].[ext]'
        }
      },
      {
        test: /\.(js|jsx)$/,
        use: [
          {
            loader: 'babel-loader',
            options: { plugins: ['@babel/plugin-transform-runtime'] }
          }
        ],
        exclude: /node_modules/
      }
    ]
  },
  devServer: {
    port: env.REACT_APP_PORT
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new HtmlPlugin({
      template: 'public/index.html'
    }),
    // 重点在这里!
    new Dotenv({
      path: path.resolve(__dirname, `.env.${env.REACT_APP_ENV}`)
    }),
    // 全局引入插件
    new webpack.ProvidePlugin({ React: 'react', process: 'process/browser' }),
    new CleanWebpackPlugin()
  ]
}

if (env.NODE_ENV === 'backserver') {
  config['devServer'] = {
    ...config.devServer,
    overlay: {
      warnings: false,
      errors: true
    },
    proxy: {
      [env.REACT_APP_MAIN_PATH]: {
        target: `http://${env.REACT_APP_IP}:${env.REACT_APP_PORT}${env.REACT_APP_MAIN_PATH}`,
        changeOrigin: true,
        pathRewrite: {
          [`^${env.REACT_APP_MAIN_PATH}`]: ''
        }
      }
    }
  }
}

module.exports = config

针对env的配置重点,我抽取出来。

首先,引入dotenv-webpack

const Dotenv = require('dotenv-webpack')

将引入的插件加入webpack配置。这里的path重新指定了对应的env配置的路径。

plugins: [
    new Dotenv({
      path: path.resolve(__dirname, `.env.${env.REACT_APP_ENV}`)
    }),
  ]

至此,配置文件就准备好了。

运行

package.json中配置运行脚本:

"scripts": {
  "start": "dotenv -e .env.development webpack-dev-server",
  "backserver": "dotenv -e .env.backserver webpack-dev-server"
},

这里就使用到了dotenv-cli

运行对应脚本,我们就可以通过REACT_APP_ENV进行环境区分,从而搭配不同的配置了。这个变量名称是可以自定义的,根据个人需要增删改吧。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐