Open Lenny-Hu opened 5 years ago
该配置可以对momentjs、lodash、icon等打包进行优化,同时配有css精灵图。
vue.config.js
const path = require('path');
const AntdDayjsWebpackPlugin = require('antd-dayjs-webpack-plugin'); // ant ui的momentjs换成dayjs优化体积
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin'); // 优化lodash打包
const SpritesmithPlugin = require('webpack-spritesmith'); // css精灵图
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; // js打包代码来源分析
const isProd = process.env.NODE_ENV === 'production';
module.exports = {
// publicPath: isProd ? '/assets/frontend/' : '/',
assetsDir: 'assets/frontend',
devServer: {
proxy: { // 代理api请求到接口
'/api': {
target: 'http://xxxx.com',
ws: true,
changeOrigin: true
},
'/assets': {
target: 'http://xxx.com',
ws: true,
changeOrigin: true
},
}
},
pages: {
index: { // 对于源代码不是在src目录结构这种情况可使用pages指定入口文件
entry: ['./app/scripts/polyfill.js', './app/scripts/main.js'], // 多个文件作为一个入口,也可内部import
chunks: ['polyfill', 'lib', 'ui', 'vendors', 'index'], // 使用的代码块,对应cacheGroups
chunksSortMode: 'manual' // 按照chunks数组顺序插入script标签
}
},
css: {
loaderOptions: {
less: { // ant UI 主题配置
javascriptEnabled: true,
modifyVars: {
'primary-color': '#1cc208',
'link-color': '#0282e1',
'border-color-base': '#e6e6e6',
// 'border-radius-base': '8px'
}
}
}
},
chainWebpack: (config) => { // 设置webpack的alias,方便内部引用包
config.resolve.alias
.set('vue$', 'vue/dist/vue.esm.js')
.set('@', path.resolve(__dirname, 'app', 'scripts'))
.set('@images', path.resolve(__dirname, 'app', 'images'))
.set('@styles', path.resolve(__dirname, 'app', 'styles'))
.set('@ant-design/icons/lib/dist$', path.resolve(__dirname, 'app/scripts/icons.js')); // 优化ant ui图标体积,仅引入常用图标,具体见js文件
},
configureWebpack: config => {
config.optimization = { // 此处有一部分是vue-cli4的默认配置
splitChunks: {
chunks: 'all',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
polyfill: { // 此处无效,具体要进一步查看
name: 'polyfill',
test: /[\\/]polyfill\./,
priority: -5
},
lib: { // 打包vue基本依赖
name: 'lib',
test: /[\\/]node_modules[\\/](vue|vue-router|vue-meta|vuex|axios)[\\/]/,
priority: -10
},
ui: {
name: 'ui',
test: /[\\/]node_modules[\\/](dayjs|ant-design-vue|@ant-design)[\\/]/,
priority: -10
},
vendors: { // 默认配置
test: /[\\/]node_modules[\\/]/,
priority: -20
},
default: { // 默认配置
minChunks: 2,
priority: -30,
reuseExistingChunk: true
}
}
}
};
config.plugins.push(
new AntdDayjsWebpackPlugin({
preset: 'antdv3'
}),
new LodashModuleReplacementPlugin(),
new SpritesmithPlugin({
src: { // 精灵图的小图标目录
cwd: path.resolve(__dirname, 'app/images/icons'),
glob: '*.png'
},
target: { // 生成精灵图和样式目录
image: path.resolve(__dirname, 'app/styles/sprite/sprite.png'),
css: path.resolve(__dirname, 'app/styles/sprite/_sprite.scss')
},
apiOptions: {
cssImageRef: '../../../styles/sprite/sprite.png', // 生成的css中,使用的地址,该地址是相对于你是在何处import main.scss
spritesheet_info: {
name: 'icons-spritesheet' // 控制精灵图变量名称,运行查看_sprite.scss即可明白
},
generateSpriteName (filename) { // 控制精灵图的class名称,运行查看_sprite.scss即可明白
let { name } = path.parse(filename);
return `icons-${name}`;
}
},
spritesmithOptions: {
padding: 2 // 设置精灵图每个图标的之间的距离
}
})
);
if (isProd) {
config.plugins.push(
new BundleAnalyzerPlugin()
);
}
}
};
banbel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
[
'@babel/preset-env',
{
modules: false,
useBuiltIns: 'entry',
corejs: { version: 3, proposals: true }
}
]
],
plugins: [
['@babel/plugin-transform-runtime', {
corejs: 3
}],
["import", { "libraryName": "ant-design-vue", "libraryDirectory": "es", "style": true }] // `style: true` 会加载 less 文件
],
env: {
test: {
presets: ['@babel/preset-env']
}
}
};
icons.js
/* 列出你自己用到的@ant-design/icons的图标 */
/* 下面是antd默认使用到的icon */
export { default as CloseOutline } from '@ant-design/icons/lib/outline/CloseOutline'
export { default as CheckOutline } from '@ant-design/icons/lib/outline/CheckOutline'
export { default as LoadingOutline } from '@ant-design/icons/lib/outline/LoadingOutline'
export { default as CheckCircleOutline } from '@ant-design/icons/lib/outline/CheckCircleOutline'
export { default as InfoCircleOutline } from '@ant-design/icons/lib/outline/InfoCircleOutline'
export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline'
export { default as ExclamationCircleOutline } from '@ant-design/icons/lib/outline/ExclamationCircleOutline'
export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill'
export { default as InfoCircleFill } from '@ant-design/icons/lib/fill/InfoCircleFill'
export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill'
export { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill'
export { default as UpOutline } from '@ant-design/icons/lib/outline/UpOutline'
export { default as DownOutline } from '@ant-design/icons/lib/outline/DownOutline'
export { default as LeftOutline } from '@ant-design/icons/lib/outline/LeftOutline'
export { default as RightOutline } from '@ant-design/icons/lib/outline/RightOutline'
export { default as RedoOutline } from '@ant-design/icons/lib/outline/RedoOutline'
export { default as CalendarOutline } from '@ant-design/icons/lib/outline/CalendarOutline'
export { default as SearchOutline } from '@ant-design/icons/lib/outline/SearchOutline'
export { default as BarsOutline } from '@ant-design/icons/lib/outline/BarsOutline'
export { default as StarFill } from '@ant-design/icons/lib/fill/StarFill'
export { default as FilterOutline } from '@ant-design/icons/lib/outline/FilterOutline'
export { default as CaretUpOutline } from '@ant-design/icons/lib/outline/CaretUpOutline'
export { default as CaretDownOutline } from '@ant-design/icons/lib/outline/CaretDownOutline'
export { default as PlusOutline } from '@ant-design/icons/lib/outline/PlusOutline'
export { default as FileOutline } from '@ant-design/icons/lib/outline/FileOutline'
export { default as FolderOpenOutline } from '@ant-design/icons/lib/outline/FolderOpenOutline'
export { default as FolderOutline } from '@ant-design/icons/lib/outline/FolderOutline'
export { default as PaperClipOutline } from '@ant-design/icons/lib/outline/PaperClipOutline'
export { default as PictureOutline } from '@ant-design/icons/lib/outline/PictureOutline'
export { default as EyeOutline } from '@ant-design/icons/lib/outline/EyeOutline'
export { default as DeleteOutline } from '@ant-design/icons/lib/outline/DeleteOutline'
export { default as UploadOutline } from '@ant-design/icons/lib/outline/UploadOutline'
polyfill.js
// 主要配置一些IE不支持而用到的特性
// ie
import 'core-js/features/promise';
import 'core-js/features/set';
import 'core-js/features/symbol';
import 'core-js/features/array/find';
import 'core-js/features/array/includes';
import 'core-js/features/array/map';
// HTMLElement.dataset
// Needed for: IE10-
(() => {
if (!('dataset' in document.createElement('span')) &&
'Element' in global && Element.prototype && Object.defineProperty) {
Object.defineProperty(Element.prototype, 'dataset', { get: function() {
var result = Object.create(null);
for (var i = 0; i < this.attributes.length; ++i) {
var attr = this.attributes[i];
if (attr.specified && attr.name.substring(0, 5) === 'data-') {
(function(element, name) {
var prop = name.replace(/-([a-z])/g, function(m, p) {
return p.toUpperCase();
});
result[prop] = element.getAttribute('data-' + name); // Read-only, for IE8-
Object.defineProperty(result, prop, {
get: function() {
return element.getAttribute('data-' + name);
},
set: function(value) {
element.setAttribute('data-' + name, value);
}});
}(this, attr.name.substring(5)));
}
}
return result;
}});
}
})();
main.js
// import './polyfill';
import Vue from 'vue';
import {
ConfigProvider,
Empty,
Button,
Carousel,
Modal,
FormModel,
Input,
Skeleton,
Spin,
message,
Dropdown,
Icon,
Menu,
Breadcrumb
} from 'ant-design-vue';
import App from '@/views/layouts/app';
import router from '@/routes';
import store from '@/store';
import $http from '@/plugins/$http';
import $bus from '@/plugins/$bus';
import './helpers/filter';
// import Antd from 'ant-design-vue';
// import 'ant-design-vue/dist/antd.css';
// import 'ant-design-vue/dist/antd.less';
// Vue.use(Antd);
if (process.env.NODE_ENV === 'development') {
console.log('开发环境,加载miragejs');
// require('../apis'); // NOTE: just for dev
}
Vue.config.productionTip = false;
Vue.use(ConfigProvider);
Vue.use(Empty);
Vue.use(Button);
Vue.use(Carousel);
Vue.use(Modal);
Vue.use(FormModel);
Vue.use(Input);
Vue.use(Skeleton);
Vue.use(Spin);
Vue.use(Dropdown);
Vue.use(Icon);
Vue.use(Menu);
Vue.use(Breadcrumb);
Vue.prototype.$message = message;
Vue.prototype.$info = Modal.info;
Vue.prototype.$success = Modal.success;
Vue.prototype.$error = Modal.error;
Vue.prototype.$warning = Modal.warning;
Vue.prototype.$confirm = Modal.confirm;
Vue.prototype.$destroyAll = Modal.destroyAll;
Vue.use($http);
Vue.use($bus);
new Vue({
el: '#app',
components: { App },
template: '<app/>',
router,
store
});
package.json
gulpfile.js