发布时间:2025-06-24 18:06:55  作者:北方职教升学中心  阅读量:388


   static: {      directory: path.join(__dirname, "../public"), // 托管静态资源public文件夹   },    headers: { "Access-Control-Allow-Origin": "*" }, // HTTP响应头设置,允许任何//来源进行跨域请求 },});export default devConfig;

然后再 package.json 中添加启动脚本: 

"scripts": {  "dev": "webpack serve -c build/webpack.dev.ts"},

再打开tsconfig.json中的 jsx

{  "compilerOptions": {    "target": "es2016",    "esModuleInterop": true,    "module": "commonjs",    "forceConsistentCasingInFileNames": true,    "strict": true,    "skipLibCheck": true,    "jsx": "preserve" },  "include": ["./src"]}

 然后就可以运行 pnpm run dev 脚本启动项目啦~

6.配置 webpack.prod.ts

import { Configuration } from "webpack";import { merge } from "webpack-merge";import baseConfig from "./webpack.base";const prodConfig: Configuration = merge(baseConfig, {  mode: "production", // 生产模式,会开启tree-shaking和压缩代码,以及其他优化});export default prodConfig;

在 package.json 中添加:

"scripts": {    // ...    "build": "webpack -c build/webpack.prod.ts"},

运行 pnpm run build 就可以成功打包啦 ~

7.copy 静态资源

pnpm i copy-webpack-plugin -D

修改 webpack.base.ts :

// ...const baseConfig: Configuration = {  // ...  plugins: [    new HtmlWebpackPlugin({      title: "webpack5-react-ts",      filename: "index.html",      // 复制 'index.html' 文件,并自动引入打包输出的所有资源(js/css)      template: path.join(__dirname, "../public/index.html"),      inject: true, // 自动注入静态资源      hash: true,      cache: false,      // 压缩html资源      minify: {        removeAttributeQuotes: true,        collapseWhitespace: true, //去空格        removeComments: true, // 去注释        minifyJS: true, // 在脚本元素和事件属性中缩小JavaScript(使用UglifyJS)        minifyCSS: true, // 缩小CSS样式元素和样式属性     }   }) ],};export default baseConfig;

修改  webpack.prod.ts:

import path from "path";import { Configuration } from "webpack";import { merge } from "webpack-merge";import CopyPlugin from "copy-webpack-plugin";import baseConfig from "./webpack.base";const prodConfig: Configuration = merge(baseConfig, {  mode: "production", // 生产模式,会开启tree-shaking和压缩代码,以及其他优化  plugins: [    new CopyPlugin({patterns: [       {          from: path.resolve(__dirname, "../public"), // 复制public下文件          to: path.resolve(__dirname, "../dist"), // 复制到dist目录中          filter: (source) => !source.includes("index.html"), // 忽略index.html       },     ],   }), ],});export default prodConfig;

测试一下,在 public 中新增一个 favicon.ico 图标文件,在 index.html 中引入

再执行 pnpm run build 打包,就可以看到 public 下的 favicon.ico 图标文件被复制到 dist 文件 中了~

8.配置环境变量(cross-env + DefinePlugin

pnpm i cross-env -D

安装 cross-env后修改package.json 的 scripts

"scripts": {//...    "dev:dev": "cross-env NODE_ENV=development BASE_ENV=development webpack serve -c build/webpack.dev.ts",    "dev:test": "cross-env NODE_ENV=development BASE_ENV=test webpack serve -c build/webpack.dev.ts",    "dev:pre": "cross-env NODE_ENV=development BASE_ENV=pre webpack serve -c build/webpack.dev.ts",    "dev:prod": "cross-env NODE_ENV=development BASE_ENV=production webpack serve -c build/webpack.dev.ts",    "build:dev": "cross-env NODE_ENV=production BASE_ENV=development webpack -c build/webpack.prod.ts",    "build:test": "cross-env NODE_ENV=production BASE_ENV=test webpack -c build/webpack.prod.ts",    "build:pre": "cross-env NODE_ENV=production BASE_ENV=pre webpack -c build/webpack.prod.ts",    "build:prod": "cross-env NODE_ENV=production BASE_ENV=production webpack -c build/webpack.prod.ts"},;

在 webpack.base.ts 中打印一下设置的环境变量

console.log('NODE_ENV', process.env.NODE_ENV)console.log('BASE_ENV', process.env.BASE_ENV)

执行 pnpm run build:dev ,就可以在控制台打印出

修改 webpack.base.ts

import { DefinePlugin } from 'webpack'module.export = {  // ...  plugins: [    // ...    new DefinePlugin({      'process.env': JSON.stringify(process.env)   }) ]}

在根目录下新建 typings/global.d.ts 文件后在里面配置下面代码

declare module 'process' {  global {    namespace NodeJS {      export interface ProcessEnv {        BASE_ENV: 'development' | 'test' | 'pre' | 'production'        NODE_ENV: 'development' | 'production'     }   } }}

 并在 tsconfig.json 中配置:

{  "compilerOptions": {    "target": "es2016", // 编译输出的JavaScript版本为ES2016    "esModuleInterop": true, // 允许更好的兼容性与ECMAScript模块导入    "module": "commonjs", // 指定生成哪个模块系统代码,这里是CommonJS    "forceConsistentCasingInFileNames": true, // 确保文件名大小写一致,有助于跨平//台开发    "strict": true, // 启用所有严格的类型检查选项    "skipLibCheck": true, // 跳过声明文件的类型检查,可以提高编译速度    "typeRoots": ["./typings/*.d.ts", "node_modules/@types"], // 指定类型声明文//件的路径    "jsx": "react-jsx" // react18这里改成react-jsx,就不需要在tsx文件中手动引入//React了 },  "include": ["./src", "./typings/*.d.ts"] // 指定哪些文件或目录应该被包含在编译范//围内}

测试一下,在 src/index.tsx 打印一下两个环境变量 

// src/index.tsxconsole.log('NODE_ENV', process.env.NODE_ENV)console.log('BASE_ENV', process.env.BASE_ENV)

执行 pnpm run dev:test ,可以在浏览器控制台看到打印的信息

9.配置多环境运行配置

pnpm i dotenv

安装依赖后在根目录下新建一个多文件配置文件夹 env

REACT_APP_API_URL=https://api-dev.com

REACT_APP_API_URL=https://api-test.com

REACT_APP_API_URL=https://api-pre.com  

REACT_APP_API_URL=https://api-prod.com  

然后再 webpack.base.ts 中引入,然后解析对应环境配置,最后通过 DefinePlugin 进行注入: 

import path from "path";import { Configuration, DefinePlugin } from "webpack";import HtmlWebpackPlugin from "html-webpack-plugin";import * as dotenv from "dotenv";// 加载配置文件const envConfig = dotenv.config({  path: path.resolve(__dirname, "../env/.env." + process.env.BASE_ENV),});// console.log("process.env", process.env);// console.log("NODE_ENV", process.env.BASE_ENV);// console.log("REACT_APP_API_URL", process.env.REACT_APP_API_URL);const baseConfig: Configuration = {  // ...  plugins: [    // 注入到业务    new DefinePlugin({      "process.env": JSON.stringify(envConfig.parsed),      "process.env.BASE_ENV": JSON.stringify(process.env.BASE_ENV),      "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),   }), ].filter(Boolean), // // 去除数组中的假值(例如,如果某些插件的条件不满足而导致未定义)};export default baseConfig;

在index.tsx里写入

import { createRoot } from 'react-dom/client';import App from './App';// const root = document.getElementById('root');const root = document.querySelector('#root')console.log('NODE_ENV', process.env.NODE_ENV)console.log('BASE_ENV', process.env.BASE_ENV)console.log("process.env", process.env);if(root) {  createRoot(root).render(<App />)}

pnpm i serve -g

然后重启项目: pnpm run dev:dev ,就可以在控制台 还可以验证一下环境配置是否正确,启动打 包: pnpm run build:prod ,通过 serve -s dist ,启动项目: 多运行环境配置成功!

10.文件别名

先在 webpack.base.ts 中配置:

resolve: {    extensions: [".ts", ".tsx", ".js", ".jsx", ".less", ".css"],    // 别名需要配置两个地方,这里和 tsconfig.json    alias: {      "@": path.join(__dirname, "../src")   },},

然后还需要在 tsconfig.json 中配置:

{  "compilerOptions": {    // ...     "baseUrl": ".",    "paths": {      "@/*": ["src/*"]   }, },}

然后就可以在App.tsx项目中使用了~

import '@/App.css'function App() {  return <h2>webpack5-react-ts</h2>}export default App

谢谢观看~如有问题麻烦指出!点个赞吧~~~

   // 否则可能会出现错误:Uncaught ReferenceError: React is not defined   ["@babel/preset-react", { runtime: "automatic" }],    "@babel/preset-typescript", ],};

 然后在 webpack.base.ts 文件中,就可以将 babel-loader 配置简化成:

// ...  module: {    rules: [     {        test: /.(ts|tsx)$/, // 匹配.ts, tsx文件        use: "babel-loader"     },      // ...   ], }, // ...

因为我们需要通过 webpack-dev-server 来启动我们的项目 ,所以先安装相关依赖

pnpm i webpack-dev-server webpack-merge -D

然后再配置开发环境webpack.dev.ts

import path from "path";import { merge } from "webpack-merge";import { Configuration as WebpackConfiguration } from "webpack";import { Configuration as WebpackDevServerConfiguration } from "webpack-devserver";importbaseConfig from "./webpack.base";interface Configuration extends WebpackConfiguration {  devServer?: WebpackDevServerConfiguration;}const host = "127.0.0.1";const port = "8082";// 合并公共配置,并添加开发环境配置const devConfig: Configuration = merge(baseConfig, {  mode: "development", // 开发模式,打包更加快速,省了代码优化步骤  devtool: "eval-cheap-module-source-map",  devServer: {    host,    port,    open: true, // 是否自动打开    compress: false, // gzip压缩,开发环境不开启,提升热更新速度    hot: true, // 开启热更新    historyApiFallback: true, // 解决history路由404问题    setupExitSignals: true, // 允许在 SIGINT 和 SIGTERM 信号时关闭开发服务器和退出//进程。

为了能够熟练掌握 webpack 的使用,接下来手把手教你如何搭建前端脚手架


1.项目初始化

首先初始化package.json文件

pnpm init

然后根目录会生成一个package.json文件

 手动创建下面目录

webpack.base.ts         # 公共配置

webpack.dev.ts         # 开发环境配置

webpack.prod.ts         # 打包环境配置

 index.tsx         # react应用入口页面 

 

index.html里写以下内容

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta http-equiv="X-UA-Compatible" content="IE=edge">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title>webpack5-react-ts</title></head><body>  <!-- 容器节点 -->  <div id="root"></div></body></html>

 2.引入react

pnpm i react react-dom         # 声明依赖

pnpm i @types/react @types/react-dom -D

运行完上面两个命令后列表会多出node_modules这个文件夹

接下来在src的index.tsx接口文件里写入

import React from 'react';import { createRoot } from 'react-dom/client';import App from './App';// const root = document.getElementById('root');const root = document.querySelector('#root')if(root) {  createRoot(root).render(<App />)}

在样式文件App.css文件里写入

h2 {    color: red;}

还有App.tsx里写入

import React from 'react'import './App.css'function App() {  return <h2>Hello East_White</h2>}export default App

因为我们在 App.tsx 中引入了 css 文件,所以还需要安装相关的 loader :

 pnpm i style-loader css-loader html-webpack-plugin -D

 3.引入typescript

pnpm i typescript -D

pnpm i babel-loader ts-node @babel/core @babel/preset-react @babel/presettypescript @babel/preset-env core-js -D

4.安装完依赖后初始化tsconfig.json

npx tsc --init

5.webpack配置

pnpm i webpack webpack-cli -D

pnpm i @types/node -D

安装依赖后在webpack.base.ts文件里写:

import { Configuration } from 'webpack';const path = require("path");const baseConfig: Configuration = {  entry: path.join(__dirname, "../src/index.tsx"), // 入口文件  // 打包出口文件 output: {    filename: "static/js/[name].js", // 每个输出js的名称    path: path.join(__dirname, "../dist"), // 打包结果输出路径    clean: true, // webpack4需要配置clean-webpack-plugin来删除dist文件,webpack5内置了    publicPath: "/", // 打包后文件的公共前缀路径 },  // loader 配置  module: {    rules: [], },  resolve: {    extensions: [".tsx", ".ts", ".jsx", ".js"], },  // plugins 的配置  plugins: []};

完善webpack.base.ts

import { Configuration } from "webpack";import HtmlWebpackPlugin from "html-webpack-plugin";const path = require("path");const baseConfig: Configuration = {  entry: path.join(__dirname, "../src/index.tsx"), // 入口文件  // 打包出口文件  output: {    filename: "static/js/[name].js", // 每个输出js的名称    path: path.join(__dirname, "../dist"), // 打包结果输出路径    clean: true, // webpack4需要配置clean-webpack-plugin来删除dist文件,webpack5内置了    publicPath: "/", // 打包后文件的公共前缀路径 },  // loader 配置  module: {    rules: [     {test: /.(ts|tsx)$/, // 匹配.ts, tsx文件        use: {          loader: "babel-loader",          options: {            // 预设执行顺序由右往左,所以先处理ts,再处理tsx            presets: [               [                  "@babel/preset-env",                 {                    // 设置兼容目标浏览器版本,也可以在根目录配置.browserslistrc文 // 件,babel-loader会自动寻找上面配置好的文件.browserslistrc                    targets: { browsers: ["> 1%", "last 2 versions", "not ie <= 8"] },                    useBuiltIns: "usage", // 根据配置的浏览器兼容,以及代码中使用到//的api进行引入polyfill按需添加                    corejs: 3, // 配置使用core-js使用的版本                    loose: true,                 },               ],                // 如果您使用的是 Babel 和 React 17,您可能需要将 "runtime": "automatic" //添加到配置中。

webpack 具有高度可配置性,它拥有非常丰富的配置。

 目录

 目录

前言

1.项目初始化

 2.引入react

 3.引入typescript

4.安装完依赖后初始化tsconfig.json

5.webpack配置

6.配置 webpack.prod.ts

7.copy 静态资源

8.配置环境变量(cross-env + DefinePlugin)

9.配置多环境运行配置

10.文件别名


前言

webpack 是一个现代 JavaScript 应用程序的静态模块打包工具,基本上现在的大型应用都是通过 webpack 进行构建的。在根目录新建 babel.config.js

在babel.config.js里写入

module.exports = {  // 执行顺序由右往左,所以先处理ts,再处理jsx,最后再试一下babel转换为低版本语法  presets: [   [      "@babel/preset-env",     {        // 设置兼容目标浏览器版本,这里可以不写,babel-loader会自动寻找上面配置好的文//件.browserslistrc        // "targets": {        // "chrome": 35,        // "ie": 9        // },        targets: { browsers: ["> 1%", "last 2 versions", "not ie <= 8"] },        useBuiltIns: "usage", // 根据配置的浏览器兼容,以及代码中使用到的api进行引入//polyfill按需添加        corejs: 3, // 配置使用core-js使用的版本        loose: true,     },   ],    // 如果您使用的是 Babel 和 React 17,您可能需要将 "runtime": "automatic" 添加到//配置中。                // 否则可能会出现错误:Uncaught ReferenceError: React is not defined               ["@babel/preset-react", { runtime: "automatic" }],                "@babel/preset-typescript",             ],         },       },     },     {        test: /.css$/, //匹配 css 文件        use: ["style-loader", "css-loader"],     },   ], },  resolve: {    extensions: [".tsx", ".ts", ".jsx", ".js"], },  // plugins  plugins: [    new HtmlWebpackPlugin({      // 复制 'index.html' 文件,并自动引入打包输出的所有资源(js/css)      template: path.join(__dirname, "../public/index.html"),      // 压缩html资源      minify: {        collapseWhitespace: true, //去空格        removeComments: true, // 去注释     },   }), ],};export default baseConfig

 因为 webpack.base.ts 文件承载了基本的配置,随着 webpack 做的事情越来越多,会逐渐变得很 庞大,我们可以将其中的 babel-loader 相关的配置抽离出来进行管理。