内容简介:最近导师安排了一个任务,将一个已配置好的React、Webpack4等具有市场上常见功能的模板添加上TypeScript。俗话说:环境配置三小时,Coding不足5分钟。配置环境真的非常浪费时间,因此写个文章记录下,希望能对各位要配置TS的前端们有所帮助。先放上完整配置好的项目地址:由于该文是边配置编写的,时间跨度也有点大,导致写文的思路断断续续,也未做过多的文字润色,给看到最后的读者们递眼药水。
最近导师安排了一个任务,将一个已配置好的React、Webpack4等具有市场上常见功能的模板添加上TypeScript。俗话说:环境配置三小时,Coding不足5分钟。配置环境真的非常浪费时间,因此写个文章记录下,希望能对各位要配置TS的前端们有所帮助。
模板目录
先放上完整配置好的项目地址: github.com/dcison/Reac…
├── .babelrc ├── .eslintrc ├── .gitignore ├── index.html ├── package.json ├── tsconfig.json ├── src │ ├── reducers │ ├── components │ ├── actions.ts │ ├── global.styl │ ├── index.tsx │ └── store.ts └── static 复制代码
文章目录
- Babel、Webpack 基本配置
- TypeScript配置
- Eslint 校验配置,基于Vscode
- React
- 样式相关
- React-Router
- Code Splitting
- webpack 热更新
- Redux
- Git 提交校验
Babel、Webpack
- 首先在 src 中创建入口文件 index.js, 随便写点代码,比如
// src/index.js import type from './components/Apple' console.log(type) // src/components/Apple.js export default { type: 'apple' } 复制代码
- 配置webpack.config.babel.js
import path from 'path'; export default { mode: 'development', devtool: 'eval', entry: { index: './src/index.js', }, output: { publicPath: '/', filename: 'js/[name].js', chunkFilename: 'js/[name].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } } ] }, devServer: { port: 3000 }, resolve: { extensions: [ '.jsx', '.js', '.ts', '.tsx' ] } }; 复制代码
- 编写.babelrc
{ "presets": [ "@babel/preset-env" ], "plugins": [ ] } 复制代码
- 编写package.json中的 "scripts" 与 "devDependencies"
{ "scripts": { "start": "webpack-dev-server --content-base" }, "devDependencies": { "@babel/cli": "^7.2.3", "@babel/core": "^7.2.2", "@babel/preset-env": "^7.3.1", "@babel/register": "^7.0.0", "babel-loader": "^8.0.5", "webpack": "^4.29.0", "webpack-cli": "^3.2.1", "webpack-dev-server": "^3.1.14" }, } 复制代码
- 运行 yarn 或者 npm i 安装依赖后 yarn start 或者 npm start,能看到success就表示Babel、Webpack配置成功了。
TypeScript
- 把刚才2个JS文件后缀改为tsx
- 配置webpack.config.babel.js,包括rules,入口文件的后缀:改为tsx。
entry: { index: './src/index.tsx', }, { test: /\.tsx?$/, exclude: /node_modules/, use: { loader: 'ts-loader' } } 复制代码
- 在根目录下创建一个 tsconfig.json
{ "compilerOptions": { "module": "esnext", "target": "es5", "lib": ["es6", "dom"], "sourceMap": true, "jsx": "react", "noImplicitAny": true, "allowJs": true, "moduleResolution": "node" }, "include": [ "src/*" ], "exclude": [ "node_modules" ] } 复制代码
- 安装依赖 yarn add -D ts-loader typescript
- yarn start 如果依旧 success 即表示成功
Eslint
- 添加.eslintrc 配置文件,如下:
{ "env": { "browser": true, "es6": true }, "extends": "eslint:recommended", "parserOptions": { "ecmaFeatures": { "experimentalObjectRestSpread": true, "jsx": true }, "sourceType": "module" }, "parser": "typescript-eslint-parser", "plugins": [ "react", "typescript" ], "rules": { //... 自行添加规则 } } 复制代码
- 安装依赖 yarn add -D eslint eslint-plugin-typescript typescript-eslint-parser eslint-plugin-react
- 配置Vscode:首选项 -> 设置(即setting.json),找到eslint.validate,没有就自己写,加入typescript与typescriptreact,分别用于监听ts与tsx文件,如下:
"eslint.validate": [ "javascript", "javascriptreact", { "language": "typescript", "autoFix": true }, { "language": "typescriptreact", "autoFix": true } ] 复制代码
React
- 使用配好 html-webpack-plugin 插件 ,yarn add -D html-webpack-plugin
- 在webpack.config.babel.js中配置下
import HtmlWebpackPlugin from 'html-webpack-plugin'; plugins: [ new HtmlWebpackPlugin({ title: '模板', hash: false, filename: 'index.html', template: './index.html', }) ] 复制代码
- 在根目录下写一个 html 模板
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title><%= htmlWebpackPlugin.options.title || ''%></title> </head> <body> <div id="root"></div> </body> </html> 复制代码
- 安装React相关依赖: yarn add react @types/react react-dom @types/react-dom @babel/preset-react
- .babelrc 中添加一条规则
"presets": [ "@babel/preset-env", "@babel/preset-react" // 添加这条 ], 复制代码
- 修改src/index.tsx
import * as React from 'react'; import * as ReactDOM from "react-dom"; class SomeComponent extends React.Component<{}, {}> { render () { return <div>hello</div>; } } ReactDOM.render( <SomeComponent/>, document.getElementById('root') ); 复制代码
- 在根目录运行yarn start ,在界面上看到hello就表示React的环境配好了
CSS 及 样式预处理 (以Stylus为例)
- 安装CSS相关loader:yarn add -D css-loader style-loader
- 配置webpack.config.babel.js 中的rules
{ test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { localIdentName: '[path][name]__[local]--[hash:base64:5]' } } ] } 复制代码
- 测试:在src下建一个css文件,然后在index.tsx中引用
import './global.css'; 复制代码
- 能看到样式被应用就表示CSS配置正常了,接下来配置Stylus
- 安装相关依赖: yarn add -D stylus-loader stylus
- 继续配置webpack.config.babel.js 中的rules
{ test: /\.styl$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: true, import: true, importLoaders: 1, localIdentName: '[path][name]__[local]--[hash:base64:5]' } }, { loader: 'stylus-loader' }, ] }, 复制代码
- 更改刚才CSS后缀文件为styl,index引用中的文件也改为相应的Styl文件,如果样式依旧有改动表示样式预处理器配置成功。
React-Router
- 安装依赖:yarn add react-router-dom @types/react-router-dom
- 修改下webpack.config.babel.js中的devServer,添加historyApiFallback
devServer: { historyApiFallback: true } 复制代码
- 在Component中的apple.tsx与xiaomi.tsx修改一下代码,如下
// src/components/Apple.tsx import * as React from 'react'; class Apple extends React.Component<any, any> { state = { text: 'iphone XR' } handleChange = () => { this.setState({ text: 'iphone8' }); } render () { return <> <button onClick={this.handleChange}>点我换机子</button> {this.state.text} </>; } } export default Apple; // src/components/xiaomi.tsx // 代码结构类似,就只改了下text的内容,所以不放了 // text: 'xiaomi 8' 复制代码
- 修改index.tsx中的代码,如下
import * as React from 'react'; import * as ReactDOM from "react-dom"; import { BrowserRouter, Route, Redirect, Switch, Link } from 'react-router-dom'; import Apple from './components/Apple'; import Xiaomi from './components/XiaoMi'; import './global.styl'; const Header = () => ( <ul> <li><Link to="/">苹果</Link></li> <li><Link to="/phone/xiaomi">小米</Link></li> </ul> ); ReactDOM.render( <div> <BrowserRouter> <> <Header /> <Switch> <Route path="/phone/apple" component={Apple} /> <Route path="/phone/xiaomi" component={Xiaomi} /> <Redirect to="/phone/apple" /> </Switch> </> </BrowserRouter> </div>, document.getElementById('root') ); 复制代码
- 启动你的yarn start 进行测试吧
code splitting
- 在Component目录下新增一个文件,asyncComponent.tsx
import * as React from "react"; export default function asyncComponent (importComponent: any) { class asyncComponent extends React.Component<any, any> { constructor (props: any) { super(props); this.state = { component: null }; } async componentDidMount () { const { default: component } = await importComponent(); this.setState({ component: component }); } render () { const C = this.state.component; return C ? <C {...this.props} /> : null; } } return asyncComponent; } 复制代码
- 在index.tsx引用的地方改为以下内容
import asyncComponent from "./components/asyncComponent"; const Apple = asyncComponent(() => import("./components/Apple")); const XiaoMi = asyncComponent(() => import("./components/XiaoMi")); 复制代码
- 如果出现下图情况则表示成功了
webpack 热更新
- 安装依赖 yarn add -D @types/webpack-env
- 开启热更新,修改webpack.config.babel.js的plugins、devServer ,添加两个属性
import webpack from 'webpack'; plugins: [ new webpack.HotModuleReplacementPlugin() ], devServer: { hot: true }, 复制代码
- 在入口文件中加入以下代码,更多详情可参考官网
if (module.hot) { module.hot.accept(); } 复制代码
- 随意修改一些文字内容,如果有下图类型情况出现表示配置成功
Redux
- 安装依赖:yarn add @types/react-redux react-redux redux redux-thunk
- 在src/下添加一个actions.ts,用于存放所有actions
export const initPhone = (data: object) => { return { type: 'INIT_PHONE', data }; }; export const setPhoneMoney = (data: object) => { return { type: 'SET_MONEY', data }; }; 复制代码
- 在src/下新建一个 reducers 目录,存放各业务reducer
// src/reducers/Phone.ts var initState = { name: '', money: 0 }; export default function (state = initState, action: any) { switch (action.type) { case 'INIT_PHONE': return { ...state, name: action.data.name, money: action.data.money }; case 'SET_MONEY': return { ...state, money: action.data.money }; default: return state; } } 复制代码
- 在src/下建store.ts
import { createStore, applyMiddleware, combineReducers } from 'redux'; import thunkMiddleware from 'redux-thunk'; import Phone from './reducers/Phone'; const rootReducer = combineReducers({ Phone }); const createStoreWithMiddleware = applyMiddleware( thunkMiddleware, )(createStore); function configureStore (initialState?: any) { return createStoreWithMiddleware(rootReducer, initialState); } export default configureStore(); 复制代码
- 修改组件中的代码,这里以Component/Apple.tsx为例
import * as React from 'react'; import { connect } from 'react-redux'; import * as action from '../actions'; class Apple extends React.Component<any, any> { componentDidMount () { this.props.initPhone({ name: '苹果8', money: 10000 }); } handleChange = () => { this.props.setPhoneMoney({ money: this.props.money - 20 }); } render () { return <> <button onClick={this.handleChange}>点我降价</button> {this.props.name} 现在仅售价 {this.props.money} </>; } } function mapStateToProps (state: any) { return { name: state.Phone.name, money: state.Phone.money }; } export default connect(mapStateToProps, action)(Apple); 复制代码
- 修改入口的代码(src/index.tsx)
import { Provider } from 'react-redux'; import store from './store'; <Provider store={store}> //用该容器包裹一下 <BrowserRouter> <> <Header /> <Switch> <Route path="/phone/apple" component={Apple} /> <Route path="/phone/xiaomi" component={XiaoMi} /> <Redirect to="/phone/apple" /> </Switch> </> </BrowserRouter> </Provider> 复制代码
Husky 与 lint-staged
- 安装依赖 yarn add -D lint-staged husky
- 在package.json中添加以下代码即可
"scripts": { "precommit": "lint-staged" }, "lint-staged": { "*.{ts,tsx}": [ "eslint --fix", "git add" ] } 复制代码
- 自行提交测试下吧~
参考
后话
由于该文是边配置编写的,时间跨度也有点大,导致写文的思路断断续续,也未做过多的文字润色,给看到最后的读者们递眼药水。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 网站模板 | 现代时尚创新创意投资组合HTML5模板设计
- ReportLibrary 报表模板库新增 21 张报表模板,加入报表导出功能!
- ReportLibrary 报表模板库新增 21 张报表模板,加入报表导出功能!
- 工具集核心教程 | 第五篇: 利用Velocity模板引擎生成模板代码
- Word 模板引擎 poi-tl V1.3.0 发布,新增模板语法
- React与Vue模板使用比较(一、vue模板与React JSX比较)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数据挖掘概念与技术
(加)Jiawei Han;Micheline Kamber / 范明、孟小峰 / 机械工业 / 2007-3 / 55.00元
《数据挖掘概念与技术(原书第2版)》全面地讲述数据挖掘领域的重要知识和技术创新。在第1版内容相当全面的基础上,第2版展示了该领域的最新研究成果,例如挖掘流、时序和序列数据以及挖掘时间空间、多媒体、文本和Web数据。本书可作为数据挖掘和知识发现领域的教师、研究人员和开发人员的一本必读书。 《数据挖掘概念与技术(原书第2版)》第1版曾是受读者欢迎的数据挖掘专著,是一本可读性极佳的教材。第2版充实了数据......一起来看看 《数据挖掘概念与技术》 这本书的介绍吧!