写在前面
这是一篇工具类的文档,没有过多的废话,仅仅分享一下如何快速新建一个基础的的React项目,话不多说,直接进入主题
1. 创建react项目
npx create-react-app <object name> --template typescript
2. 安装webpack脚手架
npm install webpack webpack-cli
3. 安装babel
npm install babel-loader @babel/core @babel/preset-env @babel/preset-react
4. 安装 css-loader、less-loader、file-loader、url-loader
npm install css-loader style-loader less-loader file-loader url-loader
5. 安装 html-webpack-plugin
这一步可以忽略(html-webpack-plugin是用于简化 HTML 文件,具体是什么可以自己去查)
npm install html-webpack-plugin
6. 配置webpack.config.js
resolve.alias中的别名配置是个人习惯,代码拷贝后自行修改
// webpack.config.js
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 可选,用于清理构建目录
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: process.env.NODE_ENV || 'development',
entry: {
main: resolve(__dirname, 'src', 'index.tsx')
},
output: {
filename: "[name].[contenthash].js",
path: resolve(__dirname, 'dist')
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
// 添加别名
images: resolve(__dirname, 'src/assets/images/'),
'@': resolve(__dirname, 'src/'),
},
},
module: {
rules: [
{
test: /\.tsx?/,
use: [
'babel-loader'
],
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
]
},
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader'
]
},
{
test: /\.(png|jpe?g|gif|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192, // 小于8KB的图片将会被转换为 base64
name: 'images/[name].[ext]', // 输出文件的路径和名称
},
},
],
},
// 添加用于处理视频文件的加载器规则
{
test: /\.(mp4|webm)$/i,
use: [
{
loader: 'file-loader',
options: {
name: 'videos/[name].[hash:8].[ext]',
},
},
],
},
]
},
plugins: [
new CleanWebpackPlugin(), // 可选,用于清理构建目录
// 设置每次构建之前清理 build 文件夹
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['build'],
}),
new HtmlWebpackPlugin({
template: resolve(__dirname, 'public', 'index.html'),
inject: 'body'
}),
],
devServer: {
port: 3000,
}
}
7. 配置 .babelrc
.babelrc 是 Babel 的配置文件,用于指定 Babel 编译器的行为和选项。Babel 是一个 JavaScript 编译器,通常用于将 ECMAScript 2015+ (ES6+) 的代码转换为向后兼容的 JavaScript 版本,以便在当前和旧版的浏览器或环境中运行。
.babelrc 文件允许你配置 Babel 的转换规则、插件和预设(presets)。通过配置 .babelrc,你可以指定:
- 转换规则(Transformations) :定义哪些语法或功能应该被转换,例如箭头函数、模板字符串等。
- 插件(Plugins) :自定义的转换插件,用于进行更复杂或个性化的转换操作。
- 预设(Presets) :一组预先定义好的插件集合,用于简化配置,通常针对特定的转换任务或环境。
以下是我项目中的配置:
// .babelrc
{
"presets": [
"@babel/preset-env", // 使用 @babel/preset-env 预设,根据目标环境自动转换 JavaScript 语法和功能
"@babel/preset-typescript", // 使用 @babel/preset-typescript 预设,用于处理 TypeScript 代码
[
"@babel/preset-react", // 使用 @babel/preset-react 预设,用于转换 React JSX 语法
{
"runtime": "automatic" // 使用 React 的自动运行时,以便支持 JSX 转换
}
]
],
"plugins": [
"@babel/plugin-proposal-object-rest-spread", // 使用 @babel/plugin-proposal-object-rest-spread 插件,以支持对象扩展运算符
"@babel/plugin-proposal-class-properties" // 使用 @babel/plugin-proposal-class-properties 插件,以支持类属性语法
],
"env": {
"production": { // 配置针对生产环境的特定设置
"plugins": ["transform-remove-console"] // 在生产环境下使用 transform-remove-console 插件,用于移除控制台输出语句
}
}
}
8. 配置.d.ts 文件
.d.ts 文件扩展名表示 TypeScript 的声明文件。它们的作用是为 JavaScript 代码库提供类型信息,使得 TypeScript 编译器能够进行类型检查和提供智能提示。通常用于描述 JavaScript 库的类型信息,特别是在 TypeScript 项目中使用第三方 JavaScript 库时。
// xxx.d.ts
declare module '*.module.less' {
const classes: { readonly [key: string]: string }
export default classes
}
declare module '*.png' {
const value: string;
export default value;
}
declare module '*.gif' {
const value: string;
export default value;
}
declare module '*.mp4' {
const value: string;
export default value;
}
declare module '*svg' {
const value: any;
export default value;
}
declare module 'echarts/lib/echarts' {
const echarts: any; // 使用 any 类型来避免类型检查错误
export = echarts;
}
9. 配置 tsconfig.json
// tsconfig.json
{
"compilerOptions": {
"target": "es2015",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"paths": {
"@/*": ["./src/*"],
"images/*": ["./src/assets/images/*"]
}
},
"include": [
"src",
"custom.d.ts"
]
}
10. 在src下新建config.js、config.dev.js、config.pord.js
这里是为了配置不同的环境变量,下文中有修改package.json中的start和build命令,在webpack打包时,设置不同的NODE_ENV,然后在下面的文件中就可以自动识别当前的环境(最后的request.ts中演示了如何使用环境变量)
// config.js
let env = process.env.NODE_ENV;
env = env || 'development'
const config = {
development: require('./config.dev'),
production: require('./config.prod'),
};
module.exports = config[env];
// config.dev.js
module.exports = {
value: '这是dev环境的变量',
apiUrl: 'www.dev.com',
};
// config.prod.js
module.exports = {
value: '这是生产环境的变量',
apiUrl: 'www.prod.com',
};
11. 修改package.json中的start和build
// package.json
{
"name": "react_ts",
"version": "0.1.0",
"private": true,
"dependencies": {
...
},
"scripts": {
"start": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.js",
"build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
...
12. 安装cross-env
cross-env 是一个用于设置跨平台环境变量并运行命令的 Node.js 包,设置环境变量用的
npm install cross-env
13. 安装babel依赖
这里是我配置好准备启动项目的时候,才发现有俩依赖没装,装一下就好了
npm install @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread
14.最后再封装一个request请求方法吧,顺便演示一下环境变量怎么使用的
// request.ts
const config = require("./config");
export const usePrefix = config.apiUrl
// 封装 GET 请求
export const get = async (url: RequestInfo | URL, token?: string) =>{
const local_token = window.localStorage.getItem('access_token') || ''
const useToken = token ? token : local_token
try {
const response = await fetch(`${usePrefix}${url}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${useToken}`,
},
});
const data = await response.json();
const code = response.status
// 用户信息有误,移除access_token
if(data === 401){
window.localStorage.removeItem('access_token')
}
return { data, code };
} catch (error) {
return error;
}
}
// 封装 POST 请求
export const post = async (url: RequestInfo | URL, data: any) => {
const local_token = window.localStorage.getItem('access_token') || ''
try {
const response = await fetch(`${usePrefix}${url}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${local_token}`,
},
body: JSON.stringify(data),
});
const responseData = await response.json();
const code = response.status
// 用户信息有误,移除access_token
if(code === 401){
window.localStorage.removeItem('access_token')
}
return { data: responseData, code };
} catch (error) {
return error;
}
};
文件目录
关于作者
练习时长两年半的一名前端开发工程师,最近新建项目的次数比较多,第一次写博客,主要为了记录一下学习过程,并且能够提供一个简单的通用模板,有什么好的建议可以向我提出,有什么问题也可以及时反馈