webpack-merge合并规则
前言
vue中,webpack将开发环境和生产环境的公共配置抽离出来,然后基于公共配置通过webpack-merge合并开发或者生产环境的特有配置,生成完整的开发或者生产环境配置。
以现有项目打包目录为例:如下图
其中webpack.dev.js为例:
const { merge } = require('webpack-merge');
const path = require('path');
const env = require('../config/env');
const webpack = require('webpack');
let serve_project = process.env.serve_project;
let NODE_ENV = process.env.NODE_ENV;
let project = {
list: require('./webpack.common.list.js'),
form: require('./webpack.common.form.js'),
all: require('./webpack.common.js'),
};
module.exports = merge(project[serve_project], {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
hot: true, //热更新
open: true, //编译完自动打开浏览器
compress: true, //开启gzip压缩
port: 3000, //开启端口号
//托管的静态资源文件
//可通过数组的方式托管多个静态资源文件
static: {
directory: path.join(__dirname, '../public'),
},
proxy: {
'/': {
target: 'https://test.aaa.com/',
pathRewrite: { '^/': '' },
changeOrigin: true,
},
},
},
plugins: [
new webpack.DefinePlugin({
'process.env': env[NODE_ENV],
}),
],
});
文档地址:https://www.npmjs.com/package/webpack-merge,其中有其规则使用的介绍。
它通常用于合并配置对象,最直接的用法是使用合并函数连接数组并合并对象,创建出一个新对象。使用自定义的数据与对象的合并方式这里不再深究,只阐述下最基本的连接数组并合并对象的方式。
基本使用方式:
merge(...configuration | [...configuration])
文档示例:
const { merge } = require('webpack-merge');
// Default API
const output = merge(object1, object2, object3, ...);
// You can pass an array of objects directly.
// This works with all available functions.
const output = merge([object1, object2, object3]);
// Keys matching to the right take precedence:
const output = merge(
{ fruit: "apple", color: "red" },
{ fruit: "strawberries" }
);
console.log(output);
// { color: "red", fruit: "strawberries"}
结论
如果merge的两个对象中的键值对 :
数据类型不一样,后面完全覆盖前面;如果两者都是基础数据类型,后面覆盖前面。
// 键值对数据类型不一致示例
let dog = {
color: {},
};
let cat = {
color: '#fff',
};
console.log(merge(dog, cat)); // {color: 'fff'}
// 键值对为基础类型示例
let dog = {
color: 'black',
};
let cat = {
color: '#fff',
};
console.log(merge(dog, cat)); // {color: '#fff'}
如果merge的两个对象中的键值对 :
如果两者都是数组,就会把两个数组进行合并
如果两者都是对象,键值对规则同上面合并的cat及dog相同
// 键值对为数组示例
let dog = {
love: ['run', 'eat'],
};
let cat = {
love: ['sleep', 'eat'],
};
console.log(merge(dog, cat)); // {love: ['run', 'eat', 'sleep', 'eat']}
// 完整示例
let dog = {
color: '#black',
love: ['run', 'eat'],
behavior: {
character: 'lively',
age: 4,
},
};
let cat = {
color: '#fff',
love: ['sleep', 'eat'],
behavior: {
character: 'quiet',
},
};
console.log(merge(dog, cat));
/* {
color: '#fff',
love: [['run', 'eat', 'sleep', 'eat'],
behavior:{
character: 'quiet',
age: 4
}
} */
对比Object.assign
Object.assign()将所有可枚举(Object.propertyIsEnumerable() 返回 true)的自有(Object.hasOwnProperty() 返回 true)属性从一个或多个源对象复制到目标对象,返回修改后的对象。(摘自MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
它可以用来合并对象,实现对象属性的合并
使用方式:
Object.assign(target, ...sources)
参数: target—>目标对象
source—>源对象
返回值:target,即目标对象
Object.assign目标对象和源对象中的键值对:
对于属性相同的键 源对象属性会直接覆盖目标对象的属性,如果源对象的属性值是一个对象的引用则目标对象的属性值也指向那个引用即浅拷贝,目标对象自身被改变
let dog = {
color: '#black',
love: ['jump', 'eat'],
behavior: {
character: 'lively',
age: 4,
},
};
let cat = {
color: '#fff',
love: ['sleep', 'eat'],
behavior: {
character: 'quiet',
},
};
Object.assign(dog, cat);
console.log(dog);
/*
{
color: "#fff",
love: ["sleep", "eat"],
behavior: {character: 'quiet'}
}
*/
cat.behavior.character = 'slouchingly';
console.log(dog);
/*
{
color: "#fff",
love: ["sleep", "eat"],
behavior: {character: 'slouchingly"'}
}
*/
如果只是想将两个或多个对象的属性合并到一起,不改变原有对象的属性,可以用一个空的对象作为target对象。
Object.assign({},target,source);