一直想使用webpack搭建React和Vue项目;今天就实现搭建React做做笔记。
1、初始化项目;生成一个packge.json文件
npm init -y
2、初始化tsconfig.json文件
- 需要先全局安装 (已安装可跳过)
- tsc --init
// 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"
]
}
3、安装需要的loader和plugin
npm i -S webpack webpack-cli webpack-merge cross-env react react-dom react-redux @reduxjs/toolkit react-router-domnpm i -S babel-loader @babel/preset-react @babel/preset-typescript @babel/core @babel/preset-envnpm i -S clean-webpack-plugin css-loader fork-ts-checker-webpack-plugin html-webpack-plugin mini-css-extract-plugin node-sass postcss-loader sass-loader style-loadernpm i -D @types/react @types/react-dom @types/react-sticky uglifyjs-webpack-plugin webpack-dev-server webpackbar ts-loader
{
"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",
"@reduxjs/toolkit": "^1.8.3",
"babel-loader": "^8.2.5",
"classnames": "^2.3.1",
"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",
"lodash": "^4.17.21",
"md-editor-rt": "^2.2.0",
"mini-css-extract-plugin": "^2.6.1",
"node-sass": "^7.0.1",
"postcss-loader": "^7.0.0",
"react": "^18.2.0",
"react-dev-utils": "^12.0.1",
"react-dom": "^18.2.0",
"react-redux": "^8.0.2",
"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/lodash": "^4.14.182",
"@types/markdown-navbar": "^1.4.0",
"@types/react": "^18.0.14",
"@types/react-dom": "^18.0.5",
"@types/react-sticky": "^6.0.4",
"autocannon": "^7.9.0",
"ts-loader": "^9.3.1",
"typescript": "^4.7.4",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack-dev-server": "^4.9.2",
"webpackbar": "^5.0.2"
}
}
ps:有一些依赖是写博客相关的,可以不需要安装
4、新建webpack-congfig文件夹
- 配置项
utils.js
module.exports = {
outPath: {
dev: 'dev',
prod: 'dist',
test: 'test'
},
url: {
dev: '',
test: '',
prod: ''
}
}
- 公共配置
webpack.common.js
一直想使用webpack搭建React和Vue项目;今天就实现搭建React做做笔记。
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");
console.log(ENV_STATE, 'ENV_STATE')
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: [
ENV_STATE === 'prod' ? MiniCssExtractPlugin.loader : "style-loader",
"css-loader",
"postcss-loader",
"sass-loader",
],
},
{
test: /\.module\.scss$/,
use: [
ENV_STATE === 'prod' ? MiniCssExtractPlugin.loader : "style-loader",
{
loader: "css-loader",
options: {
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
},
"postcss-loader",
"sass-loader",
],
},
{
test: /\.(jpg|png|gif|svg)$/,
type: 'asset/resource',
generator: {
filename: 'img/[hash][ext][query]' // 局部指定输出位置
}
}
],
};
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,
},
resolve: {
alias: {
"@": Path.resolve(__dirname, "../src"),
"@assets": Path.resolve(__dirname, "../src/assets")
},
extensions: [".ts", ".tsx", ".js", ".jsx"],
},
module: modules,
plugins,
cache: false
};
- 开发配置
webpack.dev.js
const WebpackMerge = require("webpack-merge");
const path = require('path')
const Config = require("./webpack.common");
const devServer = {
port: 8848,
historyApiFallback: true,
proxy: {
"/": {},
},
};
const devConfig = {
mode: "development",
devServer: devServer,
};
module.exports = WebpackMerge.merge(Config, devConfig);
- 生产配置
const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.common");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = merge(commonConfig, {
mode: "production",
plugins: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
drop_console: true
}
}
})
]
});
ts识别scss问题 types/globals.d.ts
declare module '*.scss';