这是一个用vue做的单页面管理系统,这里只是介绍架子搭建思路
前端架构
沿用Vue全家桶系列开发,主要技术栈:vue2.x+vue-router+vuex+element-ui1.x+axios
工程目录
项目浅析
webpack打包配置
webpack的配置主要是vue-cli生成的,经过一些简化修改如下
webpack.config
1 const path = require('path'); 2 const webpack = require('webpack'); 3 const cssnext = require('postcss-cssnext'); 4 const atImport = require('postcss-import'); 5 const cssvariables = require('postcss-css-variables'); 6 const ExtractTextPlugin = require('extract-text-webpack-plugin'); 7 const HtmlWebpackPlugin = require('html-webpack-plugin'); 8 const CopyWebpackPlugin = require('copy-webpack-plugin'); 9 10 const devSrc = 'http://localhost:8099/static/'; 11 const devOutputPath = '../dist/static'; 12 const prodSrc = './static/'; 13 const prodOutputPath = '../dist/static'; 14 15 const Util = require('./util') 16 17 const PATH_DIST = { 18 font: 'font/', 19 img: 'image/', 20 css: 'css/', 21 js: 'js/' 22 }; 23 const isProduction = process.env.NODE_ENV === 'production'; //环境,dev、production 24 console.log('isProduction',isProduction) 25 const host = isProduction ? prodSrc : devSrc; 26 const outputPath = isProduction ? prodOutputPath : devOutputPath; 27 const extractElementUI = new ExtractTextPlugin(PATH_DIST.css + 'element.css' + (isProduction ? '?[contenthash:8]' : '')); 28 const extractCSS = new ExtractTextPlugin(PATH_DIST.css + 'app.css' + (isProduction ? '?[contenthash:8]' : '')); 29 30 module.exports = function (env) { 31 let Config = { 32 entry: { 33 element: ['element-ui'], 34 vue: ['vue', 'axios', 'vue-router', 'vuex'], 35 app: './src/main.js' 36 }, 37 output: { 38 path: path.resolve(__dirname, outputPath), 39 publicPath: host, 40 filename: PATH_DIST.js + '[name].js' + (isProduction ? '?[chunkhash:8]' : '') 41 }, 42 module: { 43 rules: [ 44 { 45 test: /\.vue$/, 46 loader: 'vue-loader', 47 options: { 48 loaders: { 49 scss:Util.generateSassResourceLoader(), 50 sass:Util.generateSassResourceLoader(), 51 css: extractCSS.extract({ 52 use: 'css-loader!postcss-loader', 53 fallback: 'vue-style-loader' 54 }) 55 } 56 } 57 }, 58 { 59 test: function (path) { 60 if (/\.css$/.test(path) && (/element-ui/).test(path)) { 61 return true; 62 } else { 63 return false; 64 } 65 }, 66 loader: extractElementUI.extract({ 67 use: 'css-loader!postcss-loader' 68 }) 69 }, 70 { 71 test: function (path) { 72 if (/\.css$/.test(path) && !(/element-ui/).test(path)) { 73 return true; 74 } else { 75 return false; 76 } 77 }, 78 loader: extractCSS.extract({ 79 use: 'css-loader!postcss-loader' 80 }) 81 }, 82 { 83 test: /\.js$/, 84 loader: 'babel-loader', 85 exclude: /node_modules/ 86 }, 87 { 88 test: /\.(woff|svg|eot|ttf)\??.*$/, //字体文件 89 loader: 'file-loader', 90 options: { 91 publicPath:'../font/', 92 outputPath:PATH_DIST.font, 93 name: '[name].[ext]' 94 } 95 }, 96 { 97 test: /\.(gif|jpg|png)\??.*$/, //图片 98 loader: 'file-loader', 99 options: { 100 name: PATH_DIST.img + '[name].[ext]' 101 } 102 }, 103 { 104 test: /\.scss$/, 105 use: Util.generateSassResourceLoader() 106 }, 107 { 108 test: /\.sass/, 109 use: Util.generateSassResourceLoader() 110 }, 111 112 ] 113 }, 114 plugins: [ 115 new webpack.optimize.CommonsChunkPlugin({ 116 name: ['element', 'vue'] 117 }), 118 extractElementUI, 119 extractCSS, 120 new webpack.LoaderOptionsPlugin({ 121 options: { 122 postcss: function () { 123 return [atImport({ 124 path: [path.resolve(__dirname, '../src')] 125 }), cssnext, cssvariables]; 126 } 127 }, 128 minimize: isProduction 129 }), 130 new HtmlWebpackPlugin({ 131 title: 'JD唯品会运营后台', 132 template: 'index.html', 133 filename: '../index.html', 134 inject: false, 135 chunks: ['element', 'vue', 'app'] 136 }), 137 new webpack.DefinePlugin({ 138 'process.env.NODE_ENV': isProduction ? '"production"' : '"development"' 139 }) 140 ], 141 performance: { 142 hints: isProduction ? 'warning' : false 143 }, 144 devtool: isProduction ? false : '#eval-source-map', 145 resolve: { 146 alias: { 147 'src': path.resolve(__dirname, '../src'), 148 'scss':path.resolve(__dirname,'../src/scss/'), 149 'config':path.resolve(__dirname, '../src/config/'), 150 } 151 } 152 }; 153 154 if (isProduction) { 155 Config.plugins = Config.plugins.concat([ 156 new webpack.optimize.UglifyJsPlugin({ 157 sourceMap: true, 158 compress: { 159 warnings: false 160 } 161 }) 162 ]); 163 } else { 164 Config.devServer = { 165 historyApiFallback: true, 166 publicPath: '/static/', 167 disableHostCheck: true, 168 noInfo: true, 169 hot: true, 170 host: 'localhost', 171 port: 8099, 172 watchOptions: { 173 poll: false, 174 ignored: ['node_modules/**', 'config/**', 'common/**', 'dist/**'] 175 }, 176 headers: { 177 'Access-Control-Allow-Origin': '*' 178 } 179 }; 180 } 181 return Config; 182 };