Browse Source

refactor build

Pan 7 years ago
parent
commit
cade4f9449
21 changed files with 566 additions and 399 deletions
  1. 7 2
      .babelrc
  2. 195 141
      .eslintrc.js
  3. 8 0
      .gitignore
  4. 1 0
      .postcssrc.js
  5. 15 9
      build/build.js
  6. 17 11
      build/check-versions.js
  7. 0 9
      build/dev-client.js
  8. 0 89
      build/dev-server.js
  9. BIN
      build/logo.png
  10. 41 11
      build/utils.js
  11. 17 7
      build/vue-loader.conf.js
  12. 39 14
      build/webpack.base.conf.js
  13. 68 22
      build/webpack.dev.conf.js
  14. 55 31
      build/webpack.prod.conf.js
  15. 3 2
      config/dev.env.js
  16. 62 17
      config/index.js
  17. 1 0
      config/prod.env.js
  18. 1 0
      index.html
  19. 20 18
      package.json
  20. 1 1
      src/App.vue
  21. 15 15
      src/views/404.vue

+ 7 - 2
.babelrc

@@ -1,7 +1,12 @@
1 1
 {
2 2
   "presets": [
3
-    ["env", { "modules": false }],
3
+    ["env", {
4
+      "modules": false,
5
+      "targets": {
6
+        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7
+      }
8
+    }],
4 9
     "stage-2"
5 10
   ],
6
-  "plugins": ["transform-runtime"]
11
+  "plugins": ["transform-vue-jsx", "transform-runtime"]
7 12
 }

+ 195 - 141
.eslintrc.js

@@ -1,144 +1,198 @@
1 1
 module.exports = {
2
-    root: true,
3
-    parser: 'babel-eslint',
4
-    parserOptions: {
5
-        sourceType: 'module'
6
-    },
7
-    env: {
8
-        browser: true,
9
-        node: true,
10
-        es6: true,
11
-    },
12
-    extends: 'eslint:recommended',
13
-    // required to lint *.vue files
14
-    plugins: [
15
-        'html'
16
-    ],
17
-    // check if imports actually resolve
18
-    'settings': {
19
-        'import/resolver': {
20
-            'webpack': {
21
-                'config': 'build/webpack.base.conf.js'
22
-            }
23
-        }
24
-    },
25
-    // add your custom rules here
26
-    //it is base on https://github.com/vuejs/eslint-config-vue
27
-    'rules': {
28
-        'accessor-pairs': 2,
29
-        'arrow-spacing': [2, { 'before': true, 'after': true }],
30
-        'block-spacing': [2, 'always'],
31
-        'brace-style': [2, '1tbs', { 'allowSingleLine': true }],
32
-        'camelcase': [0, { 'properties': 'always' }],
33
-        'comma-dangle': [2, 'never'],
34
-        'comma-spacing': [2, { 'before': false, 'after': true }],
35
-        'comma-style': [2, 'last'],
36
-        'constructor-super': 2,
37
-        'curly': [2, 'multi-line'],
38
-        'dot-location': [2, 'property'],
39
-        'eol-last': 2,
40
-        'eqeqeq': [2, 'allow-null'],
41
-        'generator-star-spacing': [2, { 'before': true, 'after': true }],
42
-        'handle-callback-err': [2, '^(err|error)$' ],
43
-        'indent': [2, 2, { 'SwitchCase': 1 }],
44
-        'jsx-quotes': [2, 'prefer-single'],
45
-        'key-spacing': [2, { 'beforeColon': false, 'afterColon': true }],
46
-        'keyword-spacing': [2, { 'before': true, 'after': true }],
47
-        'new-cap': [2, { 'newIsCap': true, 'capIsNew': false }],
48
-        'new-parens': 2,
49
-        'no-array-constructor': 2,
50
-        'no-caller': 2,
51
-        'no-console': 'off',
52
-        'no-class-assign': 2,
53
-        'no-cond-assign': 2,
54
-        'no-const-assign': 2,
55
-        'no-control-regex': 2,
56
-        'no-delete-var': 2,
57
-        'no-dupe-args': 2,
58
-        'no-dupe-class-members': 2,
59
-        'no-dupe-keys': 2,
60
-        'no-duplicate-case': 2,
61
-        'no-empty-character-class': 2,
62
-        'no-empty-pattern': 2,
63
-        'no-eval': 2,
64
-        'no-ex-assign': 2,
65
-        'no-extend-native': 2,
66
-        'no-extra-bind': 2,
67
-        'no-extra-boolean-cast': 2,
68
-        'no-extra-parens': [2, 'functions'],
69
-        'no-fallthrough': 2,
70
-        'no-floating-decimal': 2,
71
-        'no-func-assign': 2,
72
-        'no-implied-eval': 2,
73
-        'no-inner-declarations': [2, 'functions'],
74
-        'no-invalid-regexp': 2,
75
-        'no-irregular-whitespace': 2,
76
-        'no-iterator': 2,
77
-        'no-label-var': 2,
78
-        'no-labels': [2, { 'allowLoop': false, 'allowSwitch': false }],
79
-        'no-lone-blocks': 2,
80
-        'no-mixed-spaces-and-tabs': 2,
81
-        'no-multi-spaces': 2,
82
-        'no-multi-str': 2,
83
-        'no-multiple-empty-lines': [2, { 'max': 1 }],
84
-        'no-native-reassign': 2,
85
-        'no-negated-in-lhs': 2,
86
-        'no-new-object': 2,
87
-        'no-new-require': 2,
88
-        'no-new-symbol': 2,
89
-        'no-new-wrappers': 2,
90
-        'no-obj-calls': 2,
91
-        'no-octal': 2,
92
-        'no-octal-escape': 2,
93
-        'no-path-concat': 2,
94
-        'no-proto': 2,
95
-        'no-redeclare': 2,
96
-        'no-regex-spaces': 2,
97
-        'no-return-assign': [2, 'except-parens'],
98
-        'no-self-assign': 2,
99
-        'no-self-compare': 2,
100
-        'no-sequences': 2,
101
-        'no-shadow-restricted-names': 2,
102
-        'no-spaced-func': 2,
103
-        'no-sparse-arrays': 2,
104
-        'no-this-before-super': 2,
105
-        'no-throw-literal': 2,
106
-        'no-trailing-spaces': 2,
107
-        'no-undef': 2,
108
-        'no-undef-init': 2,
109
-        'no-unexpected-multiline': 2,
110
-        'no-unmodified-loop-condition': 2,
111
-        'no-unneeded-ternary': [2, { 'defaultAssignment': false }],
112
-        'no-unreachable': 2,
113
-        'no-unsafe-finally': 2,
114
-        'no-unused-vars': [2, { 'vars': 'all', 'args': 'none' }],
115
-        'no-useless-call': 2,
116
-        'no-useless-computed-key': 2,
117
-        'no-useless-constructor': 2,
118
-        'no-useless-escape': 0,
119
-        'no-whitespace-before-property': 2,
120
-        'no-with': 2,
121
-        'one-var': [2, { 'initialized': 'never' }],
122
-        'operator-linebreak': [2, 'after', { 'overrides': { '?': 'before', ':': 'before' } }],
123
-        'padded-blocks': [2, 'never'],
124
-        'quotes': [2, 'single', { 'avoidEscape': true, 'allowTemplateLiterals': true }],
125
-        'semi': [2, 'never'],
126
-        'semi-spacing': [2, { 'before': false, 'after': true }],
127
-        'space-before-blocks': [2, 'always'],
128
-        'space-before-function-paren': [2, 'never'],
129
-        'space-in-parens': [2, 'never'],
130
-        'space-infix-ops': 2,
131
-        'space-unary-ops': [2, { 'words': true, 'nonwords': false }],
132
-        'spaced-comment': [2, 'always', { 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] }],
133
-        'template-curly-spacing': [2, 'never'],
134
-        'use-isnan': 2,
135
-        'valid-typeof': 2,
136
-        'wrap-iife': [2, 'any'],
137
-        'yield-star-spacing': [2, 'both'],
138
-        'yoda': [2, 'never'],
139
-        'prefer-const': 2,
140
-        'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
141
-        'object-curly-spacing': [2, 'always', { objectsInObjects: false }],
142
-        'array-bracket-spacing': [2, 'never']
2
+  root: true,
3
+  parser: 'babel-eslint',
4
+  parserOptions: {
5
+    sourceType: 'module'
6
+  },
7
+  env: {
8
+    browser: true,
9
+    node: true,
10
+    es6: true,
11
+  },
12
+  extends: 'eslint:recommended',
13
+  // required to lint *.vue files
14
+  plugins: [
15
+    'html'
16
+  ],
17
+  // check if imports actually resolve
18
+  'settings': {
19
+    'import/resolver': {
20
+      'webpack': {
21
+        'config': 'build/webpack.base.conf.js'
22
+      }
143 23
     }
24
+  },
25
+  // add your custom rules here
26
+  //it is base on https://github.com/vuejs/eslint-config-vue
27
+  rules: {
28
+    'accessor-pairs': 2,
29
+    'arrow-spacing': [2, {
30
+      'before': true,
31
+      'after': true
32
+    }],
33
+    'block-spacing': [2, 'always'],
34
+    'brace-style': [2, '1tbs', {
35
+      'allowSingleLine': true
36
+    }],
37
+    'camelcase': [0, {
38
+      'properties': 'always'
39
+    }],
40
+    'comma-dangle': [2, 'never'],
41
+    'comma-spacing': [2, {
42
+      'before': false,
43
+      'after': true
44
+    }],
45
+    'comma-style': [2, 'last'],
46
+    'constructor-super': 2,
47
+    'curly': [2, 'multi-line'],
48
+    'dot-location': [2, 'property'],
49
+    'eol-last': 2,
50
+    'eqeqeq': [2, 'allow-null'],
51
+    'generator-star-spacing': [2, {
52
+      'before': true,
53
+      'after': true
54
+    }],
55
+    'handle-callback-err': [2, '^(err|error)$'],
56
+    'indent': [2, 2, {
57
+      'SwitchCase': 1
58
+    }],
59
+    'jsx-quotes': [2, 'prefer-single'],
60
+    'key-spacing': [2, {
61
+      'beforeColon': false,
62
+      'afterColon': true
63
+    }],
64
+    'keyword-spacing': [2, {
65
+      'before': true,
66
+      'after': true
67
+    }],
68
+    'new-cap': [2, {
69
+      'newIsCap': true,
70
+      'capIsNew': false
71
+    }],
72
+    'new-parens': 2,
73
+    'no-array-constructor': 2,
74
+    'no-caller': 2,
75
+    'no-console': 'off',
76
+    'no-class-assign': 2,
77
+    'no-cond-assign': 2,
78
+    'no-const-assign': 2,
79
+    'no-control-regex': 2,
80
+    'no-delete-var': 2,
81
+    'no-dupe-args': 2,
82
+    'no-dupe-class-members': 2,
83
+    'no-dupe-keys': 2,
84
+    'no-duplicate-case': 2,
85
+    'no-empty-character-class': 2,
86
+    'no-empty-pattern': 2,
87
+    'no-eval': 2,
88
+    'no-ex-assign': 2,
89
+    'no-extend-native': 2,
90
+    'no-extra-bind': 2,
91
+    'no-extra-boolean-cast': 2,
92
+    'no-extra-parens': [2, 'functions'],
93
+    'no-fallthrough': 2,
94
+    'no-floating-decimal': 2,
95
+    'no-func-assign': 2,
96
+    'no-implied-eval': 2,
97
+    'no-inner-declarations': [2, 'functions'],
98
+    'no-invalid-regexp': 2,
99
+    'no-irregular-whitespace': 2,
100
+    'no-iterator': 2,
101
+    'no-label-var': 2,
102
+    'no-labels': [2, {
103
+      'allowLoop': false,
104
+      'allowSwitch': false
105
+    }],
106
+    'no-lone-blocks': 2,
107
+    'no-mixed-spaces-and-tabs': 2,
108
+    'no-multi-spaces': 2,
109
+    'no-multi-str': 2,
110
+    'no-multiple-empty-lines': [2, {
111
+      'max': 1
112
+    }],
113
+    'no-native-reassign': 2,
114
+    'no-negated-in-lhs': 2,
115
+    'no-new-object': 2,
116
+    'no-new-require': 2,
117
+    'no-new-symbol': 2,
118
+    'no-new-wrappers': 2,
119
+    'no-obj-calls': 2,
120
+    'no-octal': 2,
121
+    'no-octal-escape': 2,
122
+    'no-path-concat': 2,
123
+    'no-proto': 2,
124
+    'no-redeclare': 2,
125
+    'no-regex-spaces': 2,
126
+    'no-return-assign': [2, 'except-parens'],
127
+    'no-self-assign': 2,
128
+    'no-self-compare': 2,
129
+    'no-sequences': 2,
130
+    'no-shadow-restricted-names': 2,
131
+    'no-spaced-func': 2,
132
+    'no-sparse-arrays': 2,
133
+    'no-this-before-super': 2,
134
+    'no-throw-literal': 2,
135
+    'no-trailing-spaces': 2,
136
+    'no-undef': 2,
137
+    'no-undef-init': 2,
138
+    'no-unexpected-multiline': 2,
139
+    'no-unmodified-loop-condition': 2,
140
+    'no-unneeded-ternary': [2, {
141
+      'defaultAssignment': false
142
+    }],
143
+    'no-unreachable': 2,
144
+    'no-unsafe-finally': 2,
145
+    'no-unused-vars': [2, {
146
+      'vars': 'all',
147
+      'args': 'none'
148
+    }],
149
+    'no-useless-call': 2,
150
+    'no-useless-computed-key': 2,
151
+    'no-useless-constructor': 2,
152
+    'no-useless-escape': 0,
153
+    'no-whitespace-before-property': 2,
154
+    'no-with': 2,
155
+    'one-var': [2, {
156
+      'initialized': 'never'
157
+    }],
158
+    'operator-linebreak': [2, 'after', {
159
+      'overrides': {
160
+        '?': 'before',
161
+        ':': 'before'
162
+      }
163
+    }],
164
+    'padded-blocks': [2, 'never'],
165
+    'quotes': [2, 'single', {
166
+      'avoidEscape': true,
167
+      'allowTemplateLiterals': true
168
+    }],
169
+    'semi': [2, 'never'],
170
+    'semi-spacing': [2, {
171
+      'before': false,
172
+      'after': true
173
+    }],
174
+    'space-before-blocks': [2, 'always'],
175
+    'space-before-function-paren': [2, 'never'],
176
+    'space-in-parens': [2, 'never'],
177
+    'space-infix-ops': 2,
178
+    'space-unary-ops': [2, {
179
+      'words': true,
180
+      'nonwords': false
181
+    }],
182
+    'spaced-comment': [2, 'always', {
183
+      'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
184
+    }],
185
+    'template-curly-spacing': [2, 'never'],
186
+    'use-isnan': 2,
187
+    'valid-typeof': 2,
188
+    'wrap-iife': [2, 'any'],
189
+    'yield-star-spacing': [2, 'both'],
190
+    'yoda': [2, 'never'],
191
+    'prefer-const': 2,
192
+    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
193
+    'object-curly-spacing': [2, 'always', {
194
+      objectsInObjects: false
195
+    }],
196
+    'array-bracket-spacing': [2, 'never']
197
+  }
144 198
 }

+ 8 - 0
.gitignore

@@ -5,3 +5,11 @@ npm-debug.log*
5 5
 yarn-debug.log*
6 6
 yarn-error.log*
7 7
 package-lock.json
8
+
9
+# Editor directories and files
10
+.idea
11
+.vscode
12
+*.suo
13
+*.ntvs*
14
+*.njsproj
15
+*.sln

+ 1 - 0
.postcssrc.js

@@ -3,6 +3,7 @@
3 3
 module.exports = {
4 4
   "plugins": {
5 5
     // to edit target browsers: use "browserslist" field in package.json
6
+    "postcss-import": {},
6 7
     "autoprefixer": {}
7 8
   }
8 9
 }

+ 15 - 9
build/build.js

@@ -1,21 +1,22 @@
1
+'use strict'
1 2
 require('./check-versions')()
2 3
 
3 4
 process.env.NODE_ENV = 'production'
4 5
 
5
-var ora = require('ora')
6
-var rm = require('rimraf')
7
-var path = require('path')
8
-var chalk = require('chalk')
9
-var webpack = require('webpack')
10
-var config = require('../config')
11
-var webpackConfig = require('./webpack.prod.conf')
6
+const ora = require('ora')
7
+const rm = require('rimraf')
8
+const path = require('path')
9
+const chalk = require('chalk')
10
+const webpack = require('webpack')
11
+const config = require('../config')
12
+const webpackConfig = require('./webpack.prod.conf')
12 13
 
13
-var spinner = ora('building for production...')
14
+const spinner = ora('building for production...')
14 15
 spinner.start()
15 16
 
16 17
 rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
17 18
   if (err) throw err
18
-  webpack(webpackConfig, function (err, stats) {
19
+  webpack(webpackConfig, (err, stats) => {
19 20
     spinner.stop()
20 21
     if (err) throw err
21 22
     process.stdout.write(stats.toString({
@@ -26,6 +27,11 @@ rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
26 27
       chunkModules: false
27 28
     }) + '\n\n')
28 29
 
30
+    if (stats.hasErrors()) {
31
+      console.log(chalk.red('  Build failed with errors.\n'))
32
+      process.exit(1)
33
+    }
34
+
29 35
     console.log(chalk.cyan('  Build complete.\n'))
30 36
     console.log(chalk.yellow(
31 37
       '  Tip: built files are meant to be served over an HTTP server.\n' +

+ 17 - 11
build/check-versions.js

@@ -1,17 +1,19 @@
1
-var chalk = require('chalk')
2
-var semver = require('semver')
3
-var packageConfig = require('../package.json')
4
-var shell = require('shelljs')
1
+'use strict'
2
+const chalk = require('chalk')
3
+const semver = require('semver')
4
+const packageConfig = require('../package.json')
5
+const shell = require('shelljs')
6
+
5 7
 function exec (cmd) {
6 8
   return require('child_process').execSync(cmd).toString().trim()
7 9
 }
8 10
 
9
-var versionRequirements = [
11
+const versionRequirements = [
10 12
   {
11 13
     name: 'node',
12 14
     currentVersion: semver.clean(process.version),
13 15
     versionRequirement: packageConfig.engines.node
14
-  },
16
+  }
15 17
 ]
16 18
 
17 19
 if (shell.which('npm')) {
@@ -23,9 +25,11 @@ if (shell.which('npm')) {
23 25
 }
24 26
 
25 27
 module.exports = function () {
26
-  var warnings = []
27
-  for (var i = 0; i < versionRequirements.length; i++) {
28
-    var mod = versionRequirements[i]
28
+  const warnings = []
29
+
30
+  for (let i = 0; i < versionRequirements.length; i++) {
31
+    const mod = versionRequirements[i]
32
+
29 33
     if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
30 34
       warnings.push(mod.name + ': ' +
31 35
         chalk.red(mod.currentVersion) + ' should be ' +
@@ -38,10 +42,12 @@ module.exports = function () {
38 42
     console.log('')
39 43
     console.log(chalk.yellow('To use this template, you must update following to modules:'))
40 44
     console.log()
41
-    for (var i = 0; i < warnings.length; i++) {
42
-      var warning = warnings[i]
45
+
46
+    for (let i = 0; i < warnings.length; i++) {
47
+      const warning = warnings[i]
43 48
       console.log('  ' + warning)
44 49
     }
50
+
45 51
     console.log()
46 52
     process.exit(1)
47 53
   }

+ 0 - 9
build/dev-client.js

@@ -1,9 +0,0 @@
1
-/* eslint-disable */
2
-require('eventsource-polyfill')
3
-var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
4
-
5
-hotClient.subscribe(function (event) {
6
-  if (event.action === 'reload') {
7
-    window.location.reload()
8
-  }
9
-})

+ 0 - 89
build/dev-server.js

@@ -1,89 +0,0 @@
1
-require('./check-versions')()
2
-
3
-var config = require('../config')
4
-if (!process.env.NODE_ENV) {
5
-  process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
6
-}
7
-
8
-var opn = require('opn')
9
-var path = require('path')
10
-var express = require('express')
11
-var webpack = require('webpack')
12
-var proxyMiddleware = require('http-proxy-middleware')
13
-var webpackConfig = require('./webpack.dev.conf')
14
-
15
-// default port where dev server listens for incoming traffic
16
-var port = process.env.PORT || config.dev.port
17
-// automatically open browser, if not set will be false
18
-var autoOpenBrowser = !!config.dev.autoOpenBrowser
19
-// Define HTTP proxies to your custom API backend
20
-// https://github.com/chimurai/http-proxy-middleware
21
-var proxyTable = config.dev.proxyTable
22
-
23
-var app = express()
24
-var compiler = webpack(webpackConfig)
25
-
26
-var devMiddleware = require('webpack-dev-middleware')(compiler, {
27
-  publicPath: webpackConfig.output.publicPath,
28
-  quiet: true
29
-})
30
-
31
-var hotMiddleware = require('webpack-hot-middleware')(compiler, {
32
-  log: () => {}
33
-})
34
-// force page reload when html-webpack-plugin template changes
35
-compiler.plugin('compilation', function (compilation) {
36
-  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
37
-    hotMiddleware.publish({ action: 'reload' })
38
-    cb()
39
-  })
40
-})
41
-
42
-// proxy api requests
43
-Object.keys(proxyTable).forEach(function (context) {
44
-  var options = proxyTable[context]
45
-  if (typeof options === 'string') {
46
-    options = { target: options }
47
-  }
48
-  app.use(proxyMiddleware(options.filter || context, options))
49
-})
50
-
51
-// handle fallback for HTML5 history API
52
-app.use(require('connect-history-api-fallback')())
53
-
54
-// serve webpack bundle output
55
-app.use(devMiddleware)
56
-
57
-// enable hot-reload and state-preserving
58
-// compilation error display
59
-app.use(hotMiddleware)
60
-
61
-// serve pure static assets
62
-var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
63
-app.use(staticPath, express.static('./static'))
64
-
65
-var uri = 'http://localhost:' + port
66
-
67
-var _resolve
68
-var readyPromise = new Promise(resolve => {
69
-  _resolve = resolve
70
-})
71
-
72
-console.log('> Starting dev server...')
73
-devMiddleware.waitUntilValid(() => {
74
-  console.log('> Listening at ' + uri + '\n')
75
-  // when env is testing, don't need open it
76
-  if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
77
-    opn(uri)
78
-  }
79
-  _resolve()
80
-})
81
-
82
-var server = app.listen(port)
83
-
84
-module.exports = {
85
-  ready: readyPromise,
86
-  close: () => {
87
-    server.close()
88
-  }
89
-}

BIN
build/logo.png


+ 41 - 11
build/utils.js

@@ -1,28 +1,38 @@
1
-var path = require('path')
2
-var config = require('../config')
3
-var ExtractTextPlugin = require('extract-text-webpack-plugin')
1
+'use strict'
2
+const path = require('path')
3
+const config = require('../config')
4
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
5
+const packageConfig = require('../package.json')
4 6
 
5 7
 exports.assetsPath = function (_path) {
6
-  var assetsSubDirectory = process.env.NODE_ENV === 'production'
8
+  const assetsSubDirectory = process.env.NODE_ENV === 'production'
7 9
     ? config.build.assetsSubDirectory
8 10
     : config.dev.assetsSubDirectory
11
+
9 12
   return path.posix.join(assetsSubDirectory, _path)
10 13
 }
11 14
 
12 15
 exports.cssLoaders = function (options) {
13 16
   options = options || {}
14 17
 
15
-  var cssLoader = {
18
+  const cssLoader = {
16 19
     loader: 'css-loader',
17 20
     options: {
18
-      minimize: process.env.NODE_ENV === 'production',
21
+      sourceMap: options.sourceMap
22
+    }
23
+  }
24
+
25
+  const postcssLoader = {
26
+    loader: 'postcss-loader',
27
+    options: {
19 28
       sourceMap: options.sourceMap
20 29
     }
21 30
   }
22 31
 
23 32
   // generate loader string to be used with extract text plugin
24 33
   function generateLoaders (loader, loaderOptions) {
25
-    var loaders = [cssLoader]
34
+    const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
35
+
26 36
     if (loader) {
27 37
       loaders.push({
28 38
         loader: loader + '-loader',
@@ -58,14 +68,34 @@ exports.cssLoaders = function (options) {
58 68
 
59 69
 // Generate loaders for standalone style files (outside of .vue)
60 70
 exports.styleLoaders = function (options) {
61
-  var output = []
62
-  var loaders = exports.cssLoaders(options)
63
-  for (var extension in loaders) {
64
-    var loader = loaders[extension]
71
+  const output = []
72
+  const loaders = exports.cssLoaders(options)
73
+
74
+  for (const extension in loaders) {
75
+    const loader = loaders[extension]
65 76
     output.push({
66 77
       test: new RegExp('\\.' + extension + '$'),
67 78
       use: loader
68 79
     })
69 80
   }
81
+
70 82
   return output
71 83
 }
84
+
85
+exports.createNotifierCallback = () => {
86
+  const notifier = require('node-notifier')
87
+
88
+  return (severity, errors) => {
89
+    if (severity !== 'error') return
90
+
91
+    const error = errors[0]
92
+    const filename = error.file && error.file.split('!').pop()
93
+
94
+    notifier.notify({
95
+      title: packageConfig.name,
96
+      message: severity + ': ' + error.name,
97
+      subtitle: filename || '',
98
+      icon: path.join(__dirname, 'logo.png')
99
+    })
100
+  }
101
+}

+ 17 - 7
build/vue-loader.conf.js

@@ -1,12 +1,22 @@
1
-var utils = require('./utils')
2
-var config = require('../config')
3
-var isProduction = process.env.NODE_ENV === 'production'
1
+'use strict'
2
+const utils = require('./utils')
3
+const config = require('../config')
4
+const isProduction = process.env.NODE_ENV === 'production'
5
+const sourceMapEnabled = isProduction
6
+  ? config.build.productionSourceMap
7
+  : config.dev.cssSourceMap
4 8
 
5 9
 module.exports = {
6 10
   loaders: utils.cssLoaders({
7
-    sourceMap: isProduction
8
-      ? config.build.productionSourceMap
9
-      : config.dev.cssSourceMap,
11
+    sourceMap: sourceMapEnabled,
10 12
     extract: isProduction
11
-  })
13
+  }),
14
+  cssSourceMap: sourceMapEnabled,
15
+  cacheBusting: config.dev.cacheBusting,
16
+  transformToRequire: {
17
+    video: ['src', 'poster'],
18
+    source: 'src',
19
+    img: 'src',
20
+    image: 'xlink:href'
21
+  }
12 22
 }

+ 39 - 14
build/webpack.base.conf.js

@@ -1,13 +1,26 @@
1
-var path = require('path')
2
-var utils = require('./utils')
3
-var config = require('../config')
4
-var vueLoaderConfig = require('./vue-loader.conf')
1
+'use strict'
2
+const path = require('path')
3
+const utils = require('./utils')
4
+const config = require('../config')
5
+const vueLoaderConfig = require('./vue-loader.conf')
5 6
 
6 7
 function resolve (dir) {
7 8
   return path.join(__dirname, '..', dir)
8 9
 }
9 10
 
11
+const createLintingRule = () => ({
12
+  test: /\.(js|vue)$/,
13
+  loader: 'eslint-loader',
14
+  enforce: 'pre',
15
+  include: [resolve('src'), resolve('test')],
16
+  options: {
17
+    formatter: require('eslint-friendly-formatter'),
18
+    emitWarning: !config.dev.showEslintErrorsInOverlay
19
+  }
20
+})
21
+
10 22
 module.exports = {
23
+  context: path.resolve(__dirname, '../'),
11 24
   entry: {
12 25
     app: './src/main.js'
13 26
   },
@@ -22,20 +35,12 @@ module.exports = {
22 35
     extensions: ['.js', '.vue', '.json'],
23 36
     alias: {
24 37
       'vue$': 'vue/dist/vue.esm.js',
25
-      '@': resolve('src')
38
+      '@': resolve('src'),
26 39
     }
27 40
   },
28 41
   module: {
29 42
     rules: [
30
-      // {
31
-      //   test: /\.(js|vue)$/,
32
-      //   loader: 'eslint-loader',
33
-      //   enforce: 'pre',
34
-      //   include: [resolve('src'), resolve('test')],
35
-      //   options: {
36
-      //     formatter: require('eslint-friendly-formatter')
37
-      //   }
38
-      // },
43
+      ...(config.dev.useEslint ? [createLintingRule()] : []),
39 44
       {
40 45
         test: /\.vue$/,
41 46
         loader: 'vue-loader',
@@ -64,6 +69,14 @@ module.exports = {
64 69
         }
65 70
       },
66 71
       {
72
+        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
73
+        loader: 'url-loader',
74
+        options: {
75
+          limit: 10000,
76
+          name: utils.assetsPath('media/[name].[hash:7].[ext]')
77
+        }
78
+      },
79
+      {
67 80
         test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
68 81
         loader: 'url-loader',
69 82
         options: {
@@ -72,5 +85,17 @@ module.exports = {
72 85
         }
73 86
       }
74 87
     ]
88
+  },
89
+  node: {
90
+    // prevent webpack from injecting useless setImmediate polyfill because Vue
91
+    // source contains it (although only uses it if it's native).
92
+    setImmediate: false,
93
+    // prevent webpack from injecting mocks to Node native modules
94
+    // that does not make sense for the client
95
+    dgram: 'empty',
96
+    fs: 'empty',
97
+    net: 'empty',
98
+    tls: 'empty',
99
+    child_process: 'empty'
75 100
   }
76 101
 }

+ 68 - 22
build/webpack.dev.conf.js

@@ -1,41 +1,87 @@
1
-var utils = require('./utils')
2
-var path = require('path')
3
-var webpack = require('webpack')
4
-var config = require('../config')
5
-var merge = require('webpack-merge')
6
-var baseWebpackConfig = require('./webpack.base.conf')
7
-var HtmlWebpackPlugin = require('html-webpack-plugin')
8
-var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
1
+'use strict'
2
+const path = require('path')
3
+const utils = require('./utils')
4
+const webpack = require('webpack')
5
+const config = require('../config')
6
+const merge = require('webpack-merge')
7
+const baseWebpackConfig = require('./webpack.base.conf')
8
+const HtmlWebpackPlugin = require('html-webpack-plugin')
9
+const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
10
+const portfinder = require('portfinder')
9 11
 
10
-function resolveApp(relativePath) {
11
-  return path.resolve(relativePath);
12
+function resolve (dir) {
13
+  return path.join(__dirname, '..', dir)
12 14
 }
13 15
 
14
-// add hot-reload related code to entry chunks
15
-Object.keys(baseWebpackConfig.entry).forEach(function (name) {
16
-  baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
17
-})
16
+const HOST = process.env.HOST
17
+const PORT = process.env.PORT && Number(process.env.PORT)
18 18
 
19
-module.exports = merge(baseWebpackConfig, {
19
+const devWebpackConfig = merge(baseWebpackConfig, {
20 20
   module: {
21
-    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
21
+    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
22 22
   },
23 23
   // cheap-module-eval-source-map is faster for development
24
-  devtool: '#cheap-module-eval-source-map',
24
+  devtool: config.dev.devtool,
25
+
26
+  // these devServer options should be customized in /config/index.js
27
+  devServer: {
28
+    clientLogLevel: 'warning',
29
+    historyApiFallback: true,
30
+    hot: true,
31
+    compress: true,
32
+    host: HOST || config.dev.host,
33
+    port: PORT || config.dev.port,
34
+    open: config.dev.autoOpenBrowser,
35
+    overlay: config.dev.errorOverlay
36
+      ? { warnings: false, errors: true }
37
+      : false,
38
+    publicPath: config.dev.assetsPublicPath,
39
+    proxy: config.dev.proxyTable,
40
+    quiet: true, // necessary for FriendlyErrorsPlugin
41
+    watchOptions: {
42
+      poll: config.dev.poll,
43
+    }
44
+  },
25 45
   plugins: [
26 46
     new webpack.DefinePlugin({
27
-      'process.env': config.dev.env
47
+      'process.env': require('../config/dev.env')
28 48
     }),
29
-    // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
30 49
     new webpack.HotModuleReplacementPlugin(),
50
+    new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
31 51
     new webpack.NoEmitOnErrorsPlugin(),
32 52
     // https://github.com/ampedandwired/html-webpack-plugin
33 53
     new HtmlWebpackPlugin({
34 54
       filename: 'index.html',
35 55
       template: 'index.html',
36
-      favicon: resolveApp('favicon.ico'),
37
-      inject: true
56
+      inject: true,
57
+      favicon: resolve('favicon.ico'),
58
+      title: 'vue-element-admin'
38 59
     }),
39
-    new FriendlyErrorsPlugin()
40 60
   ]
41 61
 })
62
+
63
+module.exports = new Promise((resolve, reject) => {
64
+  portfinder.basePort = process.env.PORT || config.dev.port
65
+  portfinder.getPort((err, port) => {
66
+    if (err) {
67
+      reject(err)
68
+    } else {
69
+      // publish the new Port, necessary for e2e tests
70
+      process.env.PORT = port
71
+      // add port to devServer config
72
+      devWebpackConfig.devServer.port = port
73
+
74
+      // Add FriendlyErrorsPlugin
75
+      devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
76
+        compilationSuccessInfo: {
77
+          messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
78
+        },
79
+        onErrors: config.dev.notifyOnErrors
80
+        ? utils.createNotifierCallback()
81
+        : undefined
82
+      }))
83
+
84
+      resolve(devWebpackConfig)
85
+    }
86
+  })
87
+})

+ 55 - 31
build/webpack.prod.conf.js

@@ -1,28 +1,31 @@
1
-var path = require('path')
2
-var utils = require('./utils')
3
-var webpack = require('webpack')
4
-var config = require('../config')
5
-var merge = require('webpack-merge')
6
-var baseWebpackConfig = require('./webpack.base.conf')
7
-var CopyWebpackPlugin = require('copy-webpack-plugin')
8
-var HtmlWebpackPlugin = require('html-webpack-plugin')
9
-var ExtractTextPlugin = require('extract-text-webpack-plugin')
10
-var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
1
+'use strict'
2
+const path = require('path')
3
+const utils = require('./utils')
4
+const webpack = require('webpack')
5
+const config = require('../config')
6
+const merge = require('webpack-merge')
7
+const baseWebpackConfig = require('./webpack.base.conf')
8
+const CopyWebpackPlugin = require('copy-webpack-plugin')
9
+const HtmlWebpackPlugin = require('html-webpack-plugin')
10
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
11
+const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
12
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
11 13
 
12
-var env = config.build.env
13
-
14
-function resolveApp(relativePath) {
15
-    return path.resolve(relativePath);
14
+function resolve (dir) {
15
+  return path.join(__dirname, '..', dir)
16 16
 }
17 17
 
18
-var webpackConfig = merge(baseWebpackConfig, {
18
+const env = require('../config/prod.env')
19
+
20
+const webpackConfig = merge(baseWebpackConfig, {
19 21
   module: {
20 22
     rules: utils.styleLoaders({
21 23
       sourceMap: config.build.productionSourceMap,
22
-      extract: true
24
+      extract: true,
25
+      usePostCSS: true
23 26
     })
24 27
   },
25
-  devtool: config.build.productionSourceMap ? '#source-map' : false,
28
+  devtool: config.build.productionSourceMap ? config.build.devtool : false,
26 29
   output: {
27 30
     path: config.build.assetsRoot,
28 31
     filename: utils.assetsPath('js/[name].[chunkhash].js'),
@@ -33,22 +36,30 @@ var webpackConfig = merge(baseWebpackConfig, {
33 36
     new webpack.DefinePlugin({
34 37
       'process.env': env
35 38
     }),
36
-    new webpack.optimize.UglifyJsPlugin({
37
-      compress: {
38
-        warnings: false
39
+    new UglifyJsPlugin({
40
+      uglifyOptions: {
41
+        compress: {
42
+          warnings: false
43
+        }
39 44
       },
40
-      sourceMap: true
45
+      sourceMap: config.build.productionSourceMap,
46
+      parallel: true
41 47
     }),
42 48
     // extract css into its own file
43 49
     new ExtractTextPlugin({
44
-      filename: utils.assetsPath('css/[name].[contenthash].css')
50
+      filename: utils.assetsPath('css/[name].[contenthash].css'),
51
+      // Setting the following option to `false` will not extract CSS from codesplit chunks.
52
+      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
53
+      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
54
+      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
55
+      allChunks: true,
45 56
     }),
46 57
     // Compress extracted CSS. We are using this plugin so that possible
47 58
     // duplicated CSS from different components can be deduped.
48 59
     new OptimizeCSSPlugin({
49
-      cssProcessorOptions: {
50
-        safe: true
51
-      }
60
+      cssProcessorOptions: config.build.productionSourceMap
61
+        ? { safe: true, map: { inline: false } }
62
+        : { safe: true }
52 63
     }),
53 64
     // generate dist index.html with correct asset hash for caching.
54 65
     // you can customize output by editing /index.html
@@ -57,7 +68,8 @@ var webpackConfig = merge(baseWebpackConfig, {
57 68
       filename: config.build.index,
58 69
       template: 'index.html',
59 70
       inject: true,
60
-      favicon: resolveApp('favicon.ico'),
71
+      favicon: resolve('favicon.ico'),
72
+      title: 'vue-element-admin',
61 73
       minify: {
62 74
         removeComments: true,
63 75
         collapseWhitespace: true,
@@ -68,12 +80,14 @@ var webpackConfig = merge(baseWebpackConfig, {
68 80
       // necessary to consistently work with multiple chunks via CommonsChunkPlugin
69 81
       chunksSortMode: 'dependency'
70 82
     }),
71
-    // cache Module Identifiers
83
+    // keep module.id stable when vender modules does not change
72 84
     new webpack.HashedModuleIdsPlugin(),
85
+    // enable scope hoisting
86
+    new webpack.optimize.ModuleConcatenationPlugin(),
73 87
     // split vendor js into its own file
74 88
     new webpack.optimize.CommonsChunkPlugin({
75 89
       name: 'vendor',
76
-      minChunks: function (module, count) {
90
+      minChunks (module) {
77 91
         // any required modules inside node_modules are extracted to vendor
78 92
         return (
79 93
           module.resource &&
@@ -88,8 +102,18 @@ var webpackConfig = merge(baseWebpackConfig, {
88 102
     // prevent vendor hash from being updated whenever app bundle is updated
89 103
     new webpack.optimize.CommonsChunkPlugin({
90 104
       name: 'manifest',
91
-      chunks: ['vendor']
105
+      minChunks: Infinity
92 106
     }),
107
+    // This instance extracts shared chunks from code splitted chunks and bundles them
108
+    // in a separate chunk, similar to the vendor chunk
109
+    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
110
+    new webpack.optimize.CommonsChunkPlugin({
111
+      name: 'app',
112
+      async: 'vendor-async',
113
+      children: true,
114
+      minChunks: 3
115
+    }),
116
+
93 117
     // copy custom static assets
94 118
     new CopyWebpackPlugin([
95 119
       {
@@ -102,7 +126,7 @@ var webpackConfig = merge(baseWebpackConfig, {
102 126
 })
103 127
 
104 128
 if (config.build.productionGzip) {
105
-  var CompressionWebpackPlugin = require('compression-webpack-plugin')
129
+  const CompressionWebpackPlugin = require('compression-webpack-plugin')
106 130
 
107 131
   webpackConfig.plugins.push(
108 132
     new CompressionWebpackPlugin({
@@ -120,7 +144,7 @@ if (config.build.productionGzip) {
120 144
 }
121 145
 
122 146
 if (config.build.bundleAnalyzerReport) {
123
-  var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
147
+  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
124 148
   webpackConfig.plugins.push(new BundleAnalyzerPlugin())
125 149
 }
126 150
 

+ 3 - 2
config/dev.env.js

@@ -1,5 +1,6 @@
1
-var merge = require('webpack-merge')
2
-var prodEnv = require('./prod.env')
1
+'use strict'
2
+const merge = require('webpack-merge')
3
+const prodEnv = require('./prod.env')
3 4
 
4 5
 module.exports = merge(prodEnv, {
5 6
   NODE_ENV: '"development"',

+ 62 - 17
config/index.js

@@ -1,38 +1,83 @@
1
+'use strict'
2
+// Template version: 1.2.6
1 3
 // see http://vuejs-templates.github.io/webpack for documentation.
2
-var path = require('path')
4
+
5
+const path = require('path')
3 6
 
4 7
 module.exports = {
8
+  dev: {
9
+
10
+    // Paths
11
+    assetsSubDirectory: 'static',
12
+    assetsPublicPath: '/',
13
+    proxyTable: {},
14
+
15
+    // Various Dev Server settings
16
+    host: 'localhost', // can be overwritten by process.env.HOST
17
+    port: 9528, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
18
+    autoOpenBrowser: true,
19
+    errorOverlay: true,
20
+    notifyOnErrors: false,
21
+    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22
+
23
+    // Use Eslint Loader?
24
+    // If true, your code will be linted during bundling and
25
+    // linting errors and warnings will be shown in the console.
26
+    useEslint: true,
27
+    // If true, eslint errors and warnings will also be shown in the error overlay
28
+    // in the browser.
29
+    showEslintErrorsInOverlay: false,
30
+
31
+    /**
32
+     * Source Maps
33
+     */
34
+
35
+    // https://webpack.js.org/configuration/devtool/#development
36
+    devtool: 'eval-source-map',
37
+
38
+    // If you have problems debugging vue-files in devtools,
39
+    // set this to false - it *may* help
40
+    // https://vue-loader.vuejs.org/en/options.html#cachebusting
41
+    cacheBusting: true,
42
+
43
+    // CSS Sourcemaps off by default because relative paths are "buggy"
44
+    // with this option, according to the CSS-Loader README
45
+    // (https://github.com/webpack/css-loader#sourcemaps)
46
+    // In our experience, they generally work as expected,
47
+    // just be aware of this issue when enabling this option.
48
+    cssSourceMap: false,
49
+  },
50
+
5 51
   build: {
6
-    env: require('./prod.env'),
52
+    // Template for index.html
7 53
     index: path.resolve(__dirname, '../dist/index.html'),
54
+
55
+    // Paths
8 56
     assetsRoot: path.resolve(__dirname, '../dist'),
9 57
     assetsSubDirectory: 'static',
58
+
59
+    // you can set by youself according to actual condition
10 60
     assetsPublicPath: './',
11
-    productionSourceMap: true,
61
+
62
+    /**
63
+     * Source Maps
64
+     */
65
+
66
+    productionSourceMap: false,
67
+    // https://webpack.js.org/configuration/devtool/#production
68
+    devtool: '#source-map',
69
+
12 70
     // Gzip off by default as many popular static hosts such as
13 71
     // Surge or Netlify already gzip all static assets for you.
14 72
     // Before setting to `true`, make sure to:
15 73
     // npm install --save-dev compression-webpack-plugin
16 74
     productionGzip: false,
17 75
     productionGzipExtensions: ['js', 'css'],
76
+
18 77
     // Run the build command with an extra argument to
19 78
     // View the bundle analyzer report after build finishes:
20 79
     // `npm run build --report`
21 80
     // Set to `true` or `false` to always turn it on or off
22 81
     bundleAnalyzerReport: process.env.npm_config_report
23
-  },
24
-  dev: {
25
-    env: require('./dev.env'),
26
-    port: 9528,
27
-    autoOpenBrowser: true,
28
-    assetsSubDirectory: 'static',
29
-    assetsPublicPath: '/',
30
-    proxyTable: {},
31
-    // CSS Sourcemaps off by default because relative paths are "buggy"
32
-    // with this option, according to the CSS-Loader README
33
-    // (https://github.com/webpack/css-loader#sourcemaps)
34
-    // In our experience, they generally work as expected,
35
-    // just be aware of this issue when enabling this option.
36
-    cssSourceMap: false
37 82
   }
38 83
 }

+ 1 - 0
config/prod.env.js

@@ -1,3 +1,4 @@
1
+'use strict'
1 2
 module.exports = {
2 3
   NODE_ENV: '"production"',
3 4
   BASE_API: '"https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin"',

+ 1 - 0
index.html

@@ -2,6 +2,7 @@
2 2
 <html>
3 3
   <head>
4 4
     <meta charset="utf-8">
5
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
5 6
     <title>vue-admin-template</title>
6 7
   </head>
7 8
   <body>

+ 20 - 18
package.json

@@ -5,63 +5,65 @@
5 5
   "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
6 6
   "author": "Pan <panfree23@gmail.com>",
7 7
   "scripts": {
8
-    "dev": "node build/dev-server.js",
9
-    "start": "node build/dev-server.js",
8
+    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9
+    "start": "npm run dev",
10 10
     "build": "node build/build.js",
11 11
     "lint": "eslint --ext .js,.vue src",
12 12
     "test": "npm run lint"
13 13
   },
14 14
   "dependencies": {
15 15
     "axios": "0.17.1",
16
-    "element-ui": "2.0.5",
16
+    "element-ui": "2.0.8",
17 17
     "js-cookie": "2.2.0",
18 18
     "normalize.css": "7.0.0",
19 19
     "nprogress": "0.2.0",
20
-    "vue": "2.5.9",
20
+    "vue": "2.5.10",
21 21
     "vue-router": "3.0.1",
22 22
     "vuex": "3.0.1"
23 23
   },
24 24
   "devDependencies": {
25
-    "autoprefixer": "7.1.6",
25
+    "autoprefixer": "7.2.3",
26 26
     "babel-core": "6.26.0",
27
-    "babel-eslint": "8.0.2",
27
+    "babel-eslint": "8.0.3",
28
+    "babel-helper-vue-jsx-merge-props": "2.0.3",
28 29
     "babel-loader": "7.1.2",
30
+    "babel-plugin-syntax-jsx": "6.18.0",
29 31
     "babel-plugin-transform-runtime": "6.23.0",
32
+    "babel-plugin-transform-vue-jsx": "3.5.0",
30 33
     "babel-preset-env": "1.6.1",
31 34
     "babel-preset-stage-2": "6.24.1",
32
-    "babel-register": "6.26.0",
33 35
     "chalk": "2.3.0",
34
-    "connect-history-api-fallback": "1.5.0",
35 36
     "copy-webpack-plugin": "4.2.3",
36 37
     "css-loader": "0.28.7",
37
-    "eslint": "4.11.0",
38
+    "eslint": "4.13.1",
38 39
     "eslint-friendly-formatter": "3.0.0",
39 40
     "eslint-loader": "1.9.0",
40 41
     "eslint-plugin-html": "4.0.1",
41 42
     "eventsource-polyfill": "0.9.6",
42
-    "express": "4.16.2",
43 43
     "extract-text-webpack-plugin": "3.0.2",
44 44
     "file-loader": "1.1.5",
45 45
     "friendly-errors-webpack-plugin": "1.6.1",
46 46
     "html-webpack-plugin": "2.30.1",
47
-    "http-proxy-middleware": "0.17.4",
47
+    "node-notifier": "5.1.2",
48 48
     "node-sass": "^4.7.2",
49
-    "opn": "5.1.0",
50 49
     "optimize-css-assets-webpack-plugin": "3.2.0",
51 50
     "ora": "1.3.0",
51
+    "portfinder": "1.0.13",
52
+    "postcss-import": "11.0.0",
53
+    "postcss-loader": "2.0.9",
52 54
     "rimraf": "2.6.2",
53 55
     "sass-loader": "6.0.6",
54 56
     "semver": "5.4.1",
55 57
     "shelljs": "0.7.8",
56
-    "svg-sprite-loader": "3.4.1",
57
-    "url-loader": "0.6.1",
58
+    "svg-sprite-loader": "3.5.2",
59
+    "uglifyjs-webpack-plugin": "1.1.3",
60
+    "url-loader": "0.6.2",
58 61
     "vue-loader": "13.5.0",
59 62
     "vue-style-loader": "3.0.3",
60
-    "vue-template-compiler": "2.5.9",
61
-    "webpack": "3.8.1",
63
+    "vue-template-compiler": "2.5.10",
64
+    "webpack": "3.10.0",
62 65
     "webpack-bundle-analyzer": "2.9.1",
63
-    "webpack-dev-middleware": "1.12.1",
64
-    "webpack-hot-middleware": "2.20.0",
66
+    "webpack-dev-server": "2.9.7",
65 67
     "webpack-merge": "4.1.1"
66 68
   },
67 69
   "engines": {

+ 1 - 1
src/App.vue

@@ -11,6 +11,6 @@ export default {
11 11
 </script>
12 12
 
13 13
 <style lang="scss">
14
-  @import '~normalize.css/normalize.css';// normalize.css 样式格式化
14
+  // @import '~normalize.css/normalize.css';// normalize.css 样式格式化
15 15
   @import './styles/index.scss'; // 全局自定义的css样式
16 16
 </style>

+ 15 - 15
src/views/404.vue

@@ -19,22 +19,22 @@
19 19
 </template>
20 20
 
21 21
 <script>
22
- import img_404 from '@/assets/404_images/404.png'
23
- import img_404_cloud from '@/assets/404_images/404_cloud.png'
22
+import img_404 from '@/assets/404_images/404.png'
23
+import img_404_cloud from '@/assets/404_images/404_cloud.png'
24 24
 
25
- export default {
26
-   data() {
27
-     return {
28
-       img_404,
29
-       img_404_cloud
30
-     }
31
-   },
32
-   computed: {
33
-     message() {
34
-       return '特朗普说这个页面你不能进......'
35
-     }
36
-   }
37
- }
25
+export default {
26
+  data() {
27
+    return {
28
+      img_404,
29
+      img_404_cloud
30
+    }
31
+  },
32
+  computed: {
33
+    message() {
34
+      return '特朗普说这个页面你不能进......'
35
+    }
36
+  }
37
+}
38 38
 </script>
39 39
 
40 40
 <style rel="stylesheet/scss" lang="scss" scoped>