webpack 解析 react
项目结构
project
|
|---build < 工程代码 webpack的配置 >
| |
| |--- webpack.config.client.js
|
|---client < 项目代码 >
| |
| |--- app.js < 整个客户端的代码出口,用于和 webpack 连接 >
| |--- app.jsx < react 的入口 >
| |--- template.html < 模版文件 >
|
|---.eslintrc < 工程代码 babel 的配置文件 >
|
需要安装的依赖
npm i \
babel-core \
babel-loader \
babel-preset-es2015 \
babel-preset-es2015-loose \
babel-preset-react \
babel-preset-stage-2 \
html-webpack-plugin \
rimraf \
webpack \
工程目录下 webpack config
// /build/webpack.config.client.js
const path = require('path')
const webpack = require('webpack')
const HTMLPlugin = require('html-webpack-plugin')
module.exports = {
entry: { // 打包文件入口
app: path.join(__dirname, '../client/app.js')
},
output: { // 打包文件出口
filename: '[name].[hash].js',
/*
* app.hash.js
* hash 不同时浏览器会自动刷新缓存,更新当前引用的 js 文件。从而达到最大程度利用长缓存的作用
* [] 内代表变量
* 生成的文件的命名 hash 到达长缓存
*/
path: path.join(__dirname, '../dist'),
/*
* 存储的位置
*/
publicPath: ''
/*
* 作用:区分是请求的后端api,还是静态资源
* publicPath: 'cdn path' 可以把静态资源放在 cdn 上可以直接拿到文件
* /public/ 和 /public 是有区别,注意细节
*/
},
module: {
rules: [
/*
* test 代表匹配的规则
* loader 代表使用对应的 loader 解析匹配的文件
*/
{
test: /.jsx$/,
loader: 'babel-loader'
/*
* babel-loader 只是一个 webpack 和 babel 的桥梁,
* 所以就安装 babel-core babel-preset-env babel-preset-loose-env[这个依赖可以不装,前提是不用他]
*/
},
{
test: /.js$/,
loader: 'babel-loader',
exclude: [ // 除去的部分
path.join(__dirname, '../node_modules')
]
}
]
},
plugins: [
new HTMLPlugin({
template: path.join(__dirname, '../client/template.html') // 把 output 出来的文件 插入指定的 template
}) // 把 output 出来的文件插入到 我们指定的 html 文件中
]
}
- “webpack” 这个插件主要是 在使用 webpack 打包的时候才会用,
- “babel-loader” 是用来配合 webpack 打包之前用来编译 js 代码,他会把 es6 的代码转化成 es5
- “html-webpack-plugin” 用于把 webpack entry 中的静态文件,通过各类插件比如 babel-loader css-loader sass-loader
等插件的处理之后的文件进行压缩之后,插入到一个 html 文件中,这个 html 是我们在浏览器中展示效果的入口
模版文件
用来指定我们想要把打包之后的文件,插入的 html 文件
// /client/template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root"><!-- app --></div>
</body>
</html>
客户端所有内容的入口
// /client/app.js
import ReactDOM from 'react-dom'
import React from 'react' // 即使没有是使用也要引用,只要有 jsx 的写法就要引用
import App from './app.jsx'
ReactDOM.render(
<App />,
document.getElementById('root')
)
react 的入口
// /client/app.jsx
import React from 'react' // 应用入口
export default class App extends React.Component {
componentDidMount() {
// do something
}
render() {
return (<p> this is app.</p>)
}
}
babel 配置
// .babelrc
{
"presets": [ [ "es2015", {"loose": true} ], ["react"], "stage-2"]
}
- 所有的 babel 类型的插件都是需要 babel-core 这个依赖
- “preset” 下的 “es2015” {“loose”: true} “stage-2” 分别对应使用:babel-preset-es2015 babel-preset-es2015-loose babel-preset-stage-2 插件
- “stage-2” 主要支持对 es6 草案二的支持。其中包括 import() 新特性
- “react” 对应使用 babel-preset-react 插件
脚本命令
在 package.json scripts 下添加
"build:client": "webpack --config build/webpack.config.client.js",
"clear": "rimraf dist",
"build": "npm run clear && npm run build:client"