对于webpack这个项目打包工具,相信大家应该不陌生。我这里也只是了解其优点和基本使用方法,如果想要研究的更加深入,可以去查看(webpack官网),或者可以去瞅瞅我之前看vue2的相关笔记:(Vue学习杂记(四)——webpack的基本使用),这里还是再简单总结一下webpack的基本使用方式:
(1)首先安装第三方依赖webpack
和webpack-cli
(生产环境安装即可);
(2)接下来安装copy-webpack-plugin
和html-webpack-plugin
,前者是用来打包的时候复制特殊文件到指定位置,后者是用来打包时候处理html入口文件的。
(3)然后需要安装webpack-dev-server
,这个是生产环境下用来进行热重载的webpack依赖,当代码更新时会自动重启服务,提高我们的开发效率。
(4)在根目录下创建一个webpack.config.js,这个是webpack的默认配置文件。
下面展示一下文件结构和webpack.config.js
文件配置信息:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
module.exports = {
//指定当前使用的模式是生产模式还是开发模式
mode: "development",
//打包入口文件
entry: {
app: "./src/index.js",
},
//打包出口文件
output: {
path: path.join(__dirname, "./dist"), //只能使用绝对路径
filename: "index.js",
},
//配置插件
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, "./src/index.html"),
filename: "index.html",
inject: true,//是否将入口文件注入到这个html中
}),
//主要是为了处理ico文件,因为ico属于特殊文件,
//不能被webpack自动打包到dist目录下
new CopyWebpackPlugin({
patterns: [{
from: "./src/favicon.ico",
to: path.join(__dirname, "./dist"),
}, ],
}),
],
//配置server
devServer: {
compress: true,
port: 9000,
},
};
需要注意的是,插件中使用的路径,特别是带有输出含义的路径,需要使用绝对路径,因此引入了path模块。为什么不直接将html文件作为入口文件呢,那还不用去迁移,这个主要是现在前端再设计上启动项目的一般是一个app.js的项目启动文件,特别是再vue生态下可以看出。另外,为了方便我们快速启动或者打包项目,可以配置npm 脚本信息(脚本工作原理之前说过,这个就不再赘述了):
"build": "npx webpack",
"start": "npx webpack-dev-server"
为了更好的方便理解和使用node.js,我们来搭建一个node.js的后台环境,算作是一种实战吧,期间将用到art-template模板。加下来说一下如何利用webpack来导入art-template模板,参考官网:(art-template):
(1)下载art-template
模板引擎,需要安装art-template
和art-template-loader
两个依赖,后者是方便使用webpack对项目进行打包;
(2)为了方便快速刷新我们配置webpack-dev-server
和clean-webpack-plugin
第三方依赖,前者自动重启服务,后者每次重启自动删除并重新创建dist文件;
(3)接下来调整项目结构和webpack.config.js
文件:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
mode: "development",
devtool: "source-map",
//用来快速准确定位bug的位置,
//默认打包会使得bug的位置和实际的位置有偏差
//打包入口文件
entry: {
app: "./src/app.js",
},
//打包出口文件
output: {
path: path.join(__dirname, "./dist"), //只能使用绝对路径
filename: "app.js",
},
//导入art-temlate-loader
module: {
rules: [
// 模板文件
{
test: /\.art$/,
loader: "art-template-loader",
},
],
},
//配置插件
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.join(__dirname, "./public/index.html"),
filename: "index.html",
inject: true,
}),
new CopyWebpackPlugin({
patterns: [{
from: "./public/favicon.ico",
to: path.join(__dirname, "./dist"),
}, ],
}),
],
//配置server
devServer: {
// contentBase: path.join(__dirname, "./dist"),
compress: true,
port: 9000,
},
};
配置的时候遇到了一个坑,如果将views目录放置到src目录下,将会导致node_modules的使用出错,因为默认情况下art-template的views文件是放在根目录下的。具体怎么自定义还没有查出来,就放在根目录下吧。
为了节省前台的开发精力,使用(AdminLTE后端模板)里面的页面,同时为了方便管理路由,使用(sme-router),这个路由依赖类似于express框架。因为涉及到的代码比较多,简单说一下开发思路和里面的关键代码:
(1)首先项目依旧使用经典的RMVC模式设计;
(2)另外再来捋一下当前各种依赖的作用:
"devDependencies": {
"art-template-loader": "^1.4.3",//模板引擎打包loader
"clean-webpack-plugin": "^4.0.0",//用来快速刷新dist目录
"copy-webpack-plugin": "^10.2.4",//用来复制文件到指定位置
"html-webpack-plugin": "^5.5.0",//用来处理html页面并执行注入
"webpack": "^5.68.0",//用来打包项目
"webpack-cli": "^4.9.2",//打包工具自己的依赖
"webpack-dev-server": "^4.7.4"//用来自动重启服务
},
"dependencies": {
"art-template": "^4.13.2",//模板引擎
"jquery": "^3.6.0",//juery
"sme-router": "^0.12.8"//路由工具
}
//其他
source-map//方便快速查看bug
AdminLTE//基于bootstrap的模板,减小前端工作量
(3)简单展示一下项目的结构:
说明:在views文件中存放剥离掉html和body标签的html代码块,在index.html中设置代码块对应的“插座” :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>测试首页</title>
<!-- Google Font: Source Sans Pro -->
<!-- <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback"> -->
<!-- Font Awesome -->
<link rel="stylesheet" href="./libs/css/all.min.css">
<link rel="stylesheet" href="./libs/css/ionicons.min.css">
<link rel="stylesheet" href="./libs/css/icheck-bootstrap.min.css">
<link rel="stylesheet" href="./libs/css/adminlte.min.css">
<link rel="stylesheet" href="./libs/webfonts/font.css">
<link rel="stylesheet" href="./libs/css/jqvmap.min.css">
<link rel="stylesheet" href="./libs/css/OverlayScrollbars.min.css">
<link rel="stylesheet" href="./libs/css/tempusdominus-bootstrap-4.min.css">
<link rel="stylesheet" href="./libs/css/summernote-bs4.min.css">
<link rel="stylesheet" href="./libs/css/daterangepicker.css">
<link rel="stylesheet" href="./libs/webfonts/fa-regular-400.woff2">
<link rel="stylesheet" href="./libs/webfonts/fa-solid-900.woff2">
<style>
.login-page {
align-items: center;
background-color: #e9ecef;
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
height: 100vh;
-ms-flex-pack: center;
justify-content: center;
}
</style>
</head>
<body class="hold-transition sidebar-mini">
<div id="root"></div>
<!-- jQuery -->
<script src="./libs/js/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="./libs/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
<script src="./libs/js/adminlte.min.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="./libs/js/demo.js"></script>
</body>
</html>
libs下面存放各种静态资源依赖,展示webpack配置文件:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
mode: "development",
devtool: "source-map",
//打包入口文件
entry: {
"js/app": path.join(__dirname, "./src/app.js"),
},
//打包出口文件
output: {
path: path.join(__dirname, "./dist"), //只能使用绝对路径
filename: "[name].js",
},
module: {
rules: [
// 模板文件
{
test: /\.art$/,
loader: "art-template-loader",
},
],
},
//配置插件
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.join(__dirname, "./public/index.html"),
filename: "index.html",
inject: true,
}),
new CopyWebpackPlugin({
patterns: [{
from: "./public/favicon.ico",
to: path.join(__dirname, "./dist"),
},
{
from: "./public/libs/",
to: path.join(__dirname, "./dist/libs/"),
},
],
}),
],
//配置server
devServer: {
compress: true,
port: 9000,
},
};
路由的基本使用:
//src/router/index.js
import SMERouter from "sme-router";
import index from "../controllers/index";
import login from "../controllers/login";
//放入代码块插座
const router = new SMERouter("root");
router.route("/", index);
router.route("/login", login);
export default router;
//src/controllers/index.js
import indexTpl from "../../views/index.art";
const indexHtml = indexTpl({});
const index = (req, res, next) => {
res.render(indexHtml);
};
export default index;
需要注意的是配置完成路由之后,路由不会自动匹配,需要使用router.go("/");跳转到指定路由,其次对于模块的导出,需要使用eport default
。
这样整个项目的初步搭建就算是完成了,接下来就是后端的路由和数据传输了。对于前端来说,已经写了太多的前端页面了,后端的话其实在thinkPHP的时候也熟悉了简单的CRUD,后端其他笔记等之后有时间再进一步更新,因为要考研了,可能看这些的时间会少一些。如果你看到了这里,很感谢你,因为你的阅读是我更新的动力,其实我自己也没想到,node.js的笔记阅读量会有这么多,最后还得感谢B站古艺散人
提供的视频教程。