package.json 配置如下:
{ "name": "rise-vue", "version": "1.0.0", "description": "rise vue", "main": "index.js", "scripts": { "watch": "webpack --mode development --watch", "dev": "webpack --mode development", "build": "webpack --mode production", "server": "webpack-dev-server --mode development --inline" }, "author": "Double", "license": "ISC", "dependencies": { "@nutui/nutui": "^2.1.1", "axios": "^0.18.0", "fastclick": "^1.0.6", "mint-ui": "^2.2.13", "mockjs": "^1.0.1-beta3", "qs": "^6.7.0", "vue": "^2.6.10", "vue-router": "^3.0.2", "vuex": "^3.1.0" }, "devDependencies": { "@babel/core": "^7.4.5", "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-transform-runtime": "^7.4.4", "@babel/preset-env": "^7.4.5", "babel-loader": "^8.0.6", "clean-webpack-plugin": "^3.0.0", "css-loader": "^0.28.11", "cssnano": "^4.1.10", "file-loader": "^1.1.11", "html-loader": "^0.5.5", "html-webpack-plugin": "^3.2.0", "json-loader": "^0.5.7", "less": "^3.9.0", "less-loader": "^4.1.0", "mini-css-extract-plugin": "^0.4.5", "optimize-css-assets-webpack-plugin": "^5.0.1", "postcss-loader": "^2.1.6", "postcss-safe-parser": "^4.0.1", "url-loader": "^1.1.2", "vue-loader": "^15.7.0", "vue-style-loader": "^4.1.2", "vue-template-compiler": "^2.6.10", "webpack": "^4.29.6", "webpack-cli": "^3.3.0", "webpack-dev-server": "^3.7.1" } }
webpack.config.js配置如下:
'use strict'; const path = require("path"), webpack = require('webpack'), { VueLoaderPlugin } = require("vue-loader"), MiniCssExtractPlugin = require("mini-css-extract-plugin"), HtmlWebpackPlugin = require("html-webpack-plugin"), { CleanWebpackPlugin } = require("clean-webpack-plugin"), OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); function resolve (dir) { return path.resolve(__dirname, dir); } // 获取命令参数,命令写在package.json中 let args = process.argv; // 确定目录 let dist = resolve('dist'); // 获取插件 let plugins = [ // CSS提取 插件 new MiniCssExtractPlugin({ filename: "[name].[chunkhash].css", chunkFilename: "[id].[chunkhash].css" }), new OptimizeCssAssetsPlugin({ assetNameRegExp: /[0-9a-zA-Z]+\.css$/g, cssProcessor: require('cssnano'), cssProcessorPluginOptions: { preset: ['default', { discardComments: { removeAll: true }, // 避免 cssnano 重新计算 z-index safe: true, //cssnano通过移除注释、空白、重复规则、过时的浏览器前缀以及做出其他的优化来工作,一般能减少至少 50% 的大小 //cssnano 集成了autoprefixer的功能。会使用到autoprefixer进行无关前缀的清理。默认不兼容ios8,会去掉部分webkit前缀,比如flex //所以这里选择关闭,使用postcss的autoprefixer功能 normalizeUnicode: false, parser: require('postcss-safe-parser'), autoprefixer: false }], }, canPrint: true }), new HtmlWebpackPlugin({ template: './src/index.html', filename: 'buyOil.html', title: '选择油站', chunks: ['buyOil','vendors'], favicon:"./src/assets/favicon.ico", inject: true }), new HtmlWebpackPlugin({ template: './src/index.html', filename: 'buyShop.html', title: '汽车免费保养', chunks: ['buyShop','vendors'], favicon:"./src/assets/favicon.ico", inject: true }), new VueLoaderPlugin(), new CleanWebpackPlugin() ]; if (!args.includes('--inline')) { plugins.push(new webpack.IgnorePlugin(/\/mock$/)); } // webpack 配置 module.exports = { // 入口文件 entry: { buyOil: './src/main/buyOil.js', buyShop: './src/main/buyShop.js', }, // 输出 output: { // 输出目录 path: dist, //publicPath: '', 文件引用前缀 // 输出文件名,[name]与入口文件同名 filename: '[name]-[chunkhash].js' }, resolve: { extensions: ['.js','.vue'], // require 文件时可省略后缀 .js .vue alias: { 'vue': 'vue/dist/vue.js', // 使用完整版的vue '@': resolve('src'), '@page': resolve('src/pages') } }, module: { // 加载器配置 rules: [ { test: /\.vue$/, loader: 'vue-loader' }, { // 目标文件 test: /\.css$/, use: [ // 使用这个插件,使得所有less 能被打入一个文件,而不是一个个style MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader' ] }, { test: /\.less$/, use: [ MiniCssExtractPlugin.loader, 'css-loader','postcss-loader','less-loader' ] }, { test: /\.(js)$/, // 排除目标 exclude: /(node_modules)/, loader: 'babel-loader', options: { babelrc: false, presets:["@babel/preset-env"], plugins: [ "@babel/plugin-transform-runtime", "@babel/plugin-syntax-dynamic-import" // 动态引入文件插件,否则js不能使用import() ] } }, { test: /\.(png|jpg|jpeg|gif|webp|svg)$/, // 小于 8k的图片,输出为base64 dataurl loader: 'url-loader?name=assets/images/[name].[hash:8].[ext]&limit=8192' }, { test: /\.(ttf|otf|woff|eot)$/, // 字体转 dataurl loader: 'url-loader?name=assets/fonts/[name].[hash:8].[ext]&limit=1024' }, { test: /\.json$/, loader: 'json-loader' } ] }, optimization: { // 模块拆分提取规则 splitChunks: { /* 同时满足以下条件才拆分成单独文件 */ chunks: 'async', // 引用类型,all 表示 initial引用 + async引用 minSize: 30000, // 压缩前体积大于30000B minChunks: 1, // 引用数量大于 1 maxAsyncRequests: 5, // 异步引用数量小于5 maxInitialRequests: 3, // 初始引用数量小于3 /**********************************/ name: true, // 缓存组 cacheGroups: { vendors: { name: 'vendors', priority: 10, // 提取到本组的优先级 /* 将符合以下条件的模块提取到组 */ chunks: "all", test: /node_modules\\/, minSize: 30000, minChunks: 1 } } } }, // 额外插件 plugins: plugins, // 配置 webpack-dev-server devServer:{ historyApiFallback: true, // 允许路由 inline: true, port: 8090, disableHostCheck: true, headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Credentials": true, "Access-Control-Allow-Methods": "POST, GET, PUT, OPTIONS", "Access-Control-Allow-Headers": "X-PINGOTHER, Content-Type" }, }, performance: { hints: false // 枚举 }, // 对webpack输出信息的配置,可以减少一些不必要的输出 stats: { children: false } };