前提
- 数据管理平台包含了多个后台项目,后台项目均使用vue作为开发框架。
- 子项目存在公共头部,需要统一管理维护。
- 子项目存在公共的依赖(如
vue
、vuex
、vue-router
等),公共依赖包可以统一维护。 - 子项目存在公共存在公共的配置文件例如
postcss.config.js
需要统一维护。
解决方案一
在一个项目中,使用 entry配置多个html文件来实现多页面应用
存在的利弊:
- 配置简单
- 打包效率低下
- 灵活性差
- 需要维护多个html文件
解决方案二(采用)
使用thinkjs
统一维护每个项目的template.html
,并为头部注入用户信息,并且单独构建一个 common项目,统一维护第三方依赖。
存在的利弊:
- 配置繁琐
- 打包效率高
- 灵活性好
- 只需维护一个html文件
项目目录
├─src
│ ├─bootstrap
│ ├─config
│ ├─controller
│ ├─logic
│ └─model
├─view
│ └─index //模板文件目录
└─vue_project
|—package.json //统一维护所有依赖
├─asset_manage //子项目目录
├─common //打包公共组件项目
├─postcss.config.js //公用的配置文件
配置介绍
common配置介绍
打包主要配置介绍:
插件 | 描述 |
---|---|
webpack.DllPlugin | 将vendor 依赖中的库、文件打包(依赖的库取的是package.dependencies 的值) |
extract-text-webpack-plugin | 将css单独提取出来,打包成一个.css文件 |
assets-webpack-plugin | 将webpack.DllPlugin 打包生成的文件的文件名保存为一个.json文件。方便子项目引用。 |
optimize-css-assets-webpack-plugin | 压缩打包后的.css文件 |
module.exports = {
mode: 'production',
entry: {
vendor: [...Object.keys(package.dependencies), './css/element-css/index.css', './css/index.postcss'],
},
devtool: "source-map",
output: {
path: path.join(__dirname, '../vendor'),
filename: 'dll.[name]_[hash:6].js',
library: '[name]_[hash:6]'
},
module: {
rules: [{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
},
{
test: /\.postcss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: {
importLoaders: 1
}
}, 'postcss-loader', ]
})
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: 'url-loader'
},
]
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, '../vendor', '[name]-manifest.json'),
name: '[name]_[hash:6]',
context: path.join(__dirname, '../../'), // 执行的上下文环境,对之后DllReferencePlugin有用
}),
new ExtractTextPlugin('[name]_[hash:6].css'),
new AssetsPlugin({
filename: 'bundle-config.json',
path: path.join(__dirname, '../vendor')
}),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
cssProcessorOptions: {
parser: require('postcss-safe-parser'),
discardComments: {
removeAll: true
},
},
canPrint: true
})
]
}
vue-cli3配置介绍
vue-cli3的配置文件被封装在了npm模块
@vue/cli-service 中可使用
vue inspect > output.js
进行查看
插件 | 描述 |
---|---|
webpack.DllReferencePlugin | 将第三方依赖的索引id与对应的第三方依赖具体位置告知webpack |
add-asset-html-webpack-plugin | 将common中生成的bundle-config.json文件中的依赖文件注入html-webpack-plugin 的模板中 |
const webpackConfig = {
configureWebpack: {
plugins: [
new webpack.DllReferencePlugin({
context: path.join(__dirname, '../../'),
manifest
}),
new AddAssetHtmlPlugin([{
filepath: require.resolve(`../vendor/${bundleConfig.vendor.js}`),
includeSourcemap: false
},
{
typeOfAsset: 'css',
filepath: require.resolve(`../vendor/${bundleConfig.vendor.css}`),
includeSourcemap: false
}
])
]
},
chainWebpack: config => {
config.resolve.alias.store.delete('vue$');
config.plugin('copy').tap(args => {
args[0][0].from = './public';
args[0][0].to = 'public';
args[0][0].ignore = ['.*'];
return args;
});
config.plugin('define').tap(args => {
args[0]['process.env']['BUILD_ENV'] = "'" + process.env.BUILD_ENV + "'";
return args;
});
config.module.rule('postcss').oneOf('vue').use('postcss').loader('postcss-loader').options({
config: {
path: path.join(__dirname, '../../')
}
});
},
}
依赖统一管理
如果各自项目的打包依赖分布在各自项目中,依然会增加维护成本以及依赖安装的打包成本
这里就需要理解node查找依赖的逻辑。通过module.paths
可以看到node查找依赖时的,顺序
[ 'E:\\datamanagement\\vue_project\\asset_manage\\repl\\node_modules',
'E:\\datamanagement\\vue_project\\asset_manage\\node_modules',
'E:\\datamanagement\\vue_project\\node_modules',
'E:\\datamanagement\\node_modules',
'E:\\node_modules',
'C:\\Users\\18044854\\.node_modules',
'C:\\Users\\18044854\\.node_libraries',
'C:\\Program Files\\nodejs\\lib\\node' ]
node会从当前目录的node_modules一级一级的向上查找,
所以我们只需要将所有依赖安装在common和vue的父级目录即可