VUE2.7项目配置webpack打包-详细操作步骤
一、Webpack简介
Webpack是一个打包工具,可以把JS、CSS、Node Module、Coffeescrip、SCSS/LESS、图片等都打包在一起,因此,现在几乎所有的SPA项目、JS项目都会用到Webpack。
官网:https://webpack.js.org
GitHub为https://github.com/webpack/ webpack
二、创建基于Webpack的Vue2.7.js项目
Webpack+Vue.js的方式来做项目的,这样才可以做到“视图”“路由”“component”等的分离,以及快速打包、部署及项目上线。
1. Webpack 的相关命令,以及项目常用到的命令,我全部放这里,请务必按照版本安装!!!
"cross-env": "^7.0.2",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.70.0",
"webpack-dev-server": "^4.7.4"
"compression-webpack-plugin": "^9.2.0",
"css-loader": "^4.1.0",
"friendly-errors-webpack-plugin": "^1.7.0",
"is-glob": "^4.0.3",
"monaco-editor": "^0.27.0",
"monaco-editor-webpack-plugin": "^4.2.0",
"process": "^0.11.10",
"style-loader": "^3.3.1",
"stylus-loader": "^6.2.0",
"vue-loader": "^15.11.1",
"vue-style-loader": "^4.1.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.10.0",
"webpack-merge": "^5.8.0",
"webpackbar": "^5.0.2"
"cross-env": "^7.0.2",
package.json代码:
"scripts": {"build:private": "cross-env CONFIG_ENV=private webpack --config build/webpack.prod.js","start:private": "cross-env CONFIG_ENV=private webpack-dev-server --open --hot --config ./build/webpack.dev.js"},
2. 文件配置
看下文件目录结构:
1)build/config.js文件:
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.const path = require('path')let env
switch (process.env.CONFIG_ENV) {case 'local':env = require('../config/local.env')breakcase 'dev':env = require('../config/dev.env')breakcase 'stage':env = require('../config/stage.env')breakcase 'pro':env = require('../config/prod.env')breakcase 'private':env = require('../config/private.env')breakdefault:break
}module.exports = {shouldAnalyzerBundle: false,shouldSplitChunks: false,shouldGzipResource: false,htmlWebpackConfig: {// author: 'AnbanTech@FrontendTeam',// license: 'Copyright © 2019-2022 Anban Inc. All Rights Reserved. 安般科技.',title: '报告'// keywords: 'webpack, vue',// descritpion: 'learn how to config webpack to build vue project'}
}
2)build/webpack.base.js文件:(重点分析)
const path = require('path')
const { resolve } = path
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { htmlWebpackConfig, shouldSplitChunks } = require('./config')
const WebpackBar = require('webpackbar')
const { VueLoaderPlugin } = require('vue-loader')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')const isDev = process.env.NODE_ENV !== 'production'
function genereateAssetsLoader(shouldSplitChunks) {if (shouldSplitChunks) {return [{test: /\.(woff|woff2|eot|otf|ttf)$/,type: 'asset',generator: {filename: 'font/[hash][ext][query]'}},{test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,type: 'asset/resource',generator: {filename: 'images/[hash][ext][query]'}},{test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,type: 'asset/resource',generator: {filename: 'media/[hash][ext][query]'}}]} else {return [{test: /\.(woff|woff2|eot|otf|ttf)$/,type: 'asset/inline'},{test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,type: 'asset/inline'},{test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,type: 'asset/inline'}]}
}module.exports = {target: 'web',stats: {chunks: false,chunkModules: false,modules: false,children: false,timings: false,assetsSort: 'name',performance: false},entry: {app: resolve('src/main.ts')},output: {path: resolve('dist'),filename: shouldSplitChunks ? 'lib/[name].[chunkhash:8].js' : 'lib/bundle.js',publicPath: './',clean: true},resolve: {extensions: ['.js', '.vue', '.json', '.ts'],alias: {'@': path.resolve('src'),vue$: 'vue/dist/vue.esm.js'}},module: {rules: [{test: /\.ts$/,loader: 'ts-loader',exclude: /node_modules/,options: {appendTsSuffixTo: [/\.vue$/],transpileOnly: true}},{test: /\.vue$/,loader: 'vue-loader'},{test: /\.js$/,loader: 'babel-loader',options: {cacheDirectory: true},exclude: /node_modules/},{test: /\.md/,type: 'asset/source'},{test: /\.styl(us)?$/,use:!shouldSplitChunks || isDev? ['vue-style-loader', 'css-loader', 'stylus-loader']: [MiniCssExtractPlugin.loader, 'css-loader', 'stylus-loader']},{test: /\.css$/,use:!shouldSplitChunks || isDev? ['vue-style-loader', 'css-loader']: [MiniCssExtractPlugin.loader, 'css-loader']}].concat(genereateAssetsLoader(shouldSplitChunks))},plugins: [new MonacoWebpackPlugin({languages: ['c']}),new VueLoaderPlugin(),new HtmlWebpackPlugin(Object.assign({}, htmlWebpackConfig, {filename: 'index.html',title: 'webpack测试',template: path.resolve('public/index.html'),minify: {removeAttributeQuotes: true,collapseWhitespace: true,removeComments: true,collapseBooleanAttributes: true,collapseInlineTagWhitespace: true,removeRedundantAttributes: true,removeScriptTypeAttributes: true,removeStyleLinkTypeAttributes: true,minifyCSS: true,minifyJS: true,minifyURLs: true,useShortDoctype: true}})),shouldSplitChunks &&new MiniCssExtractPlugin({filename: 'css/[name].[contenthash:8].css',chunkFilename: 'css/[name].[contenthash:8].css'}),new CopyWebpackPlugin({patterns: [{from: resolve('public'),globOptions: {ignore: ['**/index.html', '**/.DS_Store']}},{from: path.resolve(__dirname, '../static'),to: 'static',globOptions: {ignore: ['.*']}}]}),new WebpackBar({name: '正在打包',color: '#fa8c16'}),new FriendlyErrorsWebpackPlugin({clearConsole: true}),// new BundleAnalyzerPlugin({// analyzerHost: '127.0.0.1',// // 将在“服务器”模式下使用的端口启动HTTP服务器。// analyzerPort: 8888, // // 路径捆绑,将在`static`模式下生成的报告文件。// // 相对于捆绑输出目录。// reportFilename: 'report.html',// defaultSizes: 'parsed',// // 在默认浏览器中自动打开报告// openAnalyzer: true,// // 如果为true,则Webpack Stats JSON文件将在bundle输出目录中生成// generateStatsFile: false, // // 如果`generateStatsFile`为`true`,将会生成Webpack Stats JSON文件的名字。// // 相对于捆绑输出目录。// statsFilename: 'stats.json',// // stats.toJson()方法的选项。// // 例如,您可以使用`source:false`选项排除统计文件中模块的来源。// // 在这里查看更多选项:https: //github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21// statsOptions: null,// logLevel: 'info' // 日志级别。可以是'信息','警告','错误'或'沉默'。// })].filter(Boolean)
}
2)build/webpack.dev.js文件:(重点分析)
const webpack = require('webpack')
const path = require('path')
const { default: merge } = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base')
const config = require('./config')let env
switch (process.env.CONFIG_ENV) {case 'local':env = require('../config/local.env')breakcase 'dev':env = require('../config/dev.env')breakcase 'stage':env = require('../config/stage.env')breakcase 'pro':env = require('../config/prod.env')breakcase 'private':env = require('../config/private.env')breakdefault:break
}module.exports = merge(baseWebpackConfig, {mode: 'development',devtool: 'eval-cheap-module-source-map',cache: true,devServer: {static: false,devMiddleware: {publicPath: '/'},historyApiFallback: {rewrites: [{ from: /.*/, to: path.posix.join('/', 'index.html') }]},hot: true,compress: true,host: 'localhost',// 配置开发服务器的端口,默认为8080port: 3000,open: true,proxy: {'/Arrgemnt': {target: 'http://192.168.5.32:8031',// target: 'http://192.168.50.94:9050',changeOrigin: true},'/files': {target: 'http://192.168.5.32:21101',// target: 'http://192.168.50.94:9050',changeOrigin: true,pathRewrite: { '^/files': '' }},'/yh': {target: 'http://192.168.5.57:9050',// target: 'http://192.168.50.94:9050',changeOrigin: true},'/yh/analysis': {target: 'http://192.168.5.57:9050',ws: true,changeOrigin: true},'/abfuzz/': {target: 'http://192.168.5.57:21101',changeOrigin: true},},client: {logging: 'warn',overlay: false,progress: true,reconnect: true}},plugins: [new webpack.DefinePlugin({'process.env': env}),new webpack.ProvidePlugin({process: require.resolve('process/browser')})]
})
3)build/webpack.prod.js文件:
const webpack = require('webpack')
const { default: merge } = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base')
const CompressionPlugin = require('compression-webpack-plugin')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const { shouldAnalyzerBundle, shouldGzipResource, shouldSplitChunks } = require('./config')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')let env
switch (process.env.CONFIG_ENV) {case 'local':env = require('../config/local.env')breakcase 'dev':env = require('../config/dev.env')breakcase 'stage':env = require('../config/stage.env')breakcase 'pro':env = require('../config/prod.env')breakcase 'private':env = require('../config/private.env')breakdefault:break
}console.log('process.env.CONFIG_ENV:', process.env.CONFIG_ENV)module.exports = merge(baseWebpackConfig, {mode: 'production',devtool: 'nosources-source-map', // productioncache: false,plugins: [new webpack.DefinePlugin({'process.env': env}),new webpack.ProvidePlugin({process: require.resolve('process/browser')}),shouldGzipResource &&new CompressionPlugin({filename: '[path][base].gz',algorithm: 'gzip',test: /\.(js|css)$/}),shouldAnalyzerBundle &&new BundleAnalyzerPlugin({analyzerMode: 'server',analyzerHost: '127.0.0.1',analyzerPort: 8889,reportFilename: 'report.html',defaultSizes: 'parsed',openAnalyzer: true,generateStatsFile: false,statsFilename: 'stats.json',statsOptions: null,logLevel: 'info'})].filter(Boolean),optimization: shouldSplitChunks? {runtimeChunk: true,minimize: true,minimizer: [`...`, new CssMinimizerPlugin()],splitChunks: {chunks: 'all',minChunks: 1,maxInitialRequests: 6,maxAsyncRequests: 6,cacheGroups: {commons: {test: /[\\/]node_modules[\\/]/,name: 'vendors',chunks: 'all'}}}}: {}
})
4)config/dev.env.js文件:
'use strict'
const { default: merge } = require('webpack-merge')
const prodEnv = require('./prod.env')module.exports = merge(prodEnv, {NODE_ENV: '"development"',BASE_API: '"user-test.cosec.tech"',BASE_IP: '"47.100.28.180"',CONFIG_ENV: '"dev"'
})
5)config/local.env.js文件:
'use strict'
const { default: merge } = require('webpack-merge')
const prodEnv = require('./prod.env')module.exports = merge(prodEnv, {NODE_ENV: '"development"',BASE_API: '""',BASE_IP: '""',CONFIG_ENV: '"local"'
})
6)config/poc.env.js文件:
'use strict'
const { default: merge } = require('webpack-merge')
const prodEnv = require('./prod.env')module.exports = merge(prodEnv, {NODE_ENV: '"development"',BASE_API: '""',BASE_IP: '""',CONFIG_ENV: '"private"'
})
7)config/private.env.js文件:
const { default: merge } = require('webpack-merge')
const prodEnv = require('./prod.env')module.exports = merge(prodEnv, {NODE_ENV: '"development"',BASE_API: '""',BASE_IP: '""',CONFIG_ENV: '"private"'
})
8)config/prod.env.js文件:
'use strict'
module.exports = {NODE_ENV: '"development"',BASE_API: '"www.fuzzing.tech"',BASE_IP: '"43.248.189.190"',CONFIG_ENV: '"pro"'
}
9)config/stage.env.js文件:
'use strict'module.exports = {NODE_ENV: '"development"',BASE_API: '"user-stage.cosec.tech"',BASE_IP: '"47.101.189.106"',CONFIG_ENV: '"stage"'
}
9)public/index.vue
<!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 type="image/x-icon" rel="shortcut icon" href="data:;"><link type="image/x-icon" rel="shortcut icon" href="../logo.png"> <title><%= htmlWebpackPlugin.options.title %></title><meta name="author" content="<%= htmlWebpackPlugin.options.author %>"><meta name="license" content="<%= htmlWebpackPlugin.options.license %>"><meta name="description" content="<%= htmlWebpackPlugin.options.descritpion %>"><meta name="keywords" content="<%= htmlWebpackPlugin.options.keywords %>"><script src=./lib/data.js></script></head><body><div id="app"></div>
</body></html>
10) static 文件下有图片昂;
3.运行命令和打包命令:
npm run start:private
npm run build:private
完结撒花✿✿ヽ(°▽°)ノ✿
其实我写的过程,不断地出现报错,坚持住,不断地解决掉!!
当前配置有些冗余的代码文件,后续还需要优化
代码放在了gitee上: git@gitee.com:cathyli2021/vue2.7_webpack.git
相关文章:

VUE2.7项目配置webpack打包-详细操作步骤
一、Webpack简介 Webpack是一个打包工具,可以把JS、CSS、Node Module、Coffeescrip、SCSS/LESS、图片等都打包在一起,因此,现在几乎所有的SPA项目、JS项目都会用到Webpack。 官网:https://webpack.js.org GitHub为https://git…...

Linux系统Docker部署Apache Superset并实现远程访问详细流程
目录 前言 1. 使用Docker部署Apache Superset 1.1 第一步安装docker 、docker compose 1.2 克隆superset代码到本地并使用docker compose启动 2. 安装cpolar内网穿透,实现公网访问 3. 设置固定连接公网地址 前言 作者简介: 懒大王敲代码࿰…...

Cochrane Library循证医学数据库的介绍及文献下载
今天要讲的数据库是Cochrane Library循证医学数据库,我们先来了解一下该数据库: Cochrane Library是国际Cochrane Collaboration的主要产品,由英国Wiley InterScience公司出版发行。是一个提供高质量证据的数据库,是循证医学的证…...

冯喜运:6.12今日黄金原油行情还会涨吗?黄金原油独家操作策略
【黄金消息面分析】:据荷兰国际集团(ING)大宗商品策略师埃瓦?曼西(Ewa Manthey)称,黄金价格正面临来自美元走强和中国需求疲软的新阻力,但一旦美联储开始降息,黄金价格将恢复反弹。 【黄金技术面分析】:黄金…...

VM ubuntu终端使用Host代理的方法
1、设置网络地址转换NAT 2、在终端敲击如下命令 先敲击 ip route show 找到网关。再敲击如下命令: export http_proxyhttp://10.0.2.2:33210 export https_proxyhttp://10.0.2.2:33210 export HTTP_PROXYhttp://10.0.2.2:33210/ export HTTPS_PROXYhttp://10.0.2.…...
【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 破译犯罪时间(100分) - 三语言AC题解(Python/Java/Cpp)
🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 破译犯罪时间(100分) 🌍 评测功能需要订阅专栏后私信联系清…...

大模型学习之GLM结构
探索GLM:一种新型的通用语言模型预训练方法 随着人工智能技术的不断进步,自然语言处理(NLP)领域也迎来了革命性的发展。OpenAI的ChatGPT及其后续产品在全球范围内引起了广泛关注,展示了大型语言模型(LLM&a…...
C#类库打包支持多个版本的类库
修改csproj <Project Sdk"Microsoft.NET.Sdk"><PropertyGroup><TargetFrameworks>netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks><PackageId>xxxx</PackageId><Version>1.0.0</Version><Author…...

一文介绍暗区突围手游 游戏特色、具体玩法和独特的玩法体验
🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 《暗区突围》是一款由腾讯魔方工作室群开发的第一人称射击游戏,于 2022 年 7 月 13 日正式公测,支持 Android 和 iOS 平台。这款游戏以从虚构的暗区收集物资并安全撤离作为最终目…...

Unity基础(三)3D场景搭建
目录 简介: 一.下载新手资源 二.创建基本地形 三.添加场景细节 四,添加水 五,其他 六. 总结 简介: 在 Unity 中进行 3D 场景搭建是创建富有立体感和真实感的虚拟环境的关键步骤。 首先,需要导入各种 3D 模型资源,如建筑物、角色、道具等。这些模…...

在Spring Boot中使用Sa-Token实现路径拦截和特定接口放行
在Spring Boot中使用Sa-Token实现路径拦截和特定接口放行 很喜欢的一段话:别想太多,好好生活,也许日子过着过着就会有答案,努力走着走着就会有温柔的着落。 春在路上,花在枝上,所有的美好都在路上ÿ…...
【面经总结】Java基础 - 注解
注解 什么是注解 一种特殊的注释 注解的作用 编译器可以使用注解来检测错误或抑制警告。处理注解信息以生成代码或配置文件等。可以在运行时检查某些注解并处理。 注解的缺点 侵入式编程,增加耦合度产生问题定位困难需要利用反射来获取属性,破坏代…...
Matlab笔记
quit/exit 退出Matlab pause(x) 停止x秒 标识符最多63位--namelengthmax who/whos显示变量信息 double--64bit(双精度) single--32bit(单精度) format long/short/compact 改变格式 2017后matlab默认double--single(pi)变…...
android 编译源码添加日志打印
最近闲来无事,把源码编译一下,然后把这个源码编译到pixel3手机上,并且简单修改一下源码的网络请求,添加一些日志打印,堆栈打印,记录一下防止忘记 首先需要下载源码 下载对应源码对应的驱动 https://develop…...

Vue19-key的原理
一、v-for中key的作用 给节点进行一个标识,类似于身份证号。 1-1、需求1: 点击按钮,在<li>的最前面添加一个老刘的信息 <body><div id"root"><h1>人员信息</h1><button click.once"add&qu…...

零一科技Yi-VL 6B视觉大模型环境搭建推理
引子 最近看新闻博客说零一科技的Yi-VL-Plus视觉大模型效果很不错,那就想着尝尝鲜。这是第四篇关于视觉大模型的博客。之前有写过一篇零一科技的chat大模型零一科技Yi-34B Chat大模型环境搭建&推理_python部署大模型yi-34b-chat-CSDN博客,感兴趣的童…...

Django面试题
1. 什么是wsgi? WSGI 是 “Web Server Gateway Interface” 的缩写,它是一种用于 Python Web 应用程序和 Web 服务器之间通信的标准接口。它定义了一组规则和约定,使 Web 服务器能够与任何符合 WSGI 规范的 Python Web 应用程序进行交互。 #…...

Perl语言入门学习
文心一言 Perl语言入门学习可以遵循以下步骤和要点: 1. 了解Perl语言 Perl是一种功能丰富的计算机程序语言,运行在超过100种计算机平台上。Perl最初是为文本处理而开发的,但现在用于各种任务,包括系统管理、Web开发、网络编程、…...

Autoformer
A u t o f o r m e r Autoformer Autoformer 摘要 我们设计了 A u t o f o r m e r Autoformer Autoformer作为一种新型分解架构,带有自相关机制。我们打破了序列分解的预处理惯例,并将其革新为深度模型的基本内部模块。这种设计使 A u t o f o r m…...

uniapp录音播放功能
ui效果如上。 播放就开始倒计时,并且改变播放icon,另外录音则停止上一次录音。 播放按钮(三角形)是播放功能,两竖是暂停播放功能。 const innerAudioContext wx.createInnerAudioContext();export default{data(){ret…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
电脑桌面太单调,用Python写一个桌面小宠物应用。
下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡,可以响应鼠标点击,并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...

小智AI+MCP
什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析:AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github:https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...
从零手写Java版本的LSM Tree (一):LSM Tree 概述
🔥 推荐一个高质量的Java LSM Tree开源项目! https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一个从零实现的Log-Structured Merge Tree,专为高并发写入场景设计。 核心亮点: ⚡ 极致性能:写入速度超…...

CMS内容管理系统的设计与实现:多站点模式的实现
在一套内容管理系统中,其实有很多站点,比如企业门户网站,产品手册,知识帮助手册等,因此会需要多个站点,甚至PC、mobile、ipad各有一个站点。 每个站点关联的有站点所在目录及所属的域名。 一、站点表设计…...