通过 vue.config.js 修改 webpack 的默认配置
通过 chainWebpack 自定义打包入口
module.exports = {
lintOnSave: false,
chainWebpack: config => {
config.when(process.env.NODE_ENV === "production", config => {
config
.entry("app")
.clear()
.add("./src/main-prod.js")
})
config.when(process.env.NODE_ENV === "development", config => {
config
.entry("app")
.clear()
.add("./src/main-dev.js")
})
}
}
注意 lintOnSave: false, 不可以去掉,不然无法运行
然后新建 main-dev.js 和 main-prod.js 两个入口文件
通过external 加载外部资源
module.exports = {
lintOnSave: false,
chainWebpack: config => {
config.when(process.env.NODE_ENV === "production", config => {
config
.entry("app")
.clear()
.add("./src/main-prod.js")
config.set("externals", {
vue: "Vue",
"vue-router": "VueRouter",
axios: "axios",
lodash: "_",
echarts: "echarts",
nprogress: "NProgress",
"vue-quill-editor": "VueQuillEditor"
})
})
config.when(process.env.NODE_ENV === "development", config => {
config
.entry("app")
.clear()
.add("./src/main-dev.js")
})
}
}
import Vue from "vue"
import "./plugins/axios"
import App from "./App.vue"
import router from "./router"
// import "./plugins/element.js"
// 导入 字体图标
import "./assets/fonts/iconfont.css"
// 导入全局样式表
import "./assets/css/global.css"
// 引入第三方树形组件
import TreeTable from "vue-table-with-tree-grid"
// 导入富文本编辑器
import VueQuillEditor from "vue-quill-editor"
// 导入样式
// import "quill/dist/quill.core.css" // import styles
// import "quill/dist/quill.snow.css" // for snow theme
// import "quill/dist/quill.bubble.css" // for bubble theme
// 导入对应的 js 和 css
import NProgress from "nprogress"
// import "nprogress/nprogress.css"
// 引入 axios
import axios from "axios"
// 配置请求的根路径
axios.defaults.baseURL = "http://127.0.0.1:8888/api/private/v1/"
// 在 request 拦截器中,展示进度条 NProgress.start();
axios.interceptors.request.use(config => {
// console.log(config)
NProgress.start()
config.headers.Authorization = window.sessionStorage.getItem("token")
// 在最后必须 return config
return config
})
// 在 response 拦截器中,隐藏进度条 NProgress.done();
axios.interceptors.response.use(config => {
NProgress.done()
return config
})
Vue.prototype.$http = axios
Vue.config.productionTip = false
Vue.component("tree-table", TreeTable)
Vue.use(VueQuillEditor /* { default global options } */)
Vue.filter("dateFormat", function(origunVal) {
const dt = new Date(origunVal)
const y = dt.getFullYear()
const m = (dt.getMonth() + 1 + "").padStart(2, "0")
const d = (dt.getDate() + "").padStart(2, "0")
const hh = (dt.getHours() + "").padStart(2, "0")
const mm = (dt.getMinutes() + "").padStart(2, "0")
const ss = (dt.getSeconds() + "").padStart(2, "0")
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
})
new Vue({
router,
render: h => h(App)
}).$mount("#app")
首页内容自定制
module.exports = {
lintOnSave: false,
chainWebpack: config => {
config.when(process.env.NODE_ENV === "production", config => {
config
.entry("app")
.clear()
.add("./src/main-prod.js")
config.set("externals", {
vue: "Vue",
"vue-router": "VueRouter",
axios: "axios",
lodash: "_",
echarts: "echarts",
nprogress: "NProgress",
"vue-quill-editor": "VueQuillEditor"
})
config.plugin("html").tap(args => {
args[0].isProd = true
return args
})
})
config.when(process.env.NODE_ENV === "development", config => {
config
.entry("app")
.clear()
.add("./src/main-dev.js")
config.plugin("html").tap(args => {
args[0].isProd = false
return args
})
})
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title>
<%= htmlWebpackPlugin.options.isProd? '':'dev - ' %> 电商后台管理系统
</title>
<% if(htmlWebpackPlugin.options.isProd) { %>
<!-- nprogress 的样式表文件 -->
<link
rel="stylesheet"
href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css"
/>
<!-- 富文本编辑器 的样式表文件 -->
<link
rel="stylesheet"
href="https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css"
/>
<link
rel="stylesheet"
href="https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css"
/>
<link
rel="stylesheet"
href="https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css"
/>
<!-- element-ui 的样式表文件 -->
<link
rel="stylesheet"
href="https://cdn.staticfile.org/element-ui/2.8.2/theme-chalk/index.css"
/>
<script src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script>
<script src="https://cdn.staticfile.org/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.staticfile.org/lodash.js/4.17.11/lodash.min.js"></script>
<script src="https://cdn.staticfile.org/echarts/4.1.0/echarts.min.js"></script>
<script src="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js"></script>
<!-- 富文本编辑器的 js 文件 -->
<script src="https://cdn.staticfile.org/quill/1.3.4/quill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.4/dist/vue-quill-editor.js"></script>
<!-- element-ui 的 js 文件 -->
<script src="https://cdn.staticfile.org/element-ui/2.8.2/index.js"></script>
<%}%>
</head>
<body>
<noscript>
<strong
>We're sorry but vue_shop doesn't work properly without JavaScript
enabled. Please enable it to continue.</strong
>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
在开发环境下,改变标题,不引入外部 cdn
路由懒加载
https://router.vuejs.org/zh/guide/advanced/lazy-loading.html
先安装插件
如果您使用的是 Babel,你将需要添加 syntax-dynamic-import
插件,才能使 Babel 可以正确地解析语法。
// 这是项目发布阶段需要用到的 babel 插件
const prodPlugins = []
if (process.env.NODE_ENV === 'production') {
prodPlugins.push('transform-remove-console')
}
module.exports = {
"presets": [
"@vue/cli-plugin-babel/preset"
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
],
// 发布产品时候的插件数组
...prodPlugins,
'@babel/plugin-syntax-dynamic-import'
]
}
import Vue from "vue"
import VueRouter from "vue-router"
// import Login from "../components/Login.vue"
const Login = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Login.vue')
// import Home from "../components/Home.vue"
const Home = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Home.vue')
// import Welcome from "../components/Welcome.vue"
const Welcome = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Welcome.vue')
// import Users from "../components/user/Users.vue"
const Users = () => import(/* webpackChunkName: "Users_Rights_Roles" */ '../components/user/Users.vue')
// import Rights from "../components/power/Right.vue"
const Rights = () => import(/* webpackChunkName: "Users_Rights_Roles" */ '../components/power/Right.vue')
// import Roles from "../components/power/Roles.vue"
const Roles = () => import(/* webpackChunkName: "Users_Rights_Roles" */ '../components/power/Roles.vue')
// import Cate from "../components/goods/Cate.vue"
const Cate = () => import(/* webpackChunkName: "Cate_params" */ '../components/goods/Cate.vue')
// import Params from "../components/goods/Params.vue"
const Params = () => import(/* webpackChunkName: "Cate_params" */ '../components/goods/Params.vue')
// import GoodsList from "../components/goods/List.vue"
const GoodsList = () => import(/* webpackChunkName: "GoodsList_add" */ '../components/goods/List.vue')
// import Add from "../components/goods/Add.vue"
const Add = () => import(/* webpackChunkName: "Cate_params" */ '../components/goods/Add.vue')
// import Order from "../components/order/Order.vue"
const Order = () => import(/* webpackChunkName: "Order_Report" */ '../components/order/Order.vue')
// import Report from "../components/report/Report.vue"
const Report = () => import(/* webpackChunkName: "Order_Report" */ '../components/report/Report.vue')
Vue.use(VueRouter)
const routes = [
{ path: "/", redirect: "/login" },
{
path: "/login",
component: Login
},
{
path: "/home",
component: Home,
redirect: "/welcome",
children: [
{
path: "/welcome",
component: Welcome
},
{
path: "/users",
component: Users
},
{
path: "/rights",
component: Rights
},
{
path: "/roles",
component: Roles
},
{ path: "/categories", component: Cate },
{ path: "/params", component: Params },
{ path: "/goods", component: GoodsList },
{ path: "/goods/add", component: Add },
{ path: "/orders", component: Order },
{ path: "/reports", component: Report }
]
}
]
const router = new VueRouter({
routes
})
// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
// to 将要访问的路径
// from 代表从哪个路径跳转而来
// next 是一个函数, 表示放行
// next() 放行 next('/login') 强制跳转
if (to.path == "/login") return next()
// 获取 token
const tokenStr = window.sessionStorage.getItem("token")
if (!tokenStr) return next("/login")
next()
})
export default router
项目上线
通过 node 创建 web 服务器
新建一个node项目
npm init -y
依赖
npm i express -S
把dist文件夹复制过来
新建一个 app.js文件
const express = require('express')
const app = express()
app.use(express.static('./dist'))
app.listen(80, ()=>{
console.log('server running at http://127.0.0.1');
})
sudo node app.js
访问 localhost 即可
开启 gzip 配置
npm i compression -S
const express = require('express')
const compression = require('compression')
const app = express()
// 一定把这一行代码写到 静态代码托管之前
app.use(compression())
app.use(express.static('./dist'))
app.listen(80, ()=>{
console.log('server running at http://127.0.0.1:80');
})
HTTPS 服务
https://freessl.org/
const express = require('express')
const compression = require('compression')
const https = require('https')
const fs = require('fs')
const app = express()
const options = {
cert: fs.readFileSync('./full_chain.pem'),
key: fs.readFileSync('./private.key')
}
// 一定把这一行代码写到 静态代码托管之前
app.use(compression())
app.use(express.static('./dist'))
// app.listen(80, ()=>{
// console.log('server running at http://127.0.0.1:80');
// })
https.createServer(options, app).listen(443)
使用pm2
sudo npm install -g pm2
sudo pm2 start app.js --name web_vue_shop
sudo pm2 list 就可以查看当前运行的项目了