webpack.config.js( 基于webpack4.x )
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');//导入生成html文件的插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin") //独立打包css文件插件
//创建一个插件实例
const htmlPlugin = new HtmlWebpackPlugin({
template: path.join(__dirname, 'src/index.html'),//模板文件
filename: 'index.html'//生成文件名
});
const cssPlugin = new MiniCssExtractPlugin({//选项与htmlPlugin类似
filename: "index.css"
})
//向外暴露一个配置对象,commonjs规范(因为webpack是基于node构建)
//webpack默认只能打包处理.js后缀的文件,像.jpg .vue等文件无法主动处理,所以需要配置第三方loader
module.exports = {
mode: 'development', //development production ( 生产环境会将代码压缩 )
//在webpack4中有一大特性是约定大于配置,默认打包入口路径是'src/index.js',打包输出路径是'dist/main.js'
plugins: [
htmlPlugin,
cssPlugin
],
module: {//第三方loader
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
exclude: /node_modules/ // 在使用babel-loader时候一定要加上exclude,排除node_modules文件夹
},
// 解析css文件
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']// use从右往左写
},
// 解析less
{
test: /\.less$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
}
]
}
}
package.json
{
"name": "day1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --open --port 3000"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "^0.28.11",
"html-webpack-plugin": "^3.2.0",
"less": "^3.0.2",
"less-loader": "^4.1.0",
"mini-css-extract-plugin": "^0.4.0",
"style-loader": "^0.21.0",
"webpack": "^4.6.0",
"webpack-cli": "^2.1.2",
"webpack-dev-server": "^3.1.4"
},
"dependencies": {
"prop-types": "^15.6.1",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-router-dom": "^4.2.2",
"react-transition-group": "^1.2.1"
}
}
.babelrc
{
"presets": [
"env",
"stage-0",
"react"
],
"plugins": [
"transform-runtime"
]
}
index.js
这里要注意一点,react-router4后嵌套路由要写在组件里面
import React from 'react';
import ReactDOM from 'react-dom';
import {
HashRouter as Router,
Route,
Link
} from 'react-router-dom'
import Home from './pages/Home'
import About from './pages/About'
import TabNav from './components/TabNav'
import './css/base.css'
class App extends React.Component{
render(){
return (
<div>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<TabNav/>
</div>
)
}
}
ReactDOM.render((
<Router>
<App/>
</Router>
), document.getElementById('root'));
about.js,这是一个页面组件,在跟组件上注册了路由
import React from 'react';
import {Link, Route} from 'react-router-dom';
import Haha from '../components/Haha'
class About extends React.Component{
constructor(props){
super(props);
}
render(){
return (
<div id="about">
{/* 获取路由传参id */}
<h2>这是关于我们页面,暗号是{this.props.match.params.id}</h2>
<Link to="/about/haha">haha</Link>
{/* react-router4后嵌套路由写在组件里面 */}
<Route path="/about/haha" component={Haha}/>
{/* {this.props.children} */}
</div>
)
}
}
export default About
home.js,这是展示首页文件,里面实现了一个简单的todolist小功能
import React from 'react'
import Todo from '../components/Todo'
import '../css/home.less'
import { CSSTransitionGroup } from 'react-transition-group';//引进react动画组
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
todos: [1, 2, 3]
}
}
addList = val => {
let { todos } = this.state;
todos.unshift(val);
this.setState({ todos });
}
render() {
let list = this.state.todos.map((item, index) => <li key={index}>{item}</li>)
return (
<div id="home">
<Todo add={this.addList} />
<ul>
{/* react动画 */}
<CSSTransitionGroup
transitionName="example"
transitionEnterTimeout={500}
transitionLeaveTimeout={300}>
{list}
</CSSTransitionGroup>
</ul>
</div>
)
}
}
export default Home
todo.js,上面home页面实现todolist功能的组件,这里值得注意的是在组建中定义的props属性值使用prop-types包来设定参数
import React from 'react';
import PropTypes from 'prop-types';
class Todo extends React.Component{
constructor(props){
super(props);
}
add = () => {
if(this.input.value === ''){
alert('不能为空')
}else{
this.props.add(this.input.value);
}
}
render(){
return (
<div>
<input type="text" ref={input => this.input = input}/>
<button onClick={this.add}>添加</button>
</div>
)
}
}
//指定属性数据类型和必要性
Todo.propTypes = {
add: PropTypes.func.isRequired
}
export default Todo
因为没写什么功能,只作为简单的react项目配置搭建。