技术栈
- react+webpack 支持前台编写。node+mysql做后台维护
- 使用ts,包括了tsc,bable7,antd
- 使用mysql,koa-route 做路由
react+webpack配置
由于使用bable7 ,所以直接使用.babelrc 解析react、ts、es6高级语法
.babelrc相关配置如下,此文件位于项目根目录下。
//.babelrc
{
"presets": [
[
"@babel/preset-env",
{
"modules": false
}
],
["@babel/preset-react"],
["@babel/preset-typescript"]
],
"plugins": [
[
"import",
{
"libraryName": "antd"
}
],
[
"@babel/plugin-proposal-class-properties",
{
"loose": true
}
],
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
"@babel/plugin-syntax-dynamic-import"
]
}
同样需要配置tsconfig.json,此文件位于项目根目录下。内容如下
{
"compilerOptions": {
"outDir": "./dist",
"module": "esnext",
"target": "es5",
"lib": [
"es6",
"dom"
],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"allowUnreachableCode": true,
"noImplicitAny": false
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules"
]
}
这是基础配置,接下来是配置webpack.config.js,此文件位于项目根目录下
区分了开发和线上环境
if (process.env.NODE_ENV === "development") {
module.exports = require("./config/webpackconfig");
} else {
module.exports = require("./config/webpackconfig");
}
根据webpack.config.js中文件的路径,新建生产和线上的webpack 配置,有几个小知识点,
1、使用了happypack ,直接打包了babel-loader
2.1、output.path是硬盘文件路径
2.2、output.publicPath配置的是打包文件输出的访问路径
3、const MiniCssExtractPlugin = require(“mini-css-extract-plugin”);这个可以将.tsx中引入的.less 文件拆分出来
4、const HtmlWebpackPlugin = require(“html-webpack-plugin”);可以根据你设置的路径在dist中生成.html模版,并且将3中拆分出来的less 引入到dist/index.html中
5、new webpack.optimize.OccurrenceOrderPlugin(), new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin(),
这三个是是用于koa-webpack-dev-middleware热更新的,随后配置后端的时候,会再提到
下面是webpack 代码
const path = require("path");
const webpack = require("webpack"); // 加载webpack 中的模块
const HappyPack = require("happypack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const os = require("os");
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const nodeEnv = "development";
module.exports = {
mode: process.env.NODE_ENV,
entry: {
index: [
"@babel/polyfill",
"webpack-hot-middleware/client?noInfo=true",
"./src/index.tsx"
]
},
output: {
path: path.join(__dirname, "../dist"),
publicPath: "/dist/",
filename: "js/[name].js",
chunkFilename: "js/[name].chunk.js"
},
module: {
rules: [
{
test: /\.(js?|ts?|jsx?|tsx?)$/,
exclude: /node_modules/,
use: ["happypack/loader?id=babel"]
},
{
test: /\.(c|le)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: process.env.NODE_ENV === "development"
//reloadAll: true,
}
},
"css-loader",
"postcss-loader",
"less-loader"
]
}
]
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify(nodeEnv),
NODE_LOCATION: JSON.stringify(process.env.NODE_ENV)
}
}),
new HappyPack({
id: "babel",
loaders: [
{
loader: "babel-loader"
}
],
threadPool: happyThreadPool
}),
new MiniCssExtractPlugin({
filename: "css/[name].css",
chunkFilename: "css/[name].css",
ignoreOrder: false
}),
new HtmlWebpackPlugin({
filename: "index.html",
template: "index.html",
inject: true
})
],
resolve: {
//有些不同的模块会区分不同的代码这里决定使用哪份代码,例如es6 and es5
mainFiles: ["index.web", "index"],
modules: [path.resolve(__dirname, "src"), "node_modules"],
// 添加让webpack 解析的后缀 例如 ./entry ,优先匹配entry.ts,entry.tsx,最后是entry.js
extensions: [".ts", ".tsx", ".js", ".json", ".less", ".css"]
},
performance: {
hints: false
}
};
总的来说,react+webpack 前半部分基本上就是这样了
package.json 启动脚本是这样的
"start": "cross-env NODE_ENV=development nodemon --watch 'server_koa.js' -e ts,tsx --exec 'ts-node' ./server_koa.js ",
koa_server.js,在后半部分详细介绍,启动http 服务,做接口请求。
nodemon 检测server_koa.js,支持检测路径’server/**/*’,当使用ts 编写后台时,可以直接重新编译,然后重启ts-node’ ./server_koa.js 服务
======================手动分割线=
现在是重中之重koa2+node +koaroute路由做接口
koa2 是轻量级的服务器接口
- koa2 中没有像express中可以直接使用use,或者get 拦截处理路由,需要使用const Router = require(“koa-router”);做路由分发,也可以自己做这一步,不过麻烦
- koa2 中同样没有静态文件分发,需要使用const send = require(“koa-send”);进行react打包的js 和less 进行模版发送,就是webpack 中从.tsx中抽离出来的js 和less 。也有资源说可以使用koa-static,但是,但是我这里加在不出来js和less,报错404.所以最后问同事才了解到koa-send。koa-static是继承实现koa-send,所以问题不大。
下面就是这一块代码,/dist/是webpack 中 output.publicpath 路径,检测系统访问的时候分发文件资源,
/test/是项目文件,就是react route 的路径,也就是浏览器地址栏的路径
这里配置中间件的格式,返回我们配置的模版,所有的访问路径都会经过这个中间件
router.get("/dist/*", async (ctx, next) => {
await send(ctx, ctx.path);
});
// app.use(static(__dirname + "/dist/", { extensions: ["html"] }));
router.get("/test/*", async (ctx, next) => {
ctx.type = "html";
ctx.body = fs.createReadStream("dist/index.html");
await next();
});
nodemon 是检测server,也就是用ts 写的node后台。现在使用
const webpackDevMiddleware = require("koa-webpack-dev-middleware");
const webpackHotMiddleware = require("koa-webpack-hot-middleware");
const wdm = webpackDevMiddleware(compiler, {
noInfo: true,
publicPath: config.output.publicPath
});
app.use(wdm);
app.use(webpackHotMiddleware(compiler));
这两块内容来对.tsx 文件进行热更新。webpackDevMiddleware这个板块中的必须注明 publicPath: config.output.publicPath这个路径,否则不能进行文件热更新,因为找不到更改的文件对应的板块,出现的问题就是hot-update.json找不到,这个链接中注明了publicPath必须写明的原因。
还有就是config/webpackconfig.js 中使用的那三个插件
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
注意npm 官网上的这三个插件名称不正确,会直接在webpack 编译中直接报错,拿着报错信息自行百度一下就会有结果。
明天继续…
来源:CSDN
作者:艾离
链接:https://blog.csdn.net/weixin_42946929/article/details/103464389