使用webpack配置react并添加到flask应用
学习react,配置是很痛苦的一关,虽然现在有了create-react-app这样方便的工具,但是必须要自己配置一遍,才能更好地进行项目开发。
首先要明确一个概念:react的文件必须经过编译才能被浏览器识别,因此我们需要webpack这个打包工具来把react的组件打包成一个js文件,然后将这个js文件放到flask目录下,然后引入到flask模版的html文件里面。当然,你也可以在前端用express等服务进行客户端渲染,只将flask服务视为一个传递数据的api。
下面开始配置吧
1、如果你的电脑没有安装node.js,先装node.js
brew install node 或者yarn install node
然后查看node和npm的版本检查安装情况,npm是node自带的安装工具
node -v
npm -v
2、npm安装的时候有可能很慢,最好把资源换成淘宝的
npm config set registry https://registry.npm.taobao.org
验证配置是否成功
npm config get registry
3、新建一个空的文件夹作为项目根目录,在项目根目录
npm init
接下来要填的东西按需求填写,也可以之后在package.json中修改
现在根目录多了一个文件package.json,这个是npm的配置文件。之后我们会在这个文件里定义一些npm的脚本。
4、因为我们的项目需要用到webpack和react,先装上
npm install -s webpack
npm install -s react
-s表示会把这个包连同版本号写到package.json的dependencies中,如果加上-d就会把这个包写到devDependencies。package.json中的dependencies与devDependencies两项的区别是:devDependencies中的插件只用于开发环境(development)而不用于生产环境(production),如何在运行的时候指定开发环境或生产环境我们之后会提到。
5、在项目根目录新建一个名为webpack.config.js的文件,这个文件用于配置webpack
const path= require('path')//引用path包。在node_modules中
const HTMLPlugin=require('html-webpack-plugin')
module.exports={
entry:{
app:path.join(__dirname,'/client/main.js')//main.js作为打包的入口,根据main中的依赖关系整体打包
},
output:{//打包后的输出
filename:'[name].[hash].js',//打包后输出的文件名。name就是entry中入口文件的名字,这里是app。
//webpack会根据打包的文件内容计算hash,当文件内容有变动的时候hash值才会变化
//这样的话,没有文件改动的时候不会刷新浏览器缓存
path:path.join(__dirname,'/static'),//输出路径
publicPath:''//静态资源文件引用时的路径,在浏览器中的引用变为'public/app.hash.js'。不太理解
},
module:{
rules:[//rules里可以配很多loader
{
test: /\.jsx?$/,//如何识别jsx类型的文件
loader:'babel-loader'//babel可以将最新js语法编译到低版本
}
]
},
plugins:[
new HTMLPlugin({
template:path.join(__dirname,'/client/template.html')//html模版
})
],
devServer:{
port:'8888',
contentBase:path.join(__dirname,'/static'),//对应打包后输出的path
overlay:{
errors:true//获取到的错误信息会在页面上显示
}
}
}
这样配置的话需要装很多依赖库。首先装上html-webpack-plugin,这是一个可以在webpack输出目录生成一个html页面,同时将打包好的js文件引入页面。如果我们要用webpack-dev-server,这个库必须要装。
然后装上webpack-dev-server,这个服务启动后,访问本机对应的端口就可以看到项目的效果,当你对文件有任何修改时,它会自动编译出js文件与html文件存在内存中,然后调用这些文件渲染出html展示内容。达到的效果就是可以在编辑保存文件后,不用手动执行build,刷新一下页面就可以看到修改后的内容
然后是babel-loader这个库,这个库的作用是将react特有的jsx语言翻译成浏览器可以识别的js语言。装了它之后还要装很多其他的库,之前看教程装了babel-core等库都运行不成功,说版本太旧,所以正确的姿势是装上@babel/core、@babel/preset-react、@babel/preset-env这三个库,然后在根目录新建一个名为.bablerc的babel配置文件,内容是
{
"presets": ["@babel/preset-env","@babel/preset-react"]
}
6、我们开始写一个可以打包的包含react组件的js文件
在项目根目录新建如webpack配置所述的打包入口文件,内容为
import React from 'react';
import ReactDOM from 'react-dom'; class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {
opacity: 1.0,
date:new Date()//new Date()时会获取新的时间
}
}
componentDidMount() {
this.timer = setInterval(function () {
var opacity = this.state.opacity;
opacity -= .1;
if (opacity <= 0) {
opacity = 1.0;
this.setState({
date:new Date()
});
}
this.setState({
opacity: opacity
});
}.bind(this), 100);
}
render() {
return (
<div>
<h1>MyClock</h1>
<h2 style={{opacity: this.state.opacity}}>{this.state.date.toLocaleTimeString()}</h2>
</div>
); //记得要加toLocaleTimeString,报错卡我了20分钟
}
} ReactDOM.render(<Clock />,document.getElementById('root'))
这是一个简单的时钟组件,要注意的是最后返回的时候这个组件是挂在root节点的,但是我们用html-webpack-plugin自动生成的文件是不会生成一个root节点的,因此就需要给它一个模版html,里面包含root节点。如果你问为什么不直接挂在body上,因为挂在body上编译的时候会一直有个warning,很烦,所以我就听它的挂在节点上啦。
html模版如下
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
7、该配置的配置了,需要打包的文件也写好了。现在我们到package.json里写一下npm脚本,然后就可以用npm进行打包或者运行开发服务器了
"scripts": {"build": "rimraf static && webpack --mode=production --config webpack.config.js",
"dev": "webpack-dev-server --mode=development --config webpack.config.js"
},
build是打包命令,dev是运行webpack-dev-server。用 --mode=... 可以设置命令执行在开发环境还是生产环境。rimraf是一个可以删除文件的工具库,我们也把它装上先,它可以帮我们在每一次build之前先把之前生成过的打包文件删除。
8、测试一下
打包:
npm run build
运行开发服务器
npm run dev
9、将打包的js文件引入到flask应用
在项目根目录创建run.py文件,加上一个最简单的路由:
@app.route('/')
def index():
return render_template('1.html')
再创建templates文件夹和该文件夹下的1.html文件,文件内容如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chat</title>
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="{{ url_for('static', filename='app.16d576b97de33ccfcd4f.js') }}"></script>
</body>
</html>
然后运行run.py文件,就可以通过访问flask应用的端口来获取我们写的前端应用了。
这么做就免去了配置前端服务器和配置nginx反向代理的过程,响应速度我个人感觉也不会太慢,但是build之后如果js文件名变化要改1.html中相应的内容。反正开发的时候用webpack-dev-server,测试好了再build。
使用webpack配置react并添加到flask应用的更多相关文章
- [webpack] 配置react+es6开发环境
写在前面 每次开新项目都要重新安装需要的包,简单记录一下. 以下仅包含最简单的功能: 编译react 编译es6 打包src中入口文件index.js至dist webpack配置react+es6开 ...
- webpack配置React开发环境(上)
Webpack 是一个前端资源加载/打包工具,我们部门的一条主要技术栈就是Webpack+React+ES6+node,虽然之前自己做个人项目也接触好多次Webpack,但是自己并没有研读总结过Web ...
- webpack 配置react脚手架(二):热更新
下面继续配置 webpack dev server hot module replacement: 首先配置dev-server 安装 npm i webpack-dev-ser ...
- webpack 配置react脚手架(六):api
1 访问网址 https://cnodejs.org/api 可以调取api 2.//该body-parser 可以将请求的body数据,转变成 json 格式数据://express-session ...
- webpack 配置react脚手架(三):eslint 及优化
首先谨记 eslint的官网: http://eslint.cn/ 1 安装eslint npm i eslint -D 2.在根目录下新建文件 .eslintrc { "extends ...
- webpack 配置react脚手架
1 react 基本js文件: import React from 'react'; import ReactDOM from 'react-dom'; import App from './App. ...
- webpack 配置react脚手架(五):mobx
1. 配置项.使用mobx,因为语法时es6-next,所以先配置 .babelrc 文件 { "presets": [ ["es2015", { " ...
- webpack 配置react脚手架(四):路由配置
1. 由于 react-router 是集成了 react-router-dom 和 react-router-native的一起的,所以这里要使用的是 react-router-dom, 2. 安装 ...
- 手把手教你webpack、react和node.js环境配置(上篇)
很多人刚学习react的时候,往往因为繁琐的配置而头疼,这里我将手把手教大家怎么用webpack配置react和redux的环境,这篇教程包括前端react和后台node整个网站的环境配置,对node ...
随机推荐
- PAT L1-032 Left-pad
https://pintia.cn/problem-sets/994805046380707840/problems/994805100684361728 根据新浪微博上的消息,有一位开发者不满NPM ...
- UserAgent 设置 php 抓取网页
转载:http://www.webkaka.com/tutorial/php/2013/111846/ hp抓取网页,可谓轻而易举,几行代码就可以搞定.不过,如果你有所疏忽,程序写得不够严密,就会出现 ...
- python之enumerate()学习
X = 'abcdefghijklmn' for (index,char) in enumerate(X): print (index, char) 利用enumerate()函数,可以在每次循环中同 ...
- 第138天:Web前端面试题总结(编程)
1.如何让一个盒子水平垂直居中 //已知宽高 <div class="div1"></div> <style> .div1{ width:400 ...
- hdu 6400 Parentheses Matrix
题目链接 Problem Description A parentheses matrix is a matrix where every element is either '(' or ')'. ...
- BZOJ3747 POI2015Kinoman(线段树)
考虑固定左端点,求出该情况下能获得的最大值.于是每次可以在某数第一次出现的位置加上其价值,第二次出现的位置减掉其价值,查询前缀最大值就可以了.每次移动左端点在线段树上更新即可. #include< ...
- 前端跨域问题相关知识详解(原生js和jquery两种方法实现jsonp跨域)
1.同源策略 同源策略(Same origin policy),它是由Netscape提出的一个著名的安全策略.同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正 ...
- 【Luogu3676】小清新数据结构题(动态点分治)
[Luogu3676]小清新数据结构题(动态点分治) 题面 洛谷 题解 先扯远点,这题我第一次看的时候觉得是一个树链剖分+线段树维护. 做法大概是这样: 我们先以任意一个点为根,把当前点看成是一棵有根 ...
- 【BZOJ1443】游戏(二分图匹配,博弈论)
[BZOJ1443]游戏(二分图匹配,博弈论) 题面 BZOJ 题解 很明显的二分图博弈问题. 发现每次移动一定是从一个黑点到达一个白点,或者反过来. 所以可以对于棋盘进行染色然后连边. 考虑一下必胜 ...
- 【CF666E】Forensic Examination(后缀自动机,线段树合并)
[CF666E]Forensic Examination(后缀自动机,线段树合并) 题面 洛谷 CF 翻译: 给定一个串\(S\)和若干个串\(T_i\) 每次询问\(S[pl..pr]\)在\(T_ ...