webpack5.0 搭建react+ts框架 亲测~

初始化

npm init -y

package.json文件

{
  "name": "react",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "cross-env state=dev webpack-dev-server --config ./webpack-config/webpack.dev.js",
    "dev:test": "cross-env state=test webpack-dev-server --config ./webpack-config/webpack.dev.js",
    "build": "cross-env state=prod webpack --config ./webpack-config/webpack.prod.js",
    "build:test": "cross-env state=test webpack --config ./webpack-config/webpack.prod.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.18.6",
    "@babel/preset-env": "^7.18.6",
    "@babel/preset-react": "^7.18.6",
    "@babel/preset-typescript": "^7.18.6",
    "babel-loader": "^8.2.5",
    "clean-webpack-plugin": "^4.0.0",
    "cross-env": "^7.0.3",
    "css-loader": "^6.7.1",
    "fork-ts-checker-webpack-plugin": "^7.2.11",
    "html-webpack-plugin": "^5.5.0",
    "mini-css-extract-plugin": "^2.6.1",
    "node-sass": "^7.0.1",
    "postcss-loader": "^7.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0",
    "sass-loader": "^13.0.2",
    "style-loader": "^3.3.1",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0",
    "webpack-merge": "^5.8.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.14",
    "@types/react-dom": "^18.0.5",
    "ts-loader": "^9.3.1",
    "typescript": "^4.7.4",
    "webpack-dev-server": "^4.9.2",
    "webpackbar": "^5.0.2"
  }
}

目录结构

image.png

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "es2015",
    "jsx": "react-jsx",
    "strict": true,
    "module": "esnext",
    "importHelpers": true,
    "moduleResolution": "Node",
    "allowSyntheticDefaultImports": true,
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*", "types/*.d.ts", "test.js"],
  "exclude": ["node_modules"]
}

config相关文件

// webpack.common.js

const Webpack = require("webpack");
const Path = require("path");

const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const getCSSModuleLocalIdent = require("react-dev-utils/getCSSModuleLocalIdent");
const WebpackBar = require("webpackbar");

const ENV_STATE = process.env.state;
const util = require("./util");

const modules = {
  rules: [
    {
      test: /\.(js|jsx)$/,
      loader: "babel-loader",
      exclude: /node_modules/,
    },
    {
      test: /\.(ts|tsx)$/,
      loader: "ts-loader",
      exclude: /node_modules/,
    },
    {
      test: /\.(css|scss)$/,
      exclude: /\.module\.scss$/,
      use: [
        MiniCssExtractPlugin.loader,
        "css-loader",
        "postcss-loader",
        "sass-loader",
      ],
    },
    {
      test: /\.module\.scss$/,
      use: [
        MiniCssExtractPlugin.loader,
        {
          loader: "css-loader",
          options: {
            modules: {
              getLocalIdent: getCSSModuleLocalIdent, // 命名带地址
            },
          },
        },
        "postcss-loader",
        "sass-loader",
      ],
    },
  ],
};

const plugins = [
  // html模板
  new HtmlWebpackPlugin({
    template: "index.html",
  }),
  //   css压缩
  new MiniCssExtractPlugin({
    filename: "css/[name].[hash].css",
  }),
  // 打包显示进度条
  new WebpackBar(),
  new Webpack.DefinePlugin({
    "process.env": {
      STATE_CONFIG: JSON.stringify(util.url[ENV_STATE]),
    },
  }),
  // webpack打包不会有类型检查,强制ts类型检查
  new ForkTsCheckerWebpackPlugin({
    typescript: {
      configFile: Path.resolve(__dirname, '..', "tsconfig.json"),
    },
  }),
  // 自动删除上一次打包的产物
  new CleanWebpackPlugin(),
];

module.exports = {
  entry: "./src/index.tsx",
  output: {
    path: Path.resolve(__dirname, `../${util.outPath[ENV_STATE]}`),
    filename: "./js/[name].[hash].js",
    clean: true,
    publicPath: "/",
  },
  resolve: {
    alias: {
      "@": Path.resolve(__dirname, "../src"),
    },
    extensions: [".ts", ".tsx", ".js", ".jsx"],
  },
  module: modules,
  plugins,
  cache: {
    type: "filesystem",
    // 可选配置
    buildDependencies: {
      config: [__filename], // 当构建依赖的config文件(通过 require 依赖)内容发生变化时,缓存失效
    },
    name: "development-cache",
  },
};

// webpack.dev.js
const WebpackMerge = require("webpack-merge");
const path = require('path')
const Config = require("./webpack.common");

const devServer = {
  port: 8848,
  historyApiFallback: true,
  compress: true, //gzip压缩
  open: true,
  proxy: {
    "/": {},
  },
};

const devConfig = {
  mode: "development",
  devServer: devServer,
};

module.exports = WebpackMerge.merge(Config, devConfig);

// webpack.prod.js
const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.common");

module.exports = merge(commonConfig, {
  mode: "production",
});

// url.js  自己命名修改引入路径

module.exports = {
    outPath: {
        dev: 'dev',
        prod: 'dist',
        test: 'test'
    },
    url: {
        dev: '',
        test: '',
        prod: ''
    }
}

解决无法识别scss.module.scss

// types/glovals.d.ts 可以自己命名
declare module '*.scss';
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容