webpack搭建react+ts+eslint项目
【初始化项目】
mkdir react_ts_eslint
cd react_ts_eslint
npm init
【生成ts配置文件】
tsc --init
【安装相关依赖】
npm install typescript webpack webpack-cli webpack-dev-server ts-loader cross-env webpack-merge clean-webpack-plugin html-webpack-plugin -D npm install react @types/react react-dom @types/react-dom -D npm install redux react-redux @types/react-redux redux-logger redux-promise redux-thunk @types/redux-logger @types/redux-promise -D npm install react-router-dom @types/react-router-dom connected-react-router antd -D npm install eslint @typescript-eslit/eslint-plugin @typescript-eslit/parser -D npm install @types/jest ts-jest -D
【编写 /config/webpack.base.config.js
】
/* * @Description: * @Date: 2020-12-11 15:34:09 * @Author: Jsmond2016 <jsmond2016@gmail.com> * @Copyright: Copyright (c) 2020, Jsmond2016 */ // 清理产出目录的插件 const { CleanWebpackPlugin } = require('clean-webpack-plugin') // 产出 html 的插件 const HtmlWebpackPlugin = require('html-webpack-plugin') const path = require('path') module.exports = { entry: './src/index.tsx', output: { // 输出目录 path: path.resolve(__dirname, '../dist'), filename: 'main.js' }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'] }, devServer: { contentBase: '../dist',
inline:true,
host:'127.0.0.1',
port:8080
}, module: { rules: [ { test: /\.(j|t)sx?/, use: 'ts-loader', exclude: /node_modules/ } ] }, plugins: [ new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: ['./dist'] }), new HtmlWebpackPlugin({ template: './src/index.html' }) ] }
【编写 webpack.dev.config.js
】
const { smart } = require('webpack-merge') const base = require('./webpack.base.config') module.exports = smart(base, { mode: 'development', devtool: 'inline-soruce-map' })
【编写 webpack.prod.config.js
】
const { smart } = require('webpack-merge') const base = require('./webpack.base.config') module.exports = smart(base, { mode: 'production', })
【新建 src/index.html
】
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>react-ts</title> </head> <body> <div id="root"></div> </body> </html>
【新建 src/index.tsx
】
console.log('hello')
【配置 package.json
中的 dev
, build
命令】
{ "name": "react-typeScript", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server --config ./config/webpack.dev.config.js", "build": "cross-env NODE_ENV=production webpack --config ./config/webpack.prod.config.js", "eslint": "eslint src --ext .js,.ts,.tsx", "test": "jest" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@types/jest": "^24.9.1", "@types/react-redux": "^7.1.7", "@types/react-router-dom": "^5.1.3", "@types/redux-logger": "^3.0.7", "@types/redux-promise": "^0.5.28", "clean-webpack-plugin": "^3.0.0", "cross-env": "^7.0.0", "css-loader": "^3.4.2", "html-webpack-plugin": "^3.2.0", "jest": "^25.1.0", "react-redux": "^7.1.3", "redux": "^4.0.5", "redux-logger": "^3.0.6", "redux-promise": "^0.6.0", "redux-thunk": "^2.3.0", "style-loader": "^1.1.3", "ts-jest": "^25.0.0", "ts-loader": "^6.2.1", "typescript": "^3.7.5", "webpack": "^4.41.5", "webpack-cli": "^3.3.10", "webpack-dev-server": "^3.10.1", "webpack-merge": "^4.2.2" }, "dependencies": { "@types/react": "^16.9.19", "@types/react-dom": "^16.9.5", "antd": "^3.26.7", "connected-react-router": "^6.6.1", "react": "^16.12.0", "react-dom": "^16.12.0", "react-router-dom": "^5.1.2" } }
【启动项目】
npm run dev /*webpack.dev.config.js文件的单词一定要严格书写正确*/
【如果报错】
/**可能会报错:smart is not a function*/ 这是因为webpack-merge版本不兼容,需要制定版本:npm install webpack-merge@4.2.1 -D /**如果出现报错:Error: Cannot find module 'webpack-cli/bin/config-yargs,这个也是版本不兼容问题,需要指定一下版本号*/ 终端运行命令:npm install webpack-cli@3.3 -D 安装成功后运行命令:npm run dev
【运行打包命令报错】
/**打包时出现报错,并提示你安装webpack-cli,然后一直安装不上,这时,你需要全局安装*/ npm install webpack -g
【配置eslint】
{ "parser": "@typescript-eslint/parser", "plugins": [ "@typescript-eslint/eslint-plugin" ], "extends": [ /** 使用推荐配置 */ "plugin:@typescript-eslint/recommended" ], "rules": { /** 配置规则 */ "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/no-var-requires": "off" } } /**记得在package.json新增eslint命令:"eslint": "eslint src --ext .js,.ts,.tsx",*/
【单元测试:安装 jest 测试工具】
npm install @types/jest ts-jest -D /**另外还需要全局安装jest-cli*/ npm install jest-cli -g
【新建 jest.config.js
配置】
module.exports = { preset: 'ts-jest', testEnvironment: 'node' }
【编写测试文件】
// src/calc.tsx function sum (a: number, b: number) { return a + b } function minus (a: number, b: number) { return a - b } module.exports = { sum, minus } // src/calc.test.jsx let calc = require('./calc') describe('测试calc', () => { test('1+1', () => { expect(calc.sum(1,1)).toBe(2) }) test('111', () => { expect(calc.minus(1,1)).toBe(0) }) })
【配置 package.json
中 测试命令】
运行测试命令: npm run test
【6-支持 React,编写 src/index.tsx
代码】
import React from 'react'; import ReactDom from 'react-dom' const Index = () => { return ( <div>hello, world</div> ) } ReactDom.render(<Index />, document.getElementById("root"))
【这时可能会标红语法问题,需要配置 tsconfig.json
】
{ "compilerOptions": { /** ... 新加这个 */ "jsx": "preserve", /** 'preserve' | 'react-native' | 'react' */ /** 'preserve' 表示保留 jsx 语法 和 tsx 后缀 */ /** 'react-native' 表示 保留 jsx 语法但会把后缀改为 js */ /** 'react' 表示不保留 jsx 语法,直接编译成 es5 */ } }
【这时执行npm run dev命令,控制台可能会报错】
这是因为,项目还没添加babel转换器,浏览器无法识别jsx和es6语法
【解决方案】
首先需要安装最新的:npm i babel-loader @babel/core @babel/runtime @babel/preset-env @babel/plugin-proposal-class-properties @babel/plugin-transform-runtime -D 然后在根目录创建.babelrc,并配置成: { "presets": [ "@babel/preset-env" ], "plugins": [ "@babel/plugin-transform-runtime", "@babel/plugin-proposal-class-properties" ] } 最后需要安装:npm install @babel/preset-react @babel/plugin-syntax-jsx @babel/plugin-proposal-decorators -D 并且在webpack.base.config.js中的module下的rules添加对象: { test: /\.(js|jsx|tsx)$/,//一个匹配loaders所处理的文件的拓展名的正则表达式,这里用来匹配js和jsx以及tsx文件(必须) use: { loader: 'babel-loader', options: { presets: [ '@babel/preset-react', ], plugins: [ ["@babel/plugin-proposal-decorators", { "legacy": true }], ["@babel/plugin-proposal-optional-chaining"], ["@babel/plugin-syntax-jsx"], ] } },//loader的名称(必须) exclude: /node_modules/ //屏蔽不需要处理的文件(文件夹)(可选) }
此时再运行启动命令:就可以看到项目可以启动了